Я пытаюсь обнаружить память с помощью eax=0xe820 int 15h
перед загрузкой ядра в мой загрузчик. Итак, я провел некоторое исследование и увидел, что проблема в EDX registers
. Я думаю, что я подготовил DL
и BX
для загрузки ядра, а затем уничтожил их, вызвав do_e820
.
Итак, есть мой файл загрузчика (bootloader.asm):
[bits 16]
global _start
number_sector db 0
_start:
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x8000 ; Stack pointer at SS:SP = 0x0000:0x8000
mov [BOOT_DRIVE], dl; Boot drive passed to us by the BIOS
mov dh, 17 ; Number of sectors (kernel.bin) to read from disk
; 17*512 allows for a kernel.bin up to 8704 bytes
mov bx, 0x9000 ; Load Kernel to ES:BX = 0x0000:0x9000
call do_E820
call load_kernel
call enable_A20
; call graphics_mode ; Uncomment if you want to switch to graphics mode 0x13
lgdt [gdtr]
mov eax, cr0
or al, 1
mov cr0, eax
jmp CODE_SEG:init_pm
graphics_mode:
mov ax, 0013h
int 10h
ret
load_kernel:
; load DH sectors to ES:BX from drive DL
push dx ; Store DX on stack so later we can recall
; how many sectors were request to be read ,
; even if it is altered in the meantime
mov ah , 0x02 ; BIOS read sector function
mov al , dh ; Read DH sectors
mov ch , 0x00 ; Select cylinder 0
mov dh , 0x00 ; Select head 0
mov cl , 0x02 ; Start reading from second sector ( i.e.
; after the boot sector )
int 0x13 ; BIOS interrupt
jc disk_error ; Jump if error ( i.e. carry flag set )
pop dx ; Restore DX from the stack
cmp dh , al ; if AL ( sectors read ) != DH ( sectors expected )
jne disk_error ; display error message
ret
disk_error:
mov bx , ERROR_MSG
call print_string
hlt
; prints a null - terminated string pointed to by EDX
print_string:
pusha
push es ;Save ES on stack and restore when we finish
push VIDEO_MEMORY_SEG ;Video mem segment 0xb800
pop es
xor di, di ;Video mem offset (start at 0)
print_string_loop:
mov al , [ bx ] ; Store the char at BX in AL
mov ah , WHITE_ON_BLACK ; Store the attributes in AH
cmp al , 0 ; if (al == 0) , at end of string , so
je print_string_done ; jump to done
mov word [es:di], ax ; Store char and attributes at current
; character cell.
add bx , 1 ; Increment BX to the next char in string.
add di , 2 ; Move to next character cell in vid mem.
jmp print_string_loop ; loop around to print the next char.
print_string_done:
pop es ;Restore ES that was saved on entry
popa
ret ; Return from the function
%include "BOOT/a20.inc"
%include "BOOT/gdt.inc"
%include "BOOT/detect_mem.inc"
[bits 32]
init_pm:
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000
mov esp, ebp
call 0x9000
cli
loopend: ;Infinite loop when finished
jmp loopend
[bits 16]
; Variables
ERROR db "A20 Error!" , 0
ERROR_MSG db "Error!" , 0
BOOT_DRIVE: db 0
VIDEO_MEMORY_SEG equ 0xb800
WHITE_ON_BLACK equ 0x0f
times 510-($-$$) db 0
db 0x55
db 0xAA
и есть моя функция по обнаружению памяти (detect_mem.in c):
entries equ 0
buffer equ 1
do_E820:
pushf
pusha
mov edi , buffer ;destination buffer
mov byte [edi+20] , 1 ;Force a vaalid ACPI
.begin:
xor ebx , ebx
mov edx , 0x534D4150
mov eax , 0xE820
mov ecx , 24
int 0x15
jc .failed
mov edx , 0x534D4150
cmp eax,edx ;voir si eax est different de 0x534D4150
jne .failed
test ebx , ebx ;EBX will be set to some non-zero value
je .failed
jmp .verify
.do_E820_loop:
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
mov [es:di+20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes again
int 0x15
jc .e820_failed
.verify:
jcxz .skip_entries ;Length of "region" (if this value is 0, ignore the entry)
cmp cl , 20
jbe .extension
cmp byte [es:di+20] , 0
je .skip_entries
.extension: ;go to the next buffer if cl equal 24
push eax
mov eax , dword [entries]
inc eax
mov dword [entries] , eax
pop eax
mov ecx , [es:di+8]
jcxz .skip_entries
add di ,24
.skip_entries:
test ebx , ebx ;if ebx resets to 0, list is complete
jne .do_E820_loop
.e820_failed:
clc
popa
popf
ret
.failed:
stc
popa
popf
ret
Пожалуйста, вы можете мне что-то посоветовать, если я сделал чужие ошибки, пожалуйста, посоветуйте мне тоже ,