assembly 引导装载程序内存Map函数导致内核永远不会被调用

gcxthw6b  于 2023-02-12  发布在  其他
关注(0)|答案(1)|浏览(142)

我目前正在编写一个32位操作系统,在尝试获取内存Map以便编写内存管理器时,我使用了brokenthorn教程中的以下函数
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

然而,我的问题是,这会导致Qemu永远不会调用内核,或者这之后的任何事情
我尝试过注解掉引导装载程序中的某些行,并意识到这是第12行上的特定指令mov edx, 'PAMS'。注解掉该特定行时,没有任何问题。我可以做些什么来解决这个问题?

ncecgwcz

ncecgwcz1#

修复!我在mov word [mbInfo+mbInfo.bootDevice], 0x0之后缺少一个mov edi, 0x2000

相关问题