【发布时间】:2021-03-27 15:16:24
【问题描述】:
不久前,我正在研究一个简单的引导加载程序项目,我决定重新开始研究它。无论如何,我正在尝试使用BIOS INT=15H EAX=E820h 检测内存。我在循环中使用了中断,并为内存映射分配了空间来保存所有条目。现在我正在尝试从最后一个条目开始解析条目。我的目标是找到最大的 1MB 区域,可以用来存放我从磁盘读取的文件。
到目前为止,这是我的代码。它正在 Bochs 2.6.11 上进行测试,具有 32MB 的 RAM,其他一切都设置为默认设置。当然是16位实模式代码。
[bits 16]
BlEntry:
[...] ; above here all I did was set all segments to 0, except DS which is set to 7C0h
;
; Build the system's memory map
;
xor ebx, ebx ; HANDLE for next call
mov edx, 534D4150h ; magic
mov ecx, 20 ; buffer size
sub sp, cx ; allocate 20 bytes
mov di, sp ; di points to buffer
BlpBuildMmBegin:
mov eax, 0E820h ; magic
mov [di+20], DWORD 1 ; Request ACPI compat-entry
int 15h
jc BlInt10Failure
cmp eax, edx ; magics should match
jne BlInt10Failure
test ebx, ebx ; are we finished?
je BlpFindEiArea ; jump out
sub sp, cx ; allocate 20 bytes again
mov di, sp ; setup di again
jmp BlpBuildMmBegin ; do it all again
BlpBuildMmEnd:
;
; Load the EI into memory
;
; try to find the highest address we can map the EI to
BlpFindEiAreaStart:
add di, 20 ; move onto the next entry
cmp di, bp
je BlNoMemoryFailure
BlpFindEiArea:
cmp [di+16], DWORD 1 ; check if we can use this memory region
jne BlpFindEiAreaStart ; of not, try again
cmp [di+8], DWORD 100000h ; 1MB EI file size
jge BlpFindEiAreaEnd
jmp BlpFindEiAreaStart
BlpFindEiAreaEnd:
mov eax, DWORD [di]
cli
hlt ;hang the system for now, I still need to add more functionality here
正如代码所示,当我遍历所有内容时,执行跳转到BlNoMemoryFailure,它只是使用电传输出显示No Memory! 输出然后挂起系统。这就是问题所在 - 我无法让此代码停止说出该消息。我的结构错了吗?我在编写代码时引用了这个网站http://www.uruk.org/orig-grub/mem64mb.html
【问题讨论】:
-
使用调试器检查条目是否有意义。此外,您似乎只检查了最后一批区域。你的循环错了。
-
BlNoMemoryFailure会发生什么?您可以将其定义添加到您的问题中吗?你提到它应该输出东西然后挂起,但实际行为是不同的。
标签: assembly x86-16 bootloader boot