⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setup.s

📁 计算机启动例子代码
💻 S
字号:
;这段代码载入内存0x10000, 把内核移到0x20000,
;切换到保护模式后可以跳入操作系统内核了


        mov     ax,cs           ;0x10000      ;this code load at 0x10000
        mov     ds,ax
        mov     es,ax
        
        mov	cx,12
	mov	bx,0x0007	; page 0, attribute 7 (normal)
	mov	bp,msg
	mov	ax,0x1301	; write string, move cursor
	int	0x10
  
        ;======================
        ;above is Test OK!!!!!!
        ;====================== 
        
        ;这段代码被Boot.s(长度0x800,即2048字节) 装入0x10000
        ;
        ;re move system at 0x20000
        cli
        mov     ax,0x2000                ;dest seg 和编译选项-Ttext 一致
        mov     es,ax                     
        mov     si,0x800                 ;source offset 和setup大小一致
        mov     di,0x0000                ;dest offset 
        mov     cx,0x1500                ;count 临时值
        rep     movsw
 

        

       
  
end_move:

	mov	ax,cs		; right, forgot this at first. didn't work :-)
	mov	ds,ax
	lidt	[idt_48]		; load idt with 0,0
	lgdt	[gdt_48]		; load gdt with whatever appropriate

; that was painless, now we enable A20

	call	empty_8042
	mov	al,0xD1		; command write
	out	0x64,al
	call	empty_8042
	mov	al,0xDF		; A20 on
	out	0x60,al
	call	empty_8042

; well, that went ok, I hope. Now we have to reprogram the interrupts :-(
; we put them right after the intel-reserved hardware interrupts, at
; int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
; messed this up with the original PC, and they haven't been able to
; rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
; which is used for the internal hardware interrupts as well. We just
; have to reprogram the 8259's, and it isn't fun.

	mov	al,0x11		; initialization sequence
	out	0x20,al		; send it to 8259A-1
	dw	0x00eb,0x00eb		; jmp $+2, jmp $+2
	out	0xA0,al		; and to 8259A-2
	dw	0x00eb,0x00eb
	mov	al,0x20		; start of hardware int's (0x20)
	out	0x21,al
	dw	0x00eb,0x00eb
	mov	al,0x28		; start of hardware int's 2 (0x28)
	out	0xA1,al
	dw	0x00eb,0x00eb
	mov	al,0x04		; 8259-1 is master
	out	0x21,al
	dw	0x00eb,0x00eb
	mov	al,0x02		; 8259-2 is slave
	out	0xA1,al
	dw	0x00eb,0x00eb
	mov	al,0x01		; 8086 mode for both
	out	0x21,al
	dw	0x00eb,0x00eb
	out	0xA1,al
	dw	0x00eb,0x00eb
	mov	al,0xFF		; mask off all interrupts for now
	out	0x21,al
	dw	0x00eb,0x00eb
	out	0xA1,al

; well, that certainly wasn't fun :-(. Hopefully it works, and we don't
; need no steenking BIOS anyway (except for the initial loading :-).
; The BIOS-routine wants lots of unnecessary data, and it's less
; "interesting" anyway. This is how REAL programmers do it.
;
; Well, now's the time to actually move into protected mode. To make
; things as simple as possible, we do no register set-up or anything,
; we let the gnu-compiled 32-bit programs do that. We just jump to
; absolute address 0x00000, in 32-bit protected mode.

        
	mov	ax,0x0001	; protected mode (PE) bit
	lmsw	ax		; This is it!
	jmp clean
	clean:
        mov     eax,0x10
        mov     ds,ax
        mov     es,ax
        mov     ss,ax
        mov     esp,0x1000
        mov     ax,0

        
        jmp dword 8:0x20000	; jmp offset 0 of segment 8 (cs)
                                ; 和 os 装入位置一致
                                ; 这里是 32 位的代码




;-------------------临时的32位环境以便启动内核-------------------------------
align 4
gdt:
	dw	0,0,0,0		; dummy

	dw	0x07FF		; 8Mb - limit=2047 (2048*4096=8Mb)
	dw	0x0000		; base address=0
	dw	0x9A00		; code read/exec
	dw	0x00C0		; granularity=4096, 386

	dw	0x07FF		; 8Mb - limit=2047 (2048*4096=8Mb)
	dw	0x0000		; base address=0
	dw	0x9200		; data read/write
	dw	0x00C0		; granularity=4096, 386

idt_48:
	dw	0			; idt limit=0
	dw	0,0			; idt base=0L

gdt_48:
	dw	0x800		; gdt limit=2048, 256 GDT entries
	dw	gdt,0x1		; 注意 gdt base = 0X1xxxx
                                ; 因为 setup 装入0X10000
                                ; 这两个值应该保持一致 

msg :
        db 13,10
	db "Setup ......."
	db 13,10,13,10

;**********************子程序**********************************************

; This routine checks that the keyboard command queue is empty
; No timeout is used - if this hangs there is something wrong with
; the machine, and we probably couldn't proceed anyway.
empty_8042:
	dw	0x00eb,0x00eb
	in	al,0x64	; 8042 status port
	test	al,2		; is input buffer full?
	jnz	empty_8042	; yes - loop
	ret


;****************************************************************************
times (2048-($-$$)) db 0    ;为setup预留1 个扇区


	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -