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

📄 kinitxxxxxx.asm

📁 raywill写的操作系统内核
💻 ASM
字号:
;
; LittleOS
; Copyright (C) 1998 Lacroix Pascal (placr@mygale.org)
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;

; Some code comes from ReactOS by David Welch (boot0001.zip)

; This kernel should be loaded to 0x110000 (descriptor base=0, but real addr = 0x110000)
[global kernel_entry]
[global _setvect]
[global _soft_int]
[extern _osmain]
[extern _common_interrupt]


GDT_SZ		equ 256
VIRTUAL_ADDRESS equ 0xC0000000
ID_MAP_BASE	equ 0xD0000000

%include "gdtnasm.inc"

[section .text]
[BITS 32]
GLOBAL start

extern _edata, _end

align 4
kernel_entry:
start:	
        mov ax,  8 ;DS
        mov ds,  ax

        ; this must be called before paging is set !
        call    count_memory

	call 	setup_paging
        
        lgdt 	[gdt_descr]
 
        mov	eax, cr0
        or	eax, 0x80000000
        mov	cr0, eax

        jmp KERNEL_CS:.next
.next:

        ; set good registers
	mov	ax, KERNEL_DS
        mov	ds, ax
        mov 	es, ax
        mov	ss, ax
        mov	esp, kernel_stack

	lidt 	[idt_descr]

        push	dword 0
        popfd

        xor	eax, eax
        mov	fs, ax
        mov	gs, ax

        mov	edi, _edata
        mov	ecx, _end
        sub	ecx, edi
        cld
        rep	stosb

        push	eax ; eax = 0
        push	eax
        push	eax

        ; call kernel main (in C)
        call 	_osmain

        push    dword StopMsg

        add     esp, 4

        ; endless loop
GLOBAL _die
align 4
_die:
	hlt
        jmp 	_die


StopMsg: db 10, "System is halted.", 0

BASE    equ     0x90000        ; real base (without paging)

count_memory:
	; base of DS and ES is BASE=0x110000
        mov     esi, end

        ; round and add a page
        shr     esi, 12
        inc     esi
        shl     esi, 12

.loop:
	mov	eax, [esi]
        mov	dword [esi], 0xAABBCCDD
        cmp	dword [esi], 0xAABBCCDD
        jne	.stop
        ; restore data
        mov	[esi], eax
        add	esi, 4096
        jmp 	.loop
.stop:
	add	esi, BASE

        mov	[_total_memory], esi
        ret

setup_paging:
	; first page: low memory
        mov 	eax, _lowmem_page_table
        add 	eax, BASE + 7
        mov 	[_page_directory + 0], eax

        ; also maps low memory at 0xD0000000
        mov	[_page_directory + (ID_MAP_BASE/(1024*1024)) ], eax

 	; second page: the kernel
        mov 	eax, _system_page_table
        add 	eax, BASE + 7
        mov 	[_page_directory + (VIRTUAL_ADDRESS/(1024*1024)) ], eax

        ; setup low memory page table
        xor 	ebx, ebx
.L1:
        mov	eax, ebx
        shl	eax, 12		; eax = ebx * 4096
        add	eax, 7		; user, rw, present
        mov	[_lowmem_page_table + ebx*4], eax
        inc	ebx
        cmp	ebx, 1024
        jl	.L1

        ; setup kernel page table
        mov	eax, 7
        xor	edi, edi
.L2:
        mov	edx, eax
        add	edx, BASE
        mov	[_system_page_table + edi], edx
        add	edi, 4
        add	eax, 0x1000
        cmp 	eax, end
        jl	.L2

        mov	eax, _page_directory + BASE
        mov	cr3, eax

	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%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

align 4096	; align to another page (2nd)

GLOBAL _lowmem_page_table
_lowmem_page_table: times 4096 db 0

align 4096	; new page
GLOBAL _system_page_table
_system_page_table: times 4096 db 0

align 4096	; new page
GLOBAL _page_directory
_page_directory: times 4096 db 0

align 4096	; another page

GLOBAL _gdt
_gdt:
; Null descriptor - base = 0x00000000 limit = 0x00000000 ( 0.0 Mb)
	dw 0x0000, 0x0000
	dw 0x0000, 0x0000
ZERO_DS equ 0x08
        desc 0,0xFFFFF,D_DATA+D_WRITE+ D_BIG + D_BIG_LIM ;8 - FLAT DATA

KERNEL_CS equ 0x10
        desc VIRTUAL_ADDRESS, 0xFFFFF-VIRTUAL_ADDRESS/4096, D_CODE + D_READ + D_BIG + D_BIG_LIM

KERNEL_DS equ 0x18
        desc VIRTUAL_ADDRESS, 0xFFFFF-VIRTUAL_ADDRESS/4096, D_DATA + D_WRITE+ D_BIG + D_BIG_LIM

        ; space for TSS and LDT...
	times (GDT_SZ-4)*8 db 0

        ; GDT should take 2Kb
GLOBAL _idt
_idt:
	times 256*8 db 0

        ; IDT 2Kb

align 8
gdt_descr:
	dw GDT_SZ*8 - 1
        dd _gdt+BASE

align 8
idt_descr:
	dw 256*8 - 1
        dd _gdt+VIRTUAL_ADDRESS


GLOBAL _virtual_base
align 4
_virtual_base: dd VIRTUAL_ADDRESS

GLOBAL _id_map
align 4
_id_map: dd (ID_MAP_BASE - VIRTUAL_ADDRESS)

GLOBAL _phys_base
align 4
_phys_base: dd BASE

GLOBAL _total_memory
align 4
_total_memory: dd 0

; -- Kernel stack ----------
[section .bss]
align 16
ks: resb 4*1024*4
kernel_stack:
align 16

; -- Externals ----------
extern _osmain


extern end

⌨️ 快捷键说明

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