Linux x86 bootloader

I am trying to create a simple x86 linux bootloader in nasm.

Linux bzImage is stored on sda1, starting from the first sector.

I read the real mode code from bzImage (15 sectors) into memory, starting at 0x7E00. However, when I go into the code, it just freezes, nothing happens.

I created the code for the master boot record on sda. Iโ€™m probably better if I just join All this. I would like to know why it just hangs after the long jump instruction.

[BITS 16]

%define BOOTSEG 0x7C0 
%define BOOTADDR (BOOTSEG * 0x10)

%define HDRSEG (BOOTSEG + 0x20)
%define HDRADDR (HDRSEG * 0x10)

%define KERNSEG (HDRSEG + 0x20)

[ORG BOOTADDR]
entry_section:
    cli
    jmp     start
start:
    ; Clear segments
    xor     ax, ax
    mov     ds, ax  
    mov     es, ax
    mov     gs, ax
    mov     fs, ax
    mov     ss, ax
    mov     sp, BOOTADDR    ; Lots of room for it to grow down from here

    ; Read all 15 sectors of realmode code in the kernel
    mov     ah, 0x42
    mov     si, dap
    mov     dl, 0x80
    int     0x13
    jc  bad

    ; Test magic number of kernel header
    mov     eax, dword [HDRADDR + 0x202]
    cmp     eax, 'HdrS'
    jne     bad

    ; Test jump instruction is there
    mov     al, byte [KERNSEG * 16]
    cmp     al, 0xEB
    jne     bad

    xor     ax, ax      ; Kernel entry code will set ds = ax
    xor     bx, bx      ; Will also set ss = dx
    jmp     dword KERNSEG:0

; Simple function to report an error and halt
bad:
    mov     al, "B"
    call    putc
    jmp     halt

; Param: char in al 
putc:
    mov     ah, 0X0E    
    mov     bh, 0x0F
    xor     bl, bl  
    int     0x10
    ret

halt:
    hlt
    jmp     halt

; Begin data section
dap:                ; Disk address packet
    db  0x10            ; Size of dap in bytes
    db  0               ; Unused
    dw  15              ; Number of sectors to read
    dw  0               ; Offset where to place data
    dw  HDRSEG          ; Segment where to place data
    dd  0x3F            ; Low order of start addres in sectors
    dd  0               ; High order of start address in sectors

; End data section

times 446-($-$$) db 0   ; Padding to make the MBR 512 bytes

; Hardcoded partition entries
part_boot:
    dw 0x0180, 0x0001, 0xFE83, 0x3c3f, 0x003F, 0x0000, 0xF3BE, 0x000E
part_sda2:
    dw 0x0000, 0x3D01, 0xFE83, 0xFFFF, 0xF3FD, 0x000E, 0x5AF0, 0x01B3
part_sda3:
    dw 0xFE00, 0xFFFF, 0xFE83, 0xFFFF, 0x4EED, 0x01C2, 0xb113, 0x001D
part_sda4:
    dw 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000

dw 0xAA55   ; Magic number at relative address 510
mbrend:     ; Relative address 512
+5
source share
2 answers

Assuming your code is a loader (and therefore not an MBR):

  • IRQ, . BIOS , BIOS (, " " IRQ ). (, - ), .
  • / 0x0000: 0x7C00, 0x07C0: 0x0000. , (, , BOOTSEG HDRSEG - ).
  • " ", " ", (, , /).
  • - / " LBA" ( " LBA" , , ). " LBA" MBR, , , MBR DS: SI, .
  • , " BIOS 0x80". MBR DL , , , (, โ€‹โ€‹ - .
  • " LBA " ( DAP) . , , 64- 63 , . , LBA 0x3F ( ) . , LBA 0x40 ( ).
  • " " . , , .
  • 512 ( 446 ) . 512 ( , puts("Read error while trying to load boot loader"), putc('B')). ( , , " " ..) .

, , MBR ; MBR - (, ), (, -, , MBR-). MBR ( ) - - ( ). 12 , / Linux, (, GRUB, Plop, GAG, MasterBooter ..), .

, , , . , (, Bochs), , (, dump 0x00007E00, , , JMP , ..).

+1

!

xor bx, bx ; Will also set ss = dx

, ...

: ! "" .

, "" MBR, - , 7C00h, . " " . bzImage - , 7E00h...

, . ...

+1

All Articles