[英]FASM bootloader in bochs hlp
I was trying to write my own bootloader on fasm assembly, but unsucces.我试图在 fasm 汇编上编写自己的引导加载程序,但没有成功。
Result: Prefetch: EIP 00010000 > CS.limit 0000ffff结果:预取:EIP 00010000 > CS.limit 0000ffff
Code:代码:
org 0x7C00
mov ax, 0x02
int 0x10
mov si, boot_msg
call printf
mov al, 0x01 ; secror to read
mov bx, 0x7E00 ; dest
mov cx, 0x0002 ; cylinder:sector
mov dl, 0x01 ; floppy
call disk_read
mov ax, 0x7E00
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x7E00:0x0000
include 'disk.asm'
include 'printh.asm'
boot_msg db 'R-OS BOOTLOADER
',\
'KERNEL CHS 0 0 1', 0x00
times 510-$+$$ db 0x00
dw 0xAA55
;;;;;;;;; kernel! ;;;;;;;;;;
org 0x7E00
mov ah, 0x0E
mov al, 'X'
int 0x10
cli hlt
times 4096-512-$+$$ db 0x00
disk.asm:磁盘.asm:
disk_read:
pusha
mov si, 0x02
.top:
mov ah, 0x02
int 0x13
jnc .end
xor ah, ah
int 0x13
jnc .top
jc .err
.end:
popa
ret
.msg db 'disk rw err', 0x00
.err:
popa
pusha
mov ah, 0x0E
mov si, .msg
jmp .l
.l:
lodsb
cmp al, 0x00
je .end
int 0x10
printh.asm just have print functions. printh.asm 只有打印功能。
I cant understand, why it is doesn't work.我不明白,为什么它不起作用。 I was trying a lot of variants of solve, but not one working in this list.我尝试了很多解决方案的变体,但没有一个在这个列表中起作用。
please, help请帮忙
To successfully use the BIOS.ReadSectors function 02h, you need to setup all its parameters!要成功使用BIOS.ReadSectors function 02h,您需要设置它的所有参数! You didn't initialize the ES
segment register, nor did you specify the head number in the DH
register.你没有初始化ES
段寄存器,也没有指定DH
寄存器中的头号。 Presumably you think that all registers start out with zero, but this is not the case!大概你认为所有的寄存器都是从零开始的,但事实并非如此! The only register that your bootloader receives is the DL
register that holds the number for the boot drive.引导加载程序接收的唯一寄存器是保存引导驱动器编号的DL
寄存器。 That will be the number that you need to provide to this function.这将是您需要提供给这个 function 的号码。
You are loading the additional sector at offset address 0x7E00.您正在加载偏移地址 0x7E00 处的附加扇区。 Because ES=0
(assuming), this is segmented address 0x0000:0x7E00.因为ES=0
(假设),这是分段地址 0x0000:0x7E00。 You can jmp
to this address in a number of ways, but if you want to do it with a zero offset, then the segment part will have to be 0x07E0.您可以通过多种方式jmp
到该地址,但如果您想使用零偏移量执行此操作,则段部分必须为 0x07E0。 That's how segmentation works.这就是分段的工作原理。
You can read more about bootloaders in my answer at ( https://stackoverflow.com/questions/34216893/disk-read-error-while-loading-sectors-into-memory/34382681?r=SearchResults&s=21|9.2814#34382681 ) and in Michael Petch's answer at ( https://stackoverflow.com/questions/32701854/boot-loader-doesnt-jump-to-kernel-code/32705076?r=SearchResults&s=46|10.4269#32705076 ).您可以在我的回答中阅读有关引导加载程序的更多信息,网址为 ( https://stackoverflow.com/questions/34216893/disk-read-error-while-loading-sectors-into-memory/34382681?r=SearchResults&s=21|9.2814#34382681 ) 和 Michael Petch 在 ( https://stackoverflow.com/questions/32701854/boot-loader-doesnt-jump-to-kernel-code/32705076?r=SearchResults&s=46|10.4269#32705076 ) 的回答。
This is an improved version:这是一个改进版本:
ORG 0x7C00
xor ax, ax ; Setup segment registers in accordance with the `ORG 0x7C00`
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
cld ; Once at the top of every program
mov ax, 0x0003
int 0x10
mov si, boot_msg
call printf
mov al, 1 ; Number of sectors to read
mov bx, 0x7E00 ; ES:BX
mov cx, 0x0002 ; Cylinder, Sector
mov dh, 0 ; Head, DL is bootdrive
call disk_read
mov ax, 0x07E0 ; How segmentation works!
mov ds, ax
mov es, ax
jmp 0x07E0:0x0000
include 'disk.asm'
include 'printh.asm'
boot_msg db 'R-OS BOOTLOADER
',\
'KERNEL CHS 0 0 1', 0
times 510-($-$$) db 0
dw 0xAA55
;;;;;;;;; kernel! ;;;;;;;;;;
ORG 0x7E00
mov bh, 0 ; Don't forget to mention the DisplayPage
mov ah, 0x0E
mov al, 'X'
int 0x10
cli
hlt
jmp $-2
times 4096-512-($-$$) db 0
In the disk.asm file, you are trying to implement a retry count, but you forget to actually decrement the counter if an error occured.在disk.asm文件中,您试图实现重试计数,但您忘记了在发生错误时实际递减计数器。
Also if you display an error message here, it's kinda fatal, so make the code halt.此外,如果您在此处显示错误消息,那将是致命的,因此请暂停代码。
Again an improved version:再次改进版本:
disk_read:
pusha
mov si, 5 ; Retry count
.top:
mov ah, 0x02
int 0x13
jnc .OK
mov ah, 0x00
int 0x13
dec si
jnz .top ; More tries
jmp .fatal
.OK:
popa
ret
.msg db 'disk rw err', 0
.fatal:
mov bh, 0 ; Don't forget to mention the DisplayPage
mov ah, 0x0E
mov si, .msg
lodsb
.next:
int 0x10
lodsb
cmp al, 0
jne .next
cli
hlt
jmp $-2
printh.asm just have print functions. printh.asm 只有打印功能。
It is important to include as much information as possible!包含尽可能多的信息很重要! In my above improved code I assumed that printf does not destroy the DL
register.在我上面的改进代码中,我假设printf不会破坏DL
寄存器。 Please make sure it preserves at least DX
.请确保它至少保留DX
。
If you would have included the code in the printh.asm file, I would have verified this already for you...如果您将代码包含在printh.asm文件中,我已经为您验证了这一点……
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.