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

📄 kinit0x00.asm

📁 raywill写的操作系统内核
💻 ASM
字号:


;0x010:0x0003072

[global kernel_entry]
[global _setvect]
[global _soft_int]
[extern _osmain]
[extern _common_interrupt]



	%define _PAGE_OFFSET 	0xC0000000		;3G
	%define LOAD_BASE			0x90000				;phy_addr where we load our kernel to

[section .text]


kernel_entry:

		
start:
	cli
	mov ax,8
	mov ds,ax		;seg value is in the loader
	
enable_paging:

	mov	dword [_page_directory+(_PAGE_OFFSET>>22)*4],_kernel_page_table+LOAD_BASE+7   ;seccond param is compile time determined
	mov eax,7+LOAD_BASE
	mov ebx,0
fill_page_table:	
	mov	dword [_kernel_page_table+ebx*4+0],	eax
	add eax,0x1000
	inc ebx
	cmp ebx,20
	jnz fill_page_table

	mov eax,_page_directory + LOAD_BASE
	mov	cr3,eax

;Doing nothing here
	hlt
	nop
	nop
	
reset_gdt:
	lgdt	[gdt_addr]	;load GDT.Now will use kernel gdt.

;GDT has set correctly ,now let's enable PAGING :-)

	mov	eax,cr0
	or	eax,1<<31
	mov	cr0,eax


	mov eax,1123
	mov	dword [eax],23

	jmp gdt_code_addr:reset_data_seg
reset_data_seg:

	jmp flush_page
;ret can also flush the pre-frech queue :)
flush_page:
	mov	ax,gdt_data_addr		;data segment descriptor
	mov	ds,ax
	mov	es,ax
	mov	fs,ax
	mov	gs,ax
	mov	ss,ax
	mov	esp,0x1000

;install the irq handler
	mov ecx,(idt_end - idt) >> 3 ; number of exception handlers
	mov edi,idt
	mov esi,isr0		;first handler
do_idt:
	mov eax,esi				; EAX=offset of entry point
	mov [edi],ax			; set low 16 bits of gate offset
	shr eax,16				; get high 16 of the handler address
	mov [edi + 6],ax	; set high 16 bits of gate offset
	add edi,8					; 8 bytes/interrupt gate
	add esi,(isr1 - isr0)		; bytes/stub
	loop do_idt
	
	lidt	[idt_addr]	;load null interrupt describe table

;Everything have done!Let's go!
	;sti(we can do this in C,after everything initialized)
	call	_osmain
hang:
	jmp hang


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;here is the gdt data for the kernel;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
gdt:
 gdt_null:
	dd	0
	dd	0
 gdt_data_addr	equ $-gdt
 gdt_data:
 	dw	0xffff
	dw	0x00
	db	0x00
	db	10010010b	;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,2:data seg,read and write.
	db	11001111b	;(7)limit len,0:1 byte,1:4K,(6)B bit,control stack,B=1,use esp,B=0,use sp,(5-4) reserved,(3-0)seg limit 19-16.
	db	0xC0 ;(=1100 0000)
 gdt_code_addr	equ $-gdt
 gdt_code:
 	dw	0xffff
	dw	0x00
	db	0x00
	db	10011010b	;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,10:code seg,execute and read.
	db	11001111b
	db	0xC0

gdt_end:
 gdt_addr:
 	dw	gdt_end - gdt - 1	;gdt total length,here it contains 3 item
	dd	gdt+LOAD_BASE		;gdt start address

;set null interrupt 
idt:
%rep 256
	dw 0				; offset 15:0
	dw gdt_code_addr		; selector
	db 0				; (always 0 for interrupt gates)
	db 8Eh			; present,ring 0,'386 interrupt gate
	dw 0				; offset 31:16
%endrep
idt_end:
 idt_addr:
	dw idt_end - idt - 1		; IDT limit
	dd idt				; linear adr of IDT
	
align 0x1000
GLOBAL _page_directory
	_page_directory:
		times	0x1000 db 0
	
align 0x1000
GLOBAL _kernel_page_table	
	_kernel_page_table:
		times	0x1000 db 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%macro PUSHB 1
	db 6Ah
	db %1
%endmacro

%macro INTR 1				; (byte offset from start of stub)
isr%1:
	push byte 0			; ( 0) fake error code
	PUSHB %1			; ( 2) exception number
	push gs				; ( 4) push segment registers
	push fs				; ( 6)
	push es				; ( 8)
	push ds				; ( 9)
	pusha				; (10) push GP registers
		mov ax,gdt_data_addr	; (11) put known-good values...
		mov ds,eax		; (15) ...in segment registers
		mov es,eax		; (17)
		mov fs,eax		; (19)
		mov gs,eax		; (21)
		mov eax,esp		; (23)
		push eax		; (25) push pointer to regs_t
.1:
; setvect() changes the operand of the CALL instruction at run-time,
; so we need its location = 27 bytes from start of stub. We also want
; the CALL to use absolute addressing instead of EIP-relative, so:
			mov eax,_common_interrupt; (26)
			call eax	; (31)

		pop eax
		popa				; pop GP registers
		pop ds				; pop segment registers
		pop es
		pop fs
		pop gs
		
		nop
		nop

			
	add esp,8			; drop exception number and error code
iret
%endmacro				; (38)

%macro INTR_EC 1
isr%1:
	nop				; error code already pushed
	nop				; nop+nop=same length as push byte
	PUSHB %1			; ( 2) exception number
	push gs				; ( 4) push segment registers
	push fs				; ( 6)
	push es				; ( 8)
	push ds				; ( 9)
	pusha				; (10) push GP registers
		mov ax,gdt_data_addr	; (11) put known-good values...
		mov ds,eax		; (15) ...in segment registers
		mov es,eax		; (17)
		mov fs,eax		; (19)
		mov gs,eax		; (21)
		mov eax,esp		; (23)
		push eax		; (25) push pointer to regs_t
.1:
; setvect() changes the operand of the CALL instruction at run-time,
; so we need its location = 27 bytes from start of stub. We also want
; the CALL to use absolute addressing instead of EIP-relative, so:
			mov eax,_common_interrupt	; (26)
			call eax	; (31)

		pop eax
		popa				; pop GP registers
		pop ds				; pop segment registers
		pop es
		pop fs
		pop gs
		
		nop
		nop

			
	add esp,8			; drop exception number and error code
iret
%endmacro				; (38)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; interrupt/exception stubs
; *** CAUTION: these must be consecutive, and must all be the same size.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	INTR 0		; zero divide (fault)
	INTR 1		; debug/single step
	INTR 2		; non-maskable interrupt (trap)
	INTR 3		; INT3 (trap)
	INTR 4		; INTO (trap)
	INTR 5		; BOUND (fault)
	INTR 6		; invalid opcode (fault)
	INTR 7		; coprocessor not available (fault)
	INTR_EC 8	; double fault (abort w/ error code)
	INTR 9		; coproc segment overrun (abort; 386/486SX only)
	INTR_EC 0Ah	; bad TSS (fault w/ error code)
	INTR_EC 0Bh	; segment not present (fault w/ error code)
	INTR_EC 0Ch	; stack fault (fault w/ error code)
	INTR_EC 0Dh	; GPF (fault w/ error code)
	INTR_EC 0Eh	; page fault
	INTR 0Fh	; reserved
	INTR 10h	; FP exception/coprocessor error (trap)
	INTR 11h	; alignment check (trap; 486+ only)
	INTR 12h	; machine check (Pentium+ only)
	INTR 13h
	INTR 14h
	INTR 15h
	INTR 16h
	INTR 17h
	INTR 18h
	INTR 19h
	INTR 1Ah
	INTR 1Bh
	INTR 1Ch
	INTR 1Dh
	INTR 1Eh
	INTR 1Fh

; isr20 through isr2F are hardware interrupts. The 8259 programmable
; interrupt controller (PIC) chips must be reprogrammed to make these work.
	INTR 20h	; IRQ 0/timer interrupt
	INTR 21h	; IRQ 1/keyboard interrupt
	INTR 22h
	INTR 23h
	INTR 24h
	INTR 25h
	INTR 26h	; IRQ 6/floppy interrupt
	INTR 27h
	INTR 28h	; IRQ 8/real-time clock interrupt
	INTR 29h
	INTR 2Ah
	INTR 2Bh
	INTR 2Ch
	INTR 2Dh	; IRQ 13/math coprocessor interrupt
	INTR 2Eh	; IRQ 14/primary ATA ("IDE") drive interrupt
	INTR 2Fh	; IRQ 15/secondary ATA drive interrupt

; syscall software interrupt
	INTR 30h

; the other 207 vectors are undefined

%assign i 31h
%rep (0FFh - 30h)

	INTR i

%assign i (i + 1)
%endrep




_soft_int:
	push ebp
		mov  ebp,esp
		push eax
		 mov eax,[ebp+8]
		 ;int ax
		 int 0x20
		pop eax
		pop ebp
	ret

_setvect:
	push ebp
		mov ebp,esp
		push esi
		push ebx
			mov esi,[ebp + 8]

; store accessdbyte in IDT[i]
			mov eax,[esi + 0]
			xor ebx,ebx
			mov bl,[ebp + 12]
			shl ebx,3									;ebx+5+idt=priv addr
			mov [idt + ebx + 5],al		;in al,8Eh=Present Ring0 386mode

; store handler address in stub
			mov eax,isr1
			sub eax,isr0	; assume stub size < 256 bytes
			mul byte [ebp + 12]				;which intr? 0x20 like so
			mov ebx,eax								;because the mul source is byte(al),the result is (AX)
			add ebx,isr0							;ebx=Delta_dis*No+Start
			mov eax,[esi + 4]					;[esi+4]=eip
			mov [ebx + (isr0.1 - isr0 + 1)],eax
		pop ebx
		pop esi
	pop ebp
	ret


[section .data]

[section .bss]
knrl_stack:

⌨️ 快捷键说明

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