865 lines
13 KiB
NASM
865 lines
13 KiB
NASM
cpu 386
|
|
|
|
bits 16
|
|
org 0
|
|
|
|
%define BIT_READWRITE (1 << 1)
|
|
%define BIT_EXECUTABLE (1 << 3)
|
|
%define BIT_ISCODEORDATA (1 << 4)
|
|
%define BIT_PRESENT (1 << 7)
|
|
|
|
%define PBIT_PRESENT 1
|
|
%define PBIT_WRITABLE 2
|
|
%define PBIT_USERLEVEL 4
|
|
%define PBIT_WRITETHROUGH 8
|
|
%define PBIT_CACHEDISABLE 16
|
|
%define PBIT_ACCESSED 32
|
|
|
|
MALLOC_MEM equ 0x520
|
|
|
|
BOOT1_SEGMENT equ 0x3000
|
|
BOOT1_ADDR equ (BOOT1_SEGMENT * 0x10)
|
|
|
|
start:
|
|
mov [ld_lba.drive + 1], dl
|
|
|
|
mov ah, 8
|
|
mov di, 0
|
|
int 0x13
|
|
mov dl, dh
|
|
mov dh, 0
|
|
inc dx
|
|
mov [lba2chs.numheads + 1], dx
|
|
and cl, 0x3F
|
|
mov ch, 0
|
|
mov [lba2chs.spt + 1], cx
|
|
|
|
mov eax, [es:0x7C00 + 0x1BE + 8]
|
|
mov [get_inode.abs1], eax
|
|
mov [read_inode.abs1], eax
|
|
|
|
mov ecx, 40 * 25
|
|
mov edi, 0
|
|
.lup:
|
|
mov [fs:edi + ecx * 4 - 4], dword 0x0F000F00
|
|
dec ecx
|
|
jnz .lup
|
|
|
|
mov si, MSG_START
|
|
mov ax, MSG_START.end - MSG_START
|
|
call print16
|
|
|
|
mov edi, MALLOC_MEM ;Bump allocator pointer
|
|
|
|
add edi, 4096
|
|
mov [TSS.esp0], edi ;End of stack ~ beginning of memory map!!
|
|
|
|
a20:
|
|
cli
|
|
call .waito
|
|
mov al, 0xAD
|
|
out 0x64, al
|
|
call .waito
|
|
mov al, 0xD0
|
|
out 0x64, al
|
|
.waiti:
|
|
in al, 0x64
|
|
test al, 1
|
|
jz .waiti
|
|
in al, 0x60
|
|
push ax
|
|
call .waito
|
|
mov al, 0xD1
|
|
out 0x64, al
|
|
call .waito
|
|
pop ax
|
|
or al, 2
|
|
out 0x60, al
|
|
call .waito
|
|
mov al, 0xAE
|
|
out 0x64, al
|
|
call .waito
|
|
sti
|
|
jmp ramdetect
|
|
.waito:
|
|
in al, 0x64
|
|
test al, 2
|
|
jnz .waito
|
|
ret
|
|
|
|
ramdetect: ;Currently only detects RAM below 16MB, which will be enough for a while.
|
|
clc
|
|
int 0x12
|
|
jc .fail
|
|
mov [es:di + 0], dword 0
|
|
mov [es:di + 4], dword 0
|
|
movzx ecx, ax
|
|
shr cx, 2
|
|
mov [es:di + 8], ecx
|
|
mov [es:di + 12], byte 0
|
|
add di, 13
|
|
mov al, 0
|
|
add cx, 7
|
|
shr cx, 3
|
|
rep stosb
|
|
|
|
xor cx, cx
|
|
xor dx, dx
|
|
mov ax, 0xE801
|
|
int 0x15
|
|
jc .fail
|
|
cmp ah, 0x86
|
|
je .fail
|
|
cmp ah, 0x80
|
|
je .fail
|
|
jcxz .useax
|
|
mov ax, cx
|
|
mov bx, dx
|
|
.useax:
|
|
mov [es:di + 0], dword 0x100000
|
|
mov [es:di + 4], dword 0
|
|
movzx ecx, ax
|
|
shr ecx, 2
|
|
mov [es:di + 8], ecx
|
|
mov [es:di + 12], byte 0
|
|
add di, 13
|
|
mov al, 0
|
|
shr ecx, 3
|
|
rep stosb
|
|
jmp .foundMMap
|
|
|
|
.fail:
|
|
mov si, MSG_FAIL
|
|
mov ax, MSG_FAIL.end - MSG_FAIL
|
|
call print16
|
|
|
|
jmp $
|
|
.foundMMap:
|
|
mov si, MSG_DETECTED_MEMORY_MAP
|
|
mov ax, MSG_DETECTED_MEMORY_MAP.end - MSG_DETECTED_MEMORY_MAP
|
|
call print16
|
|
|
|
pg:
|
|
; Create page directory
|
|
add edi, 4095
|
|
and edi, ~4095
|
|
mov cr3, edi ;In advance
|
|
lea eax, [edi + 4096]
|
|
or eax, PBIT_PRESENT | PBIT_WRITABLE
|
|
mov [es:edi], eax
|
|
add edi, 4
|
|
mov eax, 0
|
|
mov ecx, 1023
|
|
rep stosd
|
|
|
|
mov ecx, 192
|
|
mov edx, PBIT_PRESENT | PBIT_WRITABLE
|
|
.lup:
|
|
mov [es:edi], edx
|
|
add edi, 4
|
|
add edx, 4096
|
|
dec ecx
|
|
jnz .lup
|
|
|
|
mov ecx, 1024 - 192
|
|
mov eax, 0
|
|
rep stosd
|
|
|
|
mov eax, cr3 ;Back to the page directory
|
|
mov [es:eax + 4092], edi
|
|
or dword [es:eax + 4092], PBIT_PRESENT | PBIT_WRITABLE
|
|
mov [es:edi + 4092], edi
|
|
or dword [es:edi + 4092], PBIT_PRESENT | PBIT_WRITABLE
|
|
add edi, 4096
|
|
|
|
mov esi, MSG_STEP3s
|
|
mov eax, MSG_STEP3s.end - MSG_STEP3s
|
|
call print16
|
|
|
|
loadkernel:
|
|
mov eax, 2 ;root
|
|
call get_inode
|
|
mov bx, di
|
|
call read_inode
|
|
mov eax, edi
|
|
mov esi, KERNEL_FILE
|
|
mov ecx, KERNEL_FILE.end - KERNEL_FILE
|
|
call find_in_dirnode
|
|
test eax, eax
|
|
jnz .found
|
|
|
|
mov si, MSG_STEP5f
|
|
mov ax, MSG_STEP5f.end - MSG_STEP5f
|
|
call print16
|
|
jmp $
|
|
.found:
|
|
call get_inode
|
|
mov bx, di
|
|
call read_inode
|
|
; Now edi is kernel location, ebx is after kernel.
|
|
call fix_module_addresses
|
|
mov [inPE.KERNEL_START], edi
|
|
mov edi, ebx ;Allocate modules after kernel
|
|
;~ mov [inPE.MODULES_START], edi
|
|
|
|
loadmods:
|
|
mov eax, 2
|
|
call get_inode
|
|
mov esi, [endSector + 32] ;filesize
|
|
push es
|
|
push ds
|
|
pop es
|
|
mov bx, endSector + 0x200 ;Will break if root directory is larger than 1KB.
|
|
call read_inode
|
|
pop es
|
|
mov eax, endSector + 0x200
|
|
.lup: ;Loop over files, the names of which end with ".mod"
|
|
movzx ecx, word [eax + 10] ;Length of name
|
|
lea edx, [eax + 12] ;Get name string
|
|
cmp ecx, 4 ;Test if shorter than 4 characters
|
|
jb .cont
|
|
.testext:
|
|
cmp [eax + ecx + 12 - 4], dword ".mod"
|
|
jne .cont
|
|
.testkrnl:
|
|
cmp [eax + 12], dword "krnl"
|
|
je .cont
|
|
.ismod:
|
|
inc dword [inPE.MOD_COUNT]
|
|
push eax
|
|
mov eax, [eax] ;inode
|
|
call get_inode
|
|
call page_align_es_edi
|
|
push esi
|
|
mov esi, cr3
|
|
mov cx, 1024
|
|
push ds
|
|
push word 0
|
|
pop ds
|
|
rep movsd ;Copy page directory to one local to process
|
|
pop ds
|
|
pop esi
|
|
mov bx, di
|
|
call read_inode ;edi = start, ebx = end
|
|
mov di, bx
|
|
pop eax
|
|
.cont:
|
|
movzx ecx, byte [eax + 9]
|
|
shl cx, 4
|
|
add eax, ecx
|
|
sub esi, ecx
|
|
jnz .lup
|
|
.end:
|
|
mov di, es
|
|
shl edi, 4
|
|
add edi, 4095
|
|
and edi, ~4095
|
|
mov [inPE.IMPORTANT_MEM_END], edi
|
|
xor ax, ax
|
|
mov es, ax
|
|
|
|
add ebx, edi
|
|
fixmmap: ; Make all module memories "used"
|
|
lea ecx, [es:ebx + 4095]
|
|
shr ecx, 12
|
|
mov ebx, ecx
|
|
and ebx, 7
|
|
shr ecx, 3
|
|
mov edi, [TSS.esp0]
|
|
add edi, 13
|
|
push edi
|
|
mov al, -1
|
|
rep stosb
|
|
mov ecx, ebx
|
|
mov al, 1
|
|
shl al, cl
|
|
dec al
|
|
mov [es:edi], al
|
|
pop edi
|
|
or [es:edi + (BOOT1_ADDR / 4096 / 8)], byte 3 ; TODO: Let boot1 get overwritten after load
|
|
|
|
modex:
|
|
mov ax, 0x13
|
|
int 0x10
|
|
|
|
mov dx, 0x3C4
|
|
mov al, 4
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 6
|
|
out dx, al
|
|
|
|
mov dx, 0x3D4
|
|
mov al, 0x14
|
|
out dx, al
|
|
|
|
inc dx
|
|
xor al, al
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x17
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0xE3
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x11
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0x2C
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x06
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0x0D
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x07
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0x3E
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x10
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0xEA
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x11
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0xAC
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x12
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0xDF
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x15
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0xE7
|
|
out dx, al
|
|
|
|
dec dx
|
|
mov al, 0x16
|
|
out dx, al
|
|
|
|
inc dx
|
|
mov al, 0x06
|
|
out dx, al
|
|
|
|
; ESP should be zero here.
|
|
push strict dword BOOT1_ADDR + inPE
|
|
mov esp, BOOT1_ADDR + 0x10000 + 0xFFFC
|
|
jmp enterPM
|
|
|
|
enterPM:
|
|
cli
|
|
or [GDT.R0CSLIMFLAGS], byte 64 ;Make 32-bit
|
|
lgdt [GDT]
|
|
mov eax, cr0
|
|
or eax, 1 | (1 << 31)
|
|
mov cr0, eax
|
|
jmp 8:dword BOOT1_ADDR + .inPM
|
|
.inPM:
|
|
bits 32
|
|
mov eax, 0x23
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
mov al, 0x10
|
|
mov ss, ax
|
|
ret
|
|
|
|
enterRM:
|
|
and [GDT.R0CSLIMFLAGS], byte ~64 ;Make 16-bit
|
|
lgdt [GDT]
|
|
jmp 8:.in16
|
|
.in16:
|
|
bits 16
|
|
mov eax, cr0
|
|
and eax, ~(1 | (1 << 31))
|
|
mov cr0, eax
|
|
jmp 0:.inRM
|
|
.inRM:
|
|
mov ax, 0
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
mov ss, ax
|
|
sti
|
|
ret
|
|
|
|
; Makes es:edi a normalized far pointer
|
|
normalize_es_edi:
|
|
push eax
|
|
push edi
|
|
mov ax, es
|
|
shr di, 4
|
|
add ax, di
|
|
mov es, ax
|
|
pop edi
|
|
and edi, 15
|
|
pop eax
|
|
ret
|
|
|
|
page_align_es_edi:
|
|
push eax
|
|
xor eax, eax
|
|
mov ax, es
|
|
shl eax, 4
|
|
add eax, edi
|
|
add eax, 4095
|
|
and eax, ~4095
|
|
shr eax, 4
|
|
mov es, ax
|
|
pop eax
|
|
xor edi, edi
|
|
ret
|
|
|
|
print16:
|
|
push di
|
|
push cx
|
|
push ax
|
|
.ind:
|
|
mov di, 0
|
|
mov cx, ax
|
|
.lup:
|
|
mov al, [ds:si]
|
|
mov [fs:di], al
|
|
inc si
|
|
inc di
|
|
inc di
|
|
dec cx
|
|
jnz .lup
|
|
mov [.ind + 1], di ;SMC
|
|
pop ax
|
|
pop cx
|
|
pop di
|
|
ret
|
|
|
|
ld_lba:
|
|
pushad
|
|
call lba2chs
|
|
mov ch, al
|
|
mov dh, dl
|
|
.drive:
|
|
mov dl, 0
|
|
mov ah, 2
|
|
mov al, 1
|
|
int 0x13
|
|
popad
|
|
ret
|
|
|
|
; In: AX = lba
|
|
; Out: CX = sector, AX = cylinder, DX = head
|
|
lba2chs:
|
|
push bx
|
|
.spt:
|
|
mov bx, 0xF157
|
|
xor dx, dx
|
|
div bx
|
|
mov cx, dx
|
|
inc cx
|
|
.numheads:
|
|
mov bx, 0x9001
|
|
xor dx, dx
|
|
div bx
|
|
pop bx
|
|
ret
|
|
|
|
; In: EAX = inode
|
|
; Out: *BOOT1_SEGMENT:endSector = inode struct
|
|
get_inode:
|
|
push eax
|
|
push ebx
|
|
.abs1 equ ($ + 2)
|
|
add eax, strict dword 0xABCDEF42
|
|
push es
|
|
push ds
|
|
pop es
|
|
mov bx, endSector
|
|
call ld_lba
|
|
pop es
|
|
pop ebx
|
|
pop eax
|
|
ret
|
|
|
|
; In: *BOOT1_SEGMENT:endSector = inode struct
|
|
; Out: *ES:BX = data
|
|
read_inode:
|
|
push edx
|
|
push ecx
|
|
push eax
|
|
push esi
|
|
push edi
|
|
push ebx
|
|
|
|
mov dl, [endSector + 8] ;extent count
|
|
mov ecx, endSector + 104 ;extent starts
|
|
|
|
.lup:
|
|
mov eax, [ecx] ;start
|
|
mov esi, [ecx + 48] ;size of extent
|
|
.abs1 equ ($ + 2)
|
|
add eax, strict dword 0x12345678
|
|
|
|
.lup2:
|
|
call ld_lba
|
|
add bx, 512
|
|
inc eax
|
|
dec esi
|
|
jnz .lup2
|
|
|
|
add ecx, 8
|
|
dec dl
|
|
jnz .lup
|
|
|
|
mov edi, [esp] ;dest address
|
|
lea esi, [edi + 176]
|
|
test dword [endSector + 28], 1 << 19
|
|
jz .doesntHaveInline
|
|
add esi, 512 - 176
|
|
.doesntHaveInline:
|
|
mov ecx, [endSector + 32] ;filesize
|
|
push ds
|
|
push es
|
|
pop ds
|
|
rep movsb
|
|
pop ds
|
|
|
|
add esp, 4 ;ignore old ebx, because read_inode should return the addr after
|
|
pop edi
|
|
pop esi
|
|
pop eax
|
|
pop ecx
|
|
pop edx
|
|
ret
|
|
|
|
; In: *ES:EAX = directory content buffer, *ESI = name to test, ECX = name length
|
|
; Out: EAX = inode or 0 if not found
|
|
find_in_dirnode:
|
|
push ebx
|
|
push edx
|
|
push edi
|
|
|
|
mov edi, [endSector + 32] ;filesize
|
|
.lup:
|
|
movzx edx, word [es:eax + 10] ;record name length
|
|
cmp dx, cx
|
|
.lup2:
|
|
dec dx
|
|
mov bl, [es:eax + 12 + edx]
|
|
cmp bl, [esi + edx]
|
|
jne .next
|
|
test dx, dx
|
|
jnz .lup2
|
|
jmp .found
|
|
.next:
|
|
movzx edx, byte [es:eax + 9] ;record length
|
|
shl dx, 4
|
|
add eax, edx
|
|
sub edi, edx
|
|
jnz .lup
|
|
|
|
mov eax, 0
|
|
jmp .end
|
|
.found:
|
|
mov eax, [es:eax]
|
|
.end:
|
|
pop edi
|
|
pop edx
|
|
pop ebx
|
|
ret
|
|
|
|
fix_module_addresses:
|
|
push esi
|
|
push ecx
|
|
push eax
|
|
push ebx
|
|
|
|
movzx ecx, word [es:edi + 4] ;amount of syms
|
|
lea esi, [es:edi + 12 + ecx * 4]
|
|
lea esi, [es:esi + ecx * 2]
|
|
movzx ecx, word [es:edi + 6] ;amount of relocs
|
|
mov eax, esi ;ptr to relocs
|
|
lea esi, [esi + ecx * 4] ;ptr to data
|
|
add esi, 15
|
|
and esi, ~15
|
|
mov [es:edi], esi ;Replace the MOD\0 magic header with the base address
|
|
test ecx, ecx ;If none, end
|
|
jz .end
|
|
.lup:
|
|
; Apply relocation
|
|
mov ebx, [es:eax]
|
|
add ebx, esi
|
|
add [es:ebx], esi
|
|
|
|
add eax, 4
|
|
dec ecx
|
|
jnz .lup
|
|
.end:
|
|
|
|
pop ebx
|
|
pop eax
|
|
pop ecx
|
|
pop esi
|
|
ret
|
|
|
|
bits 32
|
|
|
|
inPE:
|
|
mov [BOOT1_ADDR + TSS.ss0], dword 0x10
|
|
mov esp, [BOOT1_ADDR + TSS.esp0]
|
|
|
|
mov eax, 40
|
|
ltr ax
|
|
|
|
mov ax, [BOOT1_ADDR + print16.ind + 1]
|
|
mov [BOOT1_ADDR + print32.LAST], ax
|
|
|
|
mov esi, BOOT1_ADDR + MSG_STEP2s
|
|
mov eax, MSG_STEP2s.end - MSG_STEP2s
|
|
call print32
|
|
|
|
.KERNEL_START equ ($ + 1)
|
|
mov edi, strict dword 0
|
|
lea ebx, [edi + 14]
|
|
; Sym 0: ppm_Bitmap
|
|
mov eax, [ebx]
|
|
add eax, [edi] ;Base address that used to be magic header
|
|
push dword [BOOT1_ADDR + TSS.esp0] ;As said before, end of stack ~ beginning of mmap!
|
|
pop dword [eax]
|
|
add ebx, 6
|
|
; Sym 1: vpm_init
|
|
mov eax, [ebx]
|
|
add eax, [edi]
|
|
.IMPORTANT_MEM_END equ ($ + 1)
|
|
push strict dword 0
|
|
call eax
|
|
add esp, 4
|
|
add ebx, 6
|
|
; Sym 2: vpm_map
|
|
mov eax, [ebx]
|
|
add eax, [edi]
|
|
mov [BOOT1_ADDR + .VPM_MAP_ENTRY], eax
|
|
add ebx, 6
|
|
; Sym 3: canal_init
|
|
mov eax, [ebx]
|
|
add eax, [edi]
|
|
call eax
|
|
add ebx, 6
|
|
; Sym 4: pci_init
|
|
mov eax, [ebx]
|
|
add eax, [edi]
|
|
call eax
|
|
add ebx, 6
|
|
; Sym 5: scheduler_init
|
|
mov eax, [ebx]
|
|
add eax, [edi]
|
|
call eax
|
|
add ebx, 6
|
|
; Sym 6: scheduler_spawn
|
|
mov eax, [ebx]
|
|
add eax, [edi]
|
|
mov [BOOT1_ADDR + .SCHEDULER_SPAWN_ENTRY], eax
|
|
add ebx, 6
|
|
; Sym 7: scheduler_start
|
|
mov eax, [ebx]
|
|
add eax, [edi]
|
|
mov [BOOT1_ADDR + .SCHEDULER_START_ENTRY], eax
|
|
|
|
.MOD_COUNT equ ($ + 1)
|
|
mov ebp, strict dword 0
|
|
.modspawnlup:
|
|
; Find next module
|
|
movzx ecx, word [edi + 4]
|
|
lea eax, [edi + ecx * 4]
|
|
lea eax, [eax + ecx * 2]
|
|
movzx ecx, word [edi + 6]
|
|
lea eax, [eax + ecx * 4]
|
|
add eax, 15
|
|
and eax, ~15
|
|
mov ecx, [edi + 8]
|
|
lea eax, [eax + ecx]
|
|
add eax, 4096 + 4095
|
|
and eax, ~4095
|
|
mov edi, eax
|
|
mov ebx, 0x40000000
|
|
call rebase_module32
|
|
sub edx, edi
|
|
|
|
push strict dword edx
|
|
push strict dword edi
|
|
push strict dword 0x40000000
|
|
push strict dword 1 ;user
|
|
lea eax, [edi - 4096] ; cr3
|
|
push eax
|
|
.VPM_MAP_ENTRY equ ($ + 1)
|
|
mov eax, strict dword 0
|
|
call eax
|
|
add esp, 20
|
|
|
|
push strict dword 0
|
|
.SCHEDULER_SPAWN_ENTRY equ ($ + 1)
|
|
mov eax, strict dword 0
|
|
call eax
|
|
add esp, 4
|
|
lea ebx, [edi - 4096]
|
|
mov [eax + 46], ebx ;cr3
|
|
mov ebx, [edi + 14] ;get sym 0 (modentry)
|
|
add ebx, [edi] ;add data offset
|
|
mov [eax + 34], ebx ;eip
|
|
|
|
dec ebp
|
|
jnz .modspawnlup
|
|
|
|
.SCHEDULER_START_ENTRY equ ($ + 1)
|
|
mov eax, strict dword 0
|
|
jmp eax
|
|
|
|
print32:
|
|
push ebx
|
|
push eax
|
|
push ecx
|
|
movzx ebx, word [BOOT1_ADDR + .LAST]
|
|
mov ecx, eax
|
|
.lup:
|
|
mov al, [esi]
|
|
mov [0xB8000 + ebx], al
|
|
inc esi
|
|
inc ebx
|
|
inc ebx
|
|
dec ecx
|
|
jnz .lup
|
|
mov [BOOT1_ADDR + .LAST], bx
|
|
pop ecx
|
|
pop eax
|
|
pop ebx
|
|
ret
|
|
.LAST: dw 0
|
|
|
|
; In: EDI = module pointer, EBX = rebase address
|
|
; Out: EDX = physical module end
|
|
rebase_module32:
|
|
push ecx
|
|
push eax
|
|
push ebx
|
|
push ebp
|
|
movzx ecx, word [edi + 4]
|
|
lea eax, [edi + 12 + ecx * 2]
|
|
lea eax, [eax + ecx * 4] ; eax = relocations pointer
|
|
movzx ecx, word [edi + 6] ;ecx = amount of relocations
|
|
lea edx, [eax + ecx * 4] ; edx = data pointer
|
|
add edx, 15
|
|
and edx, ~15
|
|
mov [edi], edx ;Store offset of data buffer in
|
|
sub [edi], edi ;file in place of magic header
|
|
add [edi], ebx ;
|
|
mov ebx, [edi]
|
|
test ecx, ecx
|
|
jz .end
|
|
.lup:
|
|
mov ebp, [eax]
|
|
add [edx + ebp], ebx
|
|
add eax, 4
|
|
dec ecx
|
|
jnz .lup
|
|
.end:
|
|
add edx, [edi + 8]
|
|
pop ebp
|
|
pop ebx
|
|
pop eax
|
|
pop ecx
|
|
ret
|
|
|
|
MSG_FAIL: db "Failed to detect memory map. "
|
|
.end:
|
|
|
|
MSG_START: db "Starting eklernel. "
|
|
.end:
|
|
|
|
MSG_DETECTED_MEMORY_MAP: db "Found memory map. "
|
|
.end:
|
|
|
|
MSG_STEP2s: db "Entered protected mode. "
|
|
.end:
|
|
|
|
MSG_STEP3s: db "Generated paging structures. "
|
|
.end:
|
|
|
|
MSG_STEP4f: db "Boot filesystem must have block size of 1024. "
|
|
.end:
|
|
|
|
KERNEL_FILE: db "krnl.mod"
|
|
.end:
|
|
|
|
MSG_STEP5f: db "Kernel not found; aborting boot. "
|
|
.end:
|
|
|
|
GDT:
|
|
dw (GDT.END - GDT) - 1 ;GDT descriptor in the null entry
|
|
dd BOOT1_ADDR + GDT
|
|
dw 0
|
|
|
|
dw 0xFFFF, 0x0000
|
|
db 0x00, BIT_READWRITE | BIT_EXECUTABLE | BIT_ISCODEORDATA | BIT_PRESENT | (0 << 5)
|
|
.R0CSLIMFLAGS:
|
|
db (128 | 64) | 0xF
|
|
db 0
|
|
|
|
dw 0xFFFF, 0x0000
|
|
db 0x00, BIT_READWRITE | BIT_ISCODEORDATA | BIT_PRESENT | (0 << 5)
|
|
db (128 | 64) | 0xF
|
|
db 0
|
|
|
|
dw 0xFFFF, 0x0000
|
|
db 0x00, BIT_READWRITE | BIT_EXECUTABLE | BIT_ISCODEORDATA | BIT_PRESENT | (3 << 5)
|
|
db (128 | 64) | 0xF
|
|
db 0
|
|
|
|
dw 0xFFFF, 0x0000
|
|
db 0x00, BIT_READWRITE | BIT_ISCODEORDATA | BIT_PRESENT | (3 << 5)
|
|
db (128 | 64) | 0xF
|
|
db 0
|
|
|
|
dw (TSS.END - TSS) - 1
|
|
dw TSS
|
|
db BOOT1_ADDR / 0x10000, 1 | 8 | 128
|
|
db 0, 0
|
|
.END:
|
|
TSS:
|
|
dd 0
|
|
.esp0: dd 0
|
|
.ss0: dd 0
|
|
times 23 dd 0
|
|
.END:
|
|
|
|
end:
|
|
times (end - start + 511) / 512 * 512 - ($ - $$) db 0
|
|
endSector:
|