📄 kinitxxxxxx.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 + -