Writing my own MBR code to choose between systems

152 views Asked by At

I am trying to implement my own MBR code in order to let users choose which system to load. After I write it, I substitute the first nearly 200 bytes of the disk with my own code. But I came across a problem that I cannot figure out, to load and execute the boot loader code of each system.

The code I wrote:

; Instruct NASM to generate code that is to be run on CPU that is running in 16 bit mode
bits 16

org 0x600

xor ax,ax
mov ss,ax
mov sp,0x7c00
sti
push ax
pop es
push ax
pop ds
cld
mov si,0x7c1b
mov di,0x61b
push ax
push di
mov cx,0x1e5
rep movsb
retf
mov bp,0x7be


; choose_background:
    mov ah, 0x06    ; Clear / scroll screen up function
    xor al, al      ; Number of lines by which to scroll up (00h = clear entire window)
    xor cx, cx      ; Row,column of window's upper left corner
    mov dx, 0x184f  ; Row,column of window's lower right corner
    mov bh, 0xf1    ; Background/foreground colour. In our case - red background / yellow foreground (https://en.wikipedia.org/wiki/BIOS_color_attributes)
    int 0x10        ; Issue BIOS video services interrupt with function 0x06

    ; Move label's bootloaderBanner memory address to si
    mov si, bootloaderBanner
    ; Put 0x0e to ah, which stands for "Write Character in TTY mode" when issuing a BIOS Video Services interrupt 0x10
    mov ah, 0x0e
    loop:
        ; Load byte at address si to al
        lodsb
        ; Check if al==0 / a NULL byte, meaning end of a C string
        test al, al
        ; If al==0, jump to end, where the bootloader will be halted
        jz exit_print_loop
        ; Issue a BIOS interrupt 0x10 for video services
        int 0x10                                                
        ; Repeat
        jmp loop
    exit_print_loop:
        ; Clear the keyboard buffer
    xor ah, ah
    ; Read a character from the keyboard
    mov ah, 0
    int 0x16

    ; Display the character on the screen
    mov ah, 0x0e
    int 0x10
    ; mov ah, 0
    ; int 0x16

    cmp al, '1'
    jne start_ubuntu

    mov ax,0x201
    mov bx,0x7c00
    mov cx,[bp+0x2]
    mov dx,[bp+0x0]
    int 0x13
    jnc 0x7c00 

    start_ubuntu:
        xor ax,ax
        mov ds,ax
        mov si,0x7c05

        mov byte [si],0x10
        mov byte [si+0x1],0x00
        mov byte [si+0x2],0x01
        mov byte [si+0x3],0x00
        mov byte [si+0x4],0x00
        mov byte [si+0x5],0x80
        mov byte [si+0x6],0x00
        mov byte [si+0x7],0x00
        mov byte [si+0x8],0x01
        mov byte [si+0x9],0x00
        mov byte [si+0xa],0x00
        mov byte [si+0xb],0x00
        mov byte [si+0xc],0x00
        mov byte [si+0xd],0x00
        mov byte [si+0xe],0x00
        mov byte [si+0xf],0x00

        mov ah,0x42
        mov dl,0x80

        int 0x13
        jnc 0x8000

    bootloaderBanner: db "                                  1 Windows",13,10,"                                  2 Ubuntu",13,10, 0

; Fill remaining space of the 512 bytes minus our instructions, with 00 bytes
; $ - address of the current instruction
; $$ - address of the start of the image .text section we're executing this code in
times 510 - ($-$$) db 0
; Bootloader magic number
dw 0xaa55


And i copied the valid binary code into the first nearly 200 bytes of the disk and did not change the rest part like partition table

Part of the partition table of my disk is:

B SCHS ID ECHS RSLBA SecCnt
80 20 21 00 07 df 13 0c 00 08 00 00 00 20 03 00
00 df 14 0c 07 fe ff ff 00 28 03 00 00 98 d1 01
00 fe ff ff 05 fe ff ff fe c7 d4 01 02 30 4b 01
00 00....

By the way, my computer system is MSWindows 11 and the virtual disk is created by qemu. And the systems I installed are MSWindows 7 and Ubuntu 22.04

Now I wonder where the stage 2 of ubuntu is located. I searched online and from this i know i need to find the (4-byte) Quad-Word, but i never know where it is. I have also searched the string "Loading stage2" in the whole disk but no results.

The result of fdisk -l in the ubuntu system installed on the disk:

equipment start beginning end sector size id type
/dev/sda1 2048 206847 204800 100M 7 HPFS/NTFS/exFAT
/dev/sda2 206848 30719999 30513152 14.5G 7 HPFS/NTFS/exFAT
/dev/sda3 30722046 52426751 21704706 10.3G 5 extend
/dev/sda5 * 30722048 31111167 389120 190M ef EFI(FAT -12/16/32)
/dev/sda6 31113216 52426751 21313536 10.2G 83 Linux
0

There are 0 answers