简体   繁体   English

bochs hlp 中的 FASM 引导程序

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM