Search code examples
nasmldosdev

next sector of NASM bootloader is not loading when using LD


I am trying to create a bootloader that allows rust code to be bootable, but i am very new to OS dev, makefile, and assembly, and I'm still an amateur in Rust. I'm trying to use int 13h (ah 0h2) to read the next sector and execute that assembly code which will then, at some point, be executing rust code. however, the code in my "stage one" of my bootloader that is past the boot sector never seems to run. here is my code:

boot.asm

;[ORG 0x7c00]
[BITS 16]

global _start

_start:
    ; set segment registers
    ; (user3840170 said to set up the segment registers, but this didn't fix the problem)
    cli
    xor ax, ax    ; code segment
    mov ds, ax    ; data segment
    mov es, ax    ; extra segment
    mov ss, ax    ; stack segment
    mov bp, 7c00h ; base pointer
    mov sp, 7c00h ; stack pointer
    sti

    ; print message
    mov si, msg1
    call print

    ; read the next sectors, then jump
    mov al, 01h   ; sectors to read (1)
    mov bx, 7e00h ; buffer address (512 bytes away from current address 0x7c00)
    mov cx, 0002h ; cylinder and sector numbers (cylinder 0, sector 2)
    mov dl, 0     ; drive 0 (boot drive)
    mov dh, 0     ; head 0

    mov ah, 02h
    int 13h

    jmp 7e00h ; jumps to stage one

%include 'Bootloader/print.asm'
msg1: db "bootsector is loading stage 1", 0
    
times 510-($ - $$) db 0
dw 0xAA55

;;;;;;;;;;;
; STAGE ONE
;;;;;;;;;;;

mov si, msg2
call print
msg2: db 'Hello', 0
mov al, 'A'
mov ah, 0eh
int 10h

times 1024 - ($ - $$) db 0 

print.asm

;set of things for printing strings to TTY
print: 
    mov bx, 0
.loop:
    lodsb
    cmp al, 0
    je .done
    call print_char
    jmp .loop
.done:
    ret

print_char:
    mov ah, 0eh
    int 10h
    ret

print_line:
    mov al, 0ah
    call print_char
    mov al, 0dh
    call print_char
    ret

and lastly, the Makefile that I am using to build this to .iso and run it in VirtualBox: (I am running the genasm command, I haven't written the Rust kernel yet)

genfull: clean
    mkdir -p iso
    powershell.exe -Command "cd Kernel; cargo rustc -Z build-std=core -- --emit obj=kernelNP.o; cd .."
    objcopy ./Kernel/kernelNP.o Kernel.o --prefix-alloc-sections='.rust' && rm -rf ./Kernel/kernelNP.o
    nasm -f elf64 ./Bootloader/boot.asm -o bootsec.o
    ld Kernel.o bootsec.o --oformat binary -o main.img
    genisoimage -quiet -no-emul-boot -V 'BOOT' -input-charset iso8859-1 -o ./out/boot.iso -b main.img -hide main.img iso/
    rm -rf ./*.img ./*.bin ./iso/ ./*.o

genasm: clean
    mkdir -p iso
    nasm -f elf64 ./Bootloader/boot.asm -o bootsec.o
    ld bootsec.o --oformat binary -Ttext 0x7c00 -o iso/main.img
    genisoimage -quiet -no-emul-boot -V 'BOOT' -input-charset iso8859-1 -o ./out/boot.iso -b main.img -hide main.img iso/
    rm -rf ./*.img ./*.bin ./iso/ ./*.o

clean:
    rm -rf ./*.img ./*.bin ./iso/ ./*.o

please help me with why the second sector never runs!


Solution

  • I figured out the problem, it was the makefile. here is the new genasm:

    genasm: clean
        mkdir -p iso
        nasm -g -f elf32 -F dwarf -o boot.o ./Bootloader/boot.asm
        ld -melf_i386 -Ttext=0x7c00 -nostdlib --nmagic -o boot.elf boot.o
        objcopy -O binary boot.elf iso/main.img
        genisoimage -quiet -no-emul-boot -V 'BOOT' -input-charset iso8859-1 -o ./out/boot.iso -b main.img -hide main.img iso/
        rm -rf ./*.img ./*.bin ./iso/ ./*.o ./*.elf