title: Linux x86 bootloader
body: <p>I am trying to build a simple x86 Linux bootloader in nasm.</p>
  
  <p>The Linux bzImage is stored on disk partition sda1 starting from the first sector.</p>
  
  <p>I read the real mode code from the bzImage (15 sectors) into memory starting from 0x7E00.
  However when i jump into the code it just hangs, nothing happens.</p>
  
  <p>I have created code for the master boot record on sda. I's probably best if i just attach
  the whole thing. I would like to know why it just hangs after the far jump instruction.</p>
  
  <pre><code>[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
  </code></pre>