When I modify code the disk image becomes unbootable

为君一笑 提交于 2020-01-07 09:14:32

问题


I'm developing an operating system in assembly language. When making changses o the code the output file isn't seen as bootable.

This is my code:

BITS 16

start:
    mov ax, 07C0h       ; Set up 4K stack space after this bootloader
    add ax, 288     ; (4096 + 512) / 16 bytes per paragraph
    mov ss, ax
    mov sp, 4096
    mov ax, 07C0h       ; Set data segment to where we're loaded
    mov ds, ax
    call cls
    MOV AH, 06h    ; Scroll up function
    XOR AL, AL     ; Clear entire screen
    XOR CX, CX     ; Upper left corner CH=row, CL=column
    MOV DX, 184FH  ; lower right corner DH=row, DL=column 
    MOV BH, 1Eh    ; YellowOnBlue
    INT 10H
    mov si, text_string ; Put string position into SI
    call print_string   ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h
       cmp al, '1'
       je reboot
       cmp al, '2'
       je shutdown
       cmp al, '3'
       je about
       cmp al, '4'
       je message
           cmp al, '5'
       je shutdown

       jmp $            ; Jump here - infinite loop!


    text_string db '|Main Menu| |Smile OS V1.2|',13,10,'1) Reboot',13,10,'2) Shutdown',13,10,'3) About',13,10,'4) Message',13,10,'5) System Halt',0
    about_string db '|About|',13,10,'Smile OS is a console based operating system in assembly.',13,10,'Press any key to go back!',0
    message_str db '|Message|',10,13,'Hello, World!',13,10,'Press any key to go back!',0

reboot:
mov ax, 0
int 19h

shutdown:
mov ax, 0x1000
mov ax, ss
mov sp, 0xf000
mov ax, 0x5307
mov bx, 0x0001
mov cx, 0x0003
int 0x15

message:
call cls
mov si, message_str ; Put string position into SI
call print_string   ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h     
je start

cls:
  pusha
  mov ah, 0x00
  mov al, 0x03  ; text mode 80x25 16 colours
  int 0x10
  popa
  ret

about:
call cls
mov si, about_string    ; Put string position into SI
call print_string   ; Call our string-printing routine
push bx ;push registers
push cx
push dx
mov ah,0h
int 16h 
je start

print_string:           ; Routine: output string in SI to screen
    mov ah, 0Eh     ; int 10h 'print char' function

.repeat:
    lodsb           ; Get character from string
    cmp al, 0
    je .done        ; If char is zero, end of string
    int 10h         ; Otherwise, print it
    jmp .repeat

.done:
    ret     

    times 512-($-$$) db 0   ; Pad remainder of boot sector with 0s
    dw 0xAA55       ; The standard PC boot signature

When I tries to revert the change the code broke.

  • I'm using Oracle VM VirtualBox and latest version of NASM.
  • I tried to restart the computer for several times and no change.
  • I tried to install a old version of NASM and nothing.

What do I have to do to fix this bootloader?


回答1:


You need to change:

times 512-($-$$) db 0

to:

times 510-($-$$) db 0

You need to pad 510 bytes so the boot signature 0xaa55 are the last 2 bytes of the 512 byte boot sector. If you don't do this the image will not be seen as a valid boot sector. Your previous question mentions using the command:

nasm -f bin os.asm -o os.iso

You aren't generating an ISO (CD-ROM image) with this command. To boot in VirtualBox I recommend creating a 1.44MB floppy disk image with your boot sector this way:

Assemble the file to os.bin.

nasm -f bin os.asm -o os.bin

After this step check that the file os.bin is exactly 512 bytes1. If it isn't you have placed too much code and data in your boot sector, the boot signature will be in the wrong place and VirtualBox will refuse to identify it as a bootable device.

Create a blank 1.44MB floppy disk image called os.img:

dd if=/dev/zero of=os.img bs=1024 count=1440

Copy the os.bin to the beginning of os.imgwithout truncating the disk image:

dd if=os.bin of=os.img conv=notrunc

In VirtualBox set it up to boot from FLOPPY (not CD-ROM) and select the os.img file as the boot image. VirtualBox needs a properly sized floppy disk image.

The code you show in this question when run appears like this in my VirtualBox:


Alternative to TIMES that will Catch Overlapping Sections

If you replace:

times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
dw 0xAA55               ; The standard PC boot signature

With:

section bootsig start=510
    dw 0xAA55           ; The standard PC boot signature

Then you will be informed with an error that your bootloader is too big:

nasm: fatal: sections .text and bootsig overlap!

This means code in the section before bootsig overlaps with the boot signature section. If this happens then you will know that it is time to read disk sectors yourself to extend your code beyond the 512 byte boot sector.

If using ORG 0x7c00 then start=510 would have to be start=0x7c00+510.

If you rely on TIMES to tell you there is a problem it will look something like:

os.asm:###: error: TIMES value -### is negative


1 If the file os.bin is more than 512 bytes then you will need to use the BIOS to read more disk sectors into memory manually. The disk reads from a floppy can be done with INT 13h/AH=2h.



来源:https://stackoverflow.com/questions/53796349/when-i-modify-code-the-disk-image-becomes-unbootable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!