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单步执行看看正在执行什么,等等. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |