Linux x86 bootloader
| 
                         
 我试图在nasm中构建一个简单的x86 
 Linux引导程序. 
  
  
Linux bzImage从第一个扇区开始存储在磁盘分区sda1上. 我从bzImage(15个扇区)读取实际模式代码到0x7E00开始的内存中. 我已经在sda上为主启动记录创建了代码.如果我只是附上,我可能是最好的 [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,0xFFFF,0xF3FD,0x000E,0x5AF0,0x01B3
part_sda3:
    dw 0xFE00,0x4EED,0x01C2,0xb113,0x001D
part_sda4:
    dw 0x0000,0x0000
dw 0xAA55   ; Magic number at relative address 510
mbrend:     ; Relative address 512
解决方法
 假设您的代码是引导加载程序(因此不是MBR): 
  
  
        >除非必须,否则永远不要禁用IRQ. BIOS需要它们才能正常工作,并且无论如何都会在某些BIOS功能中启用它们(例如,在磁盘功能中等待“扇区传输”IRQ).因为您的代码只是加载并将控制传递给更多实模式代码(例如,并且没有切换到保护模式或涉及任何内容),您没有理由在整个引导加载程序中的任何位置禁用IRQ. 请注意,计算机引导的方式经过精心设计,以便任何MBR都可以链接任何磁盘的任何分区上的任何操作系统;并且MBR可以是允许安装多个OS的更大的(例如,引导管理器)的一部分(例如,用户可以使用漂亮的菜单或某些东西来选择MBR的代码应该链加载哪个分区).此设计允许用户随时使用任何其他内容替换MBR(或引导管理器),而不会影响任何已安装的操作系统(或导致所有已安装的操作系统需要修复).举一个简单的例子,用户应该能够拥有12个不同的分区,这些分区都包含你的引导加载程序和一个独立/独立的Linux版本,然后安装任何引导管理器(例如GRUB,Plop,GAG,MasterBooter等)想要随时. 对于你的代码挂起的原因,考虑到所有代码都需要重写,这并不是很重要.如果你很好奇,我强烈建议在带有调试器(例如Bochs)的模拟器中运行它,以便你可以准确地检查发生了什么(例如,在0x00007E00转储内存以查看它包含的内容,将JMP单步执行看看正在执行什么,等等. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!  | 
                  
