Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6677161
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T04:04:58+00:00 2026-05-26T04:04:58+00:00

Recently I’m trying to get a hang on how bootloaders work. I’m writing my

  • 0

Recently I’m trying to get a hang on how bootloaders work.
I’m writing my loader in nasm assembler and test it with bochs and a floppy image.

The compiled binaries for stage 1 and 2 get joined via copy into one image.
This image is exactly as I want it. 512Bytes stage1 code (magicnumber included and it loads just fine) and 512 stage2 code in the 2nd sector.

But I think my problem is loading the sector into the ram and jumping into it. Is there something wrong with my code?

Stage1.asm

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

    mov si,s_version
    call print_string

    ; ## Load stage2
    mov si,s_loading
    call print_string

    xor ax,ax
    xor bx,bx
    xor cx,cx
    xor dx,dx

    ;read 2nd sector
    mov ah,02h
    mov al,1    ;read 1
    mov ch,0    ;on track 0
    mov cl,2    ;2nd sector
    mov dh,0    ;head 1
    mov dl,0    ;from floppy a    

    mov bx,09C0h;destination segment
    mov es,bx

    mov bx,0    ;destination offset

    int 13h ;<-- Fails right here

    mov si,s_sector
    call print_string

    ;print number of read sectors
    add ax, 48
    mov ah, 0Eh
    int 10h
    mov al, 21
    mov ah, 0Eh
    int 10h

    ;print the sector's magicnumber (debugging purposes)
    mov al, [09C0h+511]
    int 10h

    xor ax,ax
    int 16h

    mov si,s_jumping
    call print_string

    call word 09C0h:0000h

; #### print a string from si
print_string:
    push ax
    push bx
    mov ah, 0Eh
    .repeat:
        lodsb
        cmp al, 0
        je .exit
        int 10h
    jmp .repeat
    .exit:
    pop bx
    pop ax
ret
; ****

; #### define strings    
s_version    db 'VeOS 0.0.0.1',10,13,0
s_loading    db 'Loading Stage2...',10,13,0
s_sector    db 'Loading sector...',10,13,0
s_jumping    db 'Passing control to Stage2.',10,13,0
; ****

;fillup with zeros
times 510-($-$$) db 0
;boot signature
dw 0xAA55

stage2.asm

BITS 16
start:
    mov ax, 09C0h   ; 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, 09C0h   ;Set data segment to where we're loaded
    mov ds, ax

    mov ah, 0Eh
    mov al, 21      ;"!"
    int 10h

    mov ah, 00h
    int 16h

    jmp $


times 511-($-$$) db 0
;Magicnumber for debugging
db 0x41

I googled thoroughly and found nothing describing exactly how to load a sector into the ram and jump into it. Not even the Magicnumber of the 2nd sector is found by my programm.

Would be great if it is just some miscalculation on the addresses.

Update:
Current sourcecode, the line where it has a lockup is marked. I set all 4 main registers to 0 out of pure paranoia.

Update2:
Again the current version. No stuff done between setting up the registers and issuing int 13h.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T04:04:59+00:00Added an answer on May 26, 2026 at 4:04 am

    Update: In addition to the below, you’re also overwriting your stack when you load!

    Your stack is located at 07C0h + 288 : 4096 which is 08E0h:1000h = 09E0h:0000h, and you’re reading to 09C0h:0000, and 512 bytes forward (ending at 09E0h:0000h) overwriting the stack. Either move your stack or read to some other place. See the memory map from osdev.org for inspiration.

    I’m afraid I don’t know a good step-by-step debugger. I just placed a jmp $-2 instruction in the code and used QEMUs built-in debugger to do “info registers” at appropriate points. I think Bochs might have something similar.

    Three (2.5) things I see (though there might be more):

    ;read 2nd sector
        mov ah,02h
        mov al,1    ;read 1
        mov ch,0    ;on track 0
        mov cl,1    ;2nd sector
        mov dl,0    ;from floppy a
        mov bx,09C0h ;destination
        mov es,bx
        int 13h
    
    • You’re leaving bx as 09c0h, so it will read to 09C0h:09C0h rather than 09C0h:0000h.
    • You say you’re reading from the second sector (cl = 1), but you’re reading from the first!. See Ralph Brown.
    • You’re not setting dh (head). It’s probably fine in Bochs, but I can’t recall off the top of my head what initial conditions are guaranteed apart from dl being set to the drive number.

    Here’s the boot loader I’ve used for a small test kernel (parts taken from various parts of osdev.org and might have errors I’ve introduced, so be careful), if you wish to compare/copy. (I leave dl intact because it contains the boot drive so you don’t have to hard code it).

            bits 16
            org 0x7c00
    
    Start: jmp EntryPoint
    
    PrintString16:
            pusha
    .PrintLoop:
            lodsb
            or al, al
            jz .PrintDone
            mov ah, 0xe
            int 0x10
            jmp .PrintLoop
    .PrintDone:
            popa
            ret
    
    EntryPoint:
            xor ax, ax
            mov ss, ax
            mov ds, ax
            mov sp, 0x7c00
    .DiskReset:
            mov ah, 0
            int 0x13
            jc .DiskReset
            mov ax, 0x50 ; load to 0x500 linear address. It has unused space up to 0x7bff
            mov es, ax
            xor bx, bx
            mov ax, 0x023B ; count = 0x3b = 59, the maximum (while still leaving soom room for the stack and the boot sector code we're currently running)
            mov cx, 0x0002
            xor dh, dh ; leave dl intact
            int 0x13
            jnc .ReadDone
            mov si, ReadError
            call PrintString16
            jmp .DiskReset
    .ReadDone:
            ;jmp 0x50:0x0  ;jump to stage 2 loaded at 0x500
    
            cli
            xor ax, ax
            mov ds, ax
            mov es, ax
            mov ax, 0x9000
            mov ss, ax
            mov sp, 0xffff 
            sti
    
            mov si, HelloMsg
            call PrintString16
    
            ; Disable interrupts until safely in protected mode
            cli
    
            ; Install GDT
            lgdt [toc]
    
            ; Enable A20
            mov al, 0xdd
            out 0x64, al
    
            mov si, GoPMode
            call PrintString16
    
            ; enable protected mode
            mov eax, cr0 
            or eax, 1
            mov cr0, eax
    
            jmp 0x8:PmodeStart      
            bits 32
    PmodeStart:
            ; setup stack and datasegments
            mov ax, 0x10
            mov ds, ax
            mov es, ax
            mov fs, ax
            mov gs, ax
            mov ss, ax
    
            ; Setup stack at 0x90000
            mov esp, 0x90000
    
            ; Jump to C-code
            jmp 0x8:0x500
    
            ; Reboot if C-code returns
    Reboot:
            mov word [0x472], 0x1234
            jmp 0x8:0xffff0
    
    
    ReadError db 'Read error - retrying...', 13, 10, 0
    HelloMsg db 'Loading...',0
    GoPMode db 'Entering protected mode..',0
    gdt_data: 
            dd 0                            ; null descriptor
            dd 0 
    
    ; gdt code:                             ; code descriptor
            dw 0FFFFh                       ; limit low
            dw 0                            ; base low
            db 0                            ; base middle
            db 10011010b                    ; access
            db 11001111b                    ; granularity
            db 0                            ; base high
    
    ; gdt data:                             ; data descriptor
            dw 0FFFFh                       ; limit low (Same as code)10:56 AM 7/8/2007
            dw 0                            ; base low
            db 0                            ; base middle
            db 10010010b                    ; access
            db 11001111b                    ; granularity
            db 0                            ; base high
    
    end_of_gdt:
    toc: 
            dw end_of_gdt - gdt_data - 1    ; limit (Size of GDT)
            dd gdt_data                     ; base of GDT
    
    
    times 510 - ($-$$) db 0 ; pad to 512 bytees, will also warn if we exceed 512 bytes
    
            dw 0xAA55 ; boot signature
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Recently I'm doing some work on RTMP streaming, that is using Flowplayer to integrate
Recently I've noticed that on occasion I do not get a mayorship notification when
Recently, I'm trying to solve all the exercises in CLRS. but there are some
Recently I have been trying to improve my unit tests and one of the
Recently I'm dealing with the access log of nginx analyzing work with python. I've
Recently I was trying to determine the time needed to calculate a waveform using
Recently Mercurial has added certificate validation when connecting to HTTPS servers. I'm trying to
Recently I asked this question: Find Common Values in several arrays, or lists VB.NET
Recently i saw an open source javascript library have a line like : style
Recently I had a problem. How to disable scrolling in a particular area of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.