1

I'm learning about operating systems from the book, Operating Systems from 0 to 1. I'm trying to use the code in chapter 7 where they build a small bootloader and another small program called sample, where they get the bootloader to jump to the code in sample. In the text they want me to use gdb to put a breakpoint at 0x500 to check if the next assembly code is from sample.asm However when i put a breakpoint in gdb at 0x500, GDB outputs after running the program upto the breakpoint

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000000000000 in ?? ()

Also layout asm says, "no assembly available"

I also checked the cf flag after int 0x13 which is 0 which claims there is no error in reading the sector.

My problem is did I jump to the wrong address or is there a different issue with my code?

bootloader.asm ;

;*************************************************
; bootloader.asm 
; A Simple Bootloader
;*************************************************
org 0x7c00
bits 16
start: jmp  boot

;; constants and variable definitions
msg db "Welcome to My Operating System!", 0ah, 0dh, 0h

boot:

    cli ; no interrupts 
    cld ; all that we need to init
    
    mov ax, 0x50

    ;; set buffer
    mov es, ax  
    xor bx, bx  

    mov al, 1   ; read one sector
    mov ch, 0   ; track 0
    mov cl, 2   ; sector to read
    mov dh, 0   ; head number
    mov dl, 0   ; drive number
        
    mov ah, 0x02    ; read sectors from disk    
    int 0x13      ; call the BIOS routine
    jmp 0x50:0x0    ; jump and execute the sector!
    
    hlt ; halt the system 

; We have to be 512 bytes. Clear the rest of the bytes with 0

times 510 - ($-$$) db 0
dw 0xAA55 ; Boot Signature
    

sample.asm

; ******************************************
; sample.asm
; A Sample Program
; ******************************************
mov eax, 1
add eax, 1

I wrote the bootloader then sample to an img file on linux,

nasm -f bin bootloader.asm -o bootloader
dd if=/dev/zero of=disk.img bs=512 count=2880
dd if=bootloader of=disk.img conv=notrunc
dd if=sample of=disk.img bs=512 seek=1 conv=notrunc

then used QEMU

qemu-system-x86_64 -machine q35 -fda disk.img -gdb tcp::26000 -S

then connected to it using gdb;

set architecture i386:x86-64
target remote localhost:26000
b *0x500
c
USER149372
  • 103
  • 2
  • 7
  • In `sample.asm` after `add eax, 1` add `jmp $` to put your code in an infinite loop since you don't want it to continue running semi random data in memory as instructions. I suspect the processor was executing what was in memory and then eventually failed at memory address 0x0 – Michael Petch Aug 11 '20 at 23:27
  • also in gdb before at the jmp instruction in bootloader.asm, gdb says (bad) instead, so is there a problem with the far jmp? – USER149372 Aug 11 '20 at 23:34
  • still recieved the same error after adding jmp $ in sample.asm – USER149372 Aug 11 '20 at 23:42
  • 2
    Besides the fact you didn't set the stack to somewhere safe before reading a sector into memory, if you add the `JMP $` at the end of `sample.asm` then the problem is likely the debugger - GDB doesn't know how to handle segment:offset addressing when the value of CS (Code Segment) is not 0x0000. You set it to 0x50. Although your code is correct the debugger doesn't understand it. One thing I suggest is try setting ES to 0 (instead of 0x50), set BX to 0x500 for the disk read and then use `jmp 0x0000:0x0500`. That will at least not confuse GDB. At the top of `sample.asm` use `org 0x500` – Michael Petch Aug 11 '20 at 23:47
  • Regarding GDB and debugging real mode code I made an answer recently that has a bit of info https://stackoverflow.com/questions/62513643/qemu-gdb-does-not-show-instructions-of-firmware/62522147#62522147 – Michael Petch Aug 11 '20 at 23:51
  • This fixed it, its working now. – USER149372 Aug 11 '20 at 23:56

0 Answers0