bsdsylvia
bsdsylvia

Reputation: 93

Bootloader memory map function causes kernel to never be called

I am currently writing a 32bit operating system, and while trying to get the memory map in order to write a memory manager, I am using the following function from the brokenthorn tutorial

memmap.asm

struc MemoryMapEntry
    .baseAddress                        resq    1   ; base address of address range
    .length                             resq    1   ; length of address range in bytes
    .type                               resd    1   ; type of address range
    .acpi_null                          resd    1   ; reserved
endstruc

BiosGetMemoryMap:
    pushad
    xor    ebx, ebx
    xor    bp, bp            ; number of entries stored here
    mov    edx, 'PAMS'
    mov    eax, 0xe820
    mov    ecx, 24            ; memory map entry struct is 24 bytes
    int    0x15            ; get first entry
    jc    .error    
    cmp    eax, 'PAMS'        ; bios returns SMAP in eax
    jne    .error
    test    ebx, ebx        ; if ebx=0 then list is one entry long; bail out
    je    .error
    jmp    .start
.next_entry:
    mov    edx, 'PAMS'        ; some bios's trash this register
    mov    ecx, 24            ; entry is 24 bytes
    mov    eax, 0xe820
    int    0x15            ; get next entry
.start:
    jcxz    .skip_entry        ; if actual returned bytes is 0, skip entry
.notext:
    mov    ecx, [es:di + MemoryMapEntry.length]    ; get length (low dword)
    test    ecx, ecx        ; if length is 0 skip it
    jne    short .good_entry
    mov    ecx, [es:di + MemoryMapEntry.length + 4]; get length (upper dword)
    jecxz    .skip_entry        ; if length is 0 skip it
.good_entry:
    inc    bp            ; increment entry count
    add    di, 24            ; point di to next entry in buffer
.skip_entry:
    cmp    ebx, 0            ; if ebx return is 0, list is done
    jne    .next_entry        ; get next entry
    jmp    .done
.error:
    stc
.done:
    popad
    ret

loader.asm

; Fortress Bootloader
; The quasar bootloader is a bare metal bootloader
; It can load 128 sectors, and is meant to load a 
; tiny but powerful kernel

[bits 16]
[extern kernel]
[global isr_stub_table]
[global IDT_load]

[extern FortressLoader_IdtInit]
[extern FortressLoader_ChecmMemMap]

[extern X86TTY_Init]
[extern X86TTY_Clear]
[extern printf]

[global startKernel]

section .boot
global boot

KERNEL_SIZE_SECTORS equ 128


jmp $boot


bpbBytesPerSector:          DW 512
bpbSectorsPerCluster:       DB 1
bpbReservedSectors:         DW 1
bpbNumberOfFATs:            DB 2
bpbRootEntries:             DW 224
bpbTotalSectors:            DW 2880
bpbMedia:                   DB 0xF0
bpbSectorsPerFAT:           DW 9
bpbSectorsPerTrack:         DW 18
bpbHeadsPerCylinder:        DW 2
bpbHiddenSectors:           DD 0
bpbTotalSectorsBig:         DD 0
bsDriveNumber:              DB 0
bsUnused:                   DB 0
bsExtBootSignature:         DB 0x29
bsSerialNumber:             DD 0xa0a1a2a3
bsVolumeLabel:              DB "6STAR OS   "
bsFileSystem:               DB "FAT12   "



%include "./fortressloader/memory.asm"
%include "./fortressloader/memmap.asm"
%include "./fortressloader/multiboot.asm"

test_message db "test", 0

boot:
    cld
    
    xor                                 ax, ax
    mov                                 ds, ax 
    mov                                 ss, ax
    mov                                 sp, 0x7c00
    mov                                 di, 0x7c00

    cli


    mov                                 [disk], dl
    mov                                 ax, 0x2401
    int                                 0x15
 
    mov                                 ax, 0x3                                 ;Set the VGA mode, unknown at boot
    int                                 0x10
 
    mov                                 ah, 42h                                 ;Do modern disk reading (no fuckery)
    mov                                 dl, [disk]                              ;Account for cosmic bit flips
    mov                                 si, dap                                 ;Load disk address packet
    int                                 0x13
 
    jc                                  disk_err                                ;Jump if disk read error
    jmp                                 disk_target                             ;





print:
    pusha
start:
    mov                                 al, [bx] 
    cmp                                 al, 0 
    je                                  done
 
    mov                                 ah, 0x0e
    int                                 0x10 
 
    add                                 bx, 1
    jmp                                 start
 
done:
    popa
    ret
 
print_nl:
    pusha
 
    mov                                 ah, 0x0e
    mov                                 al, 0x0a
    int                                 0x10
    mov                                 al, 0x0d
    int                                 0x10
 
    popa
    ret
 
print_hex:
    pusha
 
    mov                                 cx, 0
 
hex_loop:
    cmp                                 cx, 4
    je                                  end
 
    mov                                 ax, dx
    and                                 ax, 0x000f
    add                                 al, 0x30 
    cmp                                 al, 0x39
    jle                                 step2
    add                                 al, 7
 
step2:
    mov                                 bx, HEX_OUT + 5
    sub                                 bx, cx
    mov                                 [bx], al
    ror                                 dx, 4
 
    add                                 cx, 1
    jmp                                 hex_loop
 
end:
    mov                                 bx, HEX_OUT
    call                                print
 
    popa
    ret
 
disk_err:                                                                       ;Label for any disk errors
    mov                                 bx, disk_read_error                     ;Print the disk error
    call                                print
    call                                print_nl
    mov                                 dh, ah                                  ;Load error code in ah register
    call                                print_hex
    jmp                                 $
 
GDT_START:
    dq    0x0
GDT_CODE:                                                                       ;base = 0x00000000, length = 0xfffff
    dw                                  0xffff                                  ;segment length, bits 0-15
    dw                                  0x0                                     ;segment base, bits 0-15
    db                                  0x0                                     ;segment base, bits 16-23
    db                                  10011010b                               ;flags (8 bits)
    db                                  11001111b                               ;flags (4 bits) + segment length
    db                                  0x0                                     ;segment base, bits 24-31
GDT_DATA:
    dw                                  0xFFFF
    dw                                  0x0
    db                                  0x0
    db                                  10010010b
    db                                  11001111b
    db                                  0x0
GDT_END:
GDT_POINTER:
    dw                                  GDT_END - GDT_START
    dd                                  GDT_START
 
CODE_SEG                                equ GDT_CODE - GDT_START
DATA_SEG                                equ GDT_DATA - GDT_START
 

disk:
    db                                  0x0

dap:
    db                                  0x10
    db                                  0
    dw                                  KERNEL_SIZE_SECTORS
    dw                                  0                                       ;
    dw                                  0x07e0                                  ;value recommended by a friend
    dq                                  1                                       ;start second sector read
 
HEX_OUT:
    db                                  '0x0000',0
 
disk_read_error:                        db "Disk read error!", 0
 
times 510 - ($-$$) db 0
dw 0xAA55




disk_target:
    call                                BiosGetMemorySize64MB                   ;Load the memory size
    mov                                 [mbInfo+mbInfo.memoryHi], bx
    mov                                 [mbInfo+mbInfo.memoryLo], ax
    mov                            word [mbInfo+mbInfo.bootDevice], 0x0

    call                                BiosGetMemoryMap
    mov                            word [mbInfo+mbInfo.mmap_length], ax
    mov                            word [mbInfo+mbInfo.mmap_addr], 0x2000

    cli                                                                         ;Clear the interrupts
    lgdt                                [GDT_POINTER]                           ;Load the GDT using a gdt pointer
    mov                                 eax, cr0
    or                                  eax, 0x1
    mov                                 cr0, eax
    jmp                                 CODE_SEG:boot2

[bits 32]
startKernel:
boot2:
    mov                                 ax, DATA_SEG
    mov                                 ds, ax
    mov                                 es, ax
    mov                                 fs, ax
    mov                                 gs, ax
    mov                                 ss, ax
    mov                                 esi, loaded_msg
    mov                                 ebx, 0xb8000
.loop:                                                                          ;Print a message using a loop
    lodsb
    or                                  al, al
    jz                                  load_kernel                             ;Load kern when msg finished
    or                                  eax,0x0F00
    mov                                 word [ebx], ax
    add                                 ebx,2
    jmp                                 .loop
load_kernel:
    mov                                 esp, kernel_stack_top                   ;Load the stack to call C functions

    call                                X86TTY_Init                             ;Initalize the TTY
    call                                X86TTY_Clear                            ;Clear everything on the screen
    call                                FortressLoader_IdtInit                  ;Initalize the IDT    

    mov                                 eax, 0x2BADB002                         ;Multiboot magic number
    mov                                 ebx, mbInfo
    mov                                 ebx, 0


    call                                kernel                                  ;Call the actual kernel
halt:    
    cli
    hlt





loaded_msg:                             db "Operating system loaded",0          ;Message here to verify disk read
 
section .bss
align 4
kernel_stack_bottom:                    equ $                                   ;equ the current address for the stack
    resb                                16384                                   ;Use 16kb for stack size
kernel_stack_top:                                                               ;Top of the stack

section                                 .text                                   ;Fuck bss and asm sections

Hoever, my problem is that this causes Qemu to never call the kernel, or what seems like anything after this

I have tried commenting out certain lines out of the bootloader, and have realized that it is the specific instruction mov edx, 'PAMS' on line 12. When commenting out that specific line, there are no issues. What can I do to solve this?

Upvotes: 0

Views: 76

Answers (1)

bsdsylvia
bsdsylvia

Reputation: 93

Fixed! I was missing a mov edi, 0x2000 right after mov word [mbInfo+mbInfo.bootDevice], 0x0

Upvotes: 2

Related Questions