|
|
|
|
@ -250,7 +250,11 @@ main:
|
|
|
|
|
call mem_detect
|
|
|
|
|
jc .mem_detect_fail
|
|
|
|
|
|
|
|
|
|
call print_memmap
|
|
|
|
|
|
|
|
|
|
.hlt_loop:
|
|
|
|
|
hlt
|
|
|
|
|
jmp .hlt_loop
|
|
|
|
|
|
|
|
|
|
.mem_detect_fail:
|
|
|
|
|
panic PANIC_TYPE_MEM_DETECT
|
|
|
|
|
@ -605,6 +609,38 @@ nybble_to_hex_char:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Copy a null-terminated string from ds:cx to es:ax.
|
|
|
|
|
; - es: output buffer segment
|
|
|
|
|
; - ax: output buffer offset
|
|
|
|
|
; - ds: input buffer segment
|
|
|
|
|
; - cx: input buffer offset
|
|
|
|
|
; Return:
|
|
|
|
|
; - ax: the address of the null terminator that was written
|
|
|
|
|
; Clobber: none
|
|
|
|
|
strcpy:
|
|
|
|
|
fnstart
|
|
|
|
|
push si
|
|
|
|
|
push di
|
|
|
|
|
|
|
|
|
|
mov di, ax
|
|
|
|
|
mov si, cx
|
|
|
|
|
|
|
|
|
|
.loop:
|
|
|
|
|
mov al, [si]
|
|
|
|
|
mov es:[di], al
|
|
|
|
|
test al, al
|
|
|
|
|
jz .done
|
|
|
|
|
inc si
|
|
|
|
|
inc di
|
|
|
|
|
jmp .loop
|
|
|
|
|
|
|
|
|
|
.done:
|
|
|
|
|
mov ax, di
|
|
|
|
|
pop di
|
|
|
|
|
pop si
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Check whether the A20 line is enabled. Writes to the boot sector identifier.
|
|
|
|
|
; Arguments: none
|
|
|
|
|
; Return:
|
|
|
|
|
@ -711,10 +747,6 @@ enable_a20_intel_8042:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mem_detect:
|
|
|
|
|
%if MEMMAP_CAP < 1
|
|
|
|
|
%error "memmap buffer too small"
|
|
|
|
|
%endif
|
|
|
|
|
|
|
|
|
|
fnstart
|
|
|
|
|
push es
|
|
|
|
|
|
|
|
|
|
@ -731,39 +763,43 @@ mem_detect:
|
|
|
|
|
xor ebx, ebx
|
|
|
|
|
; Buffer (es:di)
|
|
|
|
|
mov di, MEMMAP
|
|
|
|
|
mov dword [di + 0x20], 0x1
|
|
|
|
|
; Entry size
|
|
|
|
|
mov ecx, MEMMAP_ENT_SIZE
|
|
|
|
|
; Magic number
|
|
|
|
|
mov edx, E820_MAGIC
|
|
|
|
|
; Detect memory
|
|
|
|
|
mov eax, 0xe820
|
|
|
|
|
clc
|
|
|
|
|
int 0x15
|
|
|
|
|
jc .fail
|
|
|
|
|
cmp eax, E820_MAGIC
|
|
|
|
|
jne .fail
|
|
|
|
|
|
|
|
|
|
inc word [GLOBALS + MEMMAP_ENTRIES]
|
|
|
|
|
|
|
|
|
|
.loop:
|
|
|
|
|
cmp word [GLOBALS + MEMMAP_ENTRIES], MEMMAP_CAP
|
|
|
|
|
jae .done
|
|
|
|
|
|
|
|
|
|
add di, MEMMAP_ENT_SIZE
|
|
|
|
|
mov dword [di + 0x20], 0x1
|
|
|
|
|
mov ecx, MEMMAP_ENT_SIZE
|
|
|
|
|
; Init extended field to 0x1 in case e820 doesn't populate it.
|
|
|
|
|
mov dword [di + MEMMAP_ENT_FIELD_EXT], 0x1
|
|
|
|
|
; Size of entry for e820 to write
|
|
|
|
|
mov ecx, E820_ENTRY_SIZE
|
|
|
|
|
; Magic number
|
|
|
|
|
mov edx, E820_MAGIC
|
|
|
|
|
; Detect memory
|
|
|
|
|
mov eax, 0xe820
|
|
|
|
|
clc
|
|
|
|
|
int 0x15
|
|
|
|
|
; Carry flag will be set if we'd already reached the end of the entries.
|
|
|
|
|
jc .done
|
|
|
|
|
|
|
|
|
|
; Test magic number
|
|
|
|
|
cmp eax, E820_MAGIC
|
|
|
|
|
jne .fail
|
|
|
|
|
|
|
|
|
|
inc word [GLOBALS + MEMMAP_ENTRIES]
|
|
|
|
|
|
|
|
|
|
; Calculate and cache the entry end address.
|
|
|
|
|
mov eax, [di + MEMMAP_ENT_FIELD_BASE]
|
|
|
|
|
add eax, [di + MEMMAP_ENT_FIELD_LEN]
|
|
|
|
|
mov [di + MEMMAP_ENT_FIELD_END], eax
|
|
|
|
|
mov eax, [di + MEMMAP_ENT_FIELD_BASE + 4]
|
|
|
|
|
adc eax, [di + MEMMAP_ENT_FIELD_LEN + 4]
|
|
|
|
|
mov [di + MEMMAP_ENT_FIELD_END + 4], eax
|
|
|
|
|
|
|
|
|
|
; e820 _may_ return ebx=0 once we reach the last entry.
|
|
|
|
|
test ebx, ebx
|
|
|
|
|
jz .done
|
|
|
|
|
|
|
|
|
|
add di, MEMMAP_ENT_SIZE
|
|
|
|
|
jmp .loop
|
|
|
|
|
|
|
|
|
|
.fail:
|
|
|
|
|
@ -771,6 +807,9 @@ mem_detect:
|
|
|
|
|
jmp .return
|
|
|
|
|
|
|
|
|
|
.done:
|
|
|
|
|
mov ax, [GLOBALS + MEMMAP_ENTRIES]
|
|
|
|
|
test ax, ax
|
|
|
|
|
jz .fail
|
|
|
|
|
clc
|
|
|
|
|
|
|
|
|
|
.return:
|
|
|
|
|
@ -778,12 +817,107 @@ mem_detect:
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print_memmap:
|
|
|
|
|
fnstart
|
|
|
|
|
|
|
|
|
|
sub sp, VGA_WIDTH
|
|
|
|
|
push eax
|
|
|
|
|
push ebx
|
|
|
|
|
push ecx
|
|
|
|
|
push edx
|
|
|
|
|
|
|
|
|
|
mov si, MEMMAP
|
|
|
|
|
mov dx, [GLOBALS + MEMMAP_ENTRIES]
|
|
|
|
|
|
|
|
|
|
.loop:
|
|
|
|
|
test dx, dx
|
|
|
|
|
jz .done
|
|
|
|
|
dec dx
|
|
|
|
|
|
|
|
|
|
push es
|
|
|
|
|
mov ax, ss
|
|
|
|
|
mov es, ax
|
|
|
|
|
|
|
|
|
|
; Calculate region end
|
|
|
|
|
; mov eax, [si]
|
|
|
|
|
; mov ecx, [si + 8]
|
|
|
|
|
; add eax, ecx
|
|
|
|
|
; push eax
|
|
|
|
|
; mov eax, [si + 4]
|
|
|
|
|
; mov eax, [si + 12]
|
|
|
|
|
; adc eax, ecx
|
|
|
|
|
; push eax
|
|
|
|
|
|
|
|
|
|
lea ax, [bp - VGA_WIDTH]
|
|
|
|
|
|
|
|
|
|
mov cx, msg_memmap_base
|
|
|
|
|
call strcpy
|
|
|
|
|
|
|
|
|
|
mov ecx, [si + MEMMAP_ENT_FIELD_BASE + 4]
|
|
|
|
|
call dump_reg
|
|
|
|
|
mov ecx, [si + MEMMAP_ENT_FIELD_BASE]
|
|
|
|
|
call dump_reg
|
|
|
|
|
|
|
|
|
|
mov cx, msg_sep
|
|
|
|
|
call strcpy
|
|
|
|
|
mov cx, msg_memmap_len
|
|
|
|
|
call strcpy
|
|
|
|
|
|
|
|
|
|
mov ecx, [si + MEMMAP_ENT_FIELD_LEN + 4]
|
|
|
|
|
call dump_reg
|
|
|
|
|
mov ecx, [si + MEMMAP_ENT_FIELD_LEN]
|
|
|
|
|
call dump_reg
|
|
|
|
|
|
|
|
|
|
mov cx, msg_sep
|
|
|
|
|
call strcpy
|
|
|
|
|
mov cx, msg_memmap_end
|
|
|
|
|
call strcpy
|
|
|
|
|
|
|
|
|
|
mov ecx, [si + MEMMAP_ENT_FIELD_END + 4]
|
|
|
|
|
call dump_reg
|
|
|
|
|
mov ecx, [si + MEMMAP_ENT_FIELD_END]
|
|
|
|
|
call dump_reg
|
|
|
|
|
|
|
|
|
|
mov cx, msg_sep
|
|
|
|
|
call strcpy
|
|
|
|
|
mov cx, msg_memmap_type
|
|
|
|
|
call strcpy
|
|
|
|
|
|
|
|
|
|
mov ecx, [si + MEMMAP_ENT_FIELD_TYPE]
|
|
|
|
|
call dump_reg
|
|
|
|
|
|
|
|
|
|
mov bx, ax
|
|
|
|
|
mov byte [bx], 0
|
|
|
|
|
|
|
|
|
|
lea ax, [bp - VGA_WIDTH]
|
|
|
|
|
call vga_println
|
|
|
|
|
|
|
|
|
|
pop es
|
|
|
|
|
add si, MEMMAP_ENT_SIZE
|
|
|
|
|
jmp .loop
|
|
|
|
|
|
|
|
|
|
.done:
|
|
|
|
|
pop edx
|
|
|
|
|
pop ecx
|
|
|
|
|
pop ebx
|
|
|
|
|
pop eax
|
|
|
|
|
add sp, VGA_WIDTH
|
|
|
|
|
fnret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
msg_boot1_loaded db "boot1 loaded. hello!", 0
|
|
|
|
|
msg_a20_enabled db "a20 enabled", 0
|
|
|
|
|
msg_a20_disabled db "a20 not enabled", 0
|
|
|
|
|
msg_a20_8042 db "trying 8042", 0
|
|
|
|
|
msg_panic db "panic!", 0
|
|
|
|
|
|
|
|
|
|
msg_sep db ",", 0
|
|
|
|
|
msg_memmap_base db "base=", 0
|
|
|
|
|
msg_memmap_end db "end=", 0
|
|
|
|
|
msg_memmap_len db "len=", 0
|
|
|
|
|
msg_memmap_type db "type=", 0
|
|
|
|
|
msg_memmap_ext db "ext=", 0
|
|
|
|
|
|
|
|
|
|
msg_reg_eip db "eip", 0
|
|
|
|
|
msg_reg_eax db "eax", 0
|
|
|
|
|
msg_reg_ebx db "ebx", 0
|
|
|
|
|
|