我正在跟随这些教程制作一个简单的内核,然后使用GRUB进行加载。编译指令没有起作用(ld找不到-T选项),最终得到的编译文件是Macho格式。在Mac上编译这些文件的正确步骤是什么?
编辑:
我在Ubuntu虚拟机上编译了代码,现在我有了kernel.bin文件。现在我该如何制作一个可启动的映像以运行内核?
为了使这个工作起来,你需要做几件事情。
首先,你需要确保nasm、gcc和ld创建的是macho i386二进制文件。这意味着要在nasm中传递-f macho
,在gcc中传递-m32
,在ld中传递-arch i386
,否则你将得到x86_64 macho二进制文件。
其次,GRUB不支持macho二进制文件——它只支持ELF二进制格式的开箱即用支持。但这并不是问题——你可以使用multiboot头告诉GRUB如何启动你的macho内核。
特别地,你需要在multiboot头中设置FLAGS的第16位:
FLAGS 1<<16 | whateverelse
这将告诉GRUB从您那里获取有关内核加载位置的信息,而不是尝试自动解决此问题。
现在您需要告诉GRUB这些信息。特别地,GRUB(或任何多引导兼容的引导加载程序)需要4个字段才能以任何二进制格式加载内核:
header_addr
:您的内核预期位于的物理内存位置。将其设置为.text部分的地址。(提示:在.text之后放置一个标签,然后在此处简单地引用它)load_addr
:GRUB应该从磁盘开始加载的地址。在macho的情况下,.text是第一个地址,因此我们还将其设置为.text的位置load_end_addr
:GRUB应停止加载的位置。通常,类似于stack+STACKSIZE
的东西会起作用。bss_end_addr
:BSS部分的结尾位置。在macho中,它就在最后,因此将其设置为load_end_addr
即可。entry_addr
:您的内核代码入口点。在OS X上,默认值为start
,但根据该指南,它是loader
。我的示例代码:
global start ; making entry point visible to linker
extern _kmain ; kmain is defined elsewhere
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
MACHO equ 1<<16
FLAGS equ MODULEALIGN | MEMINFO | MACHO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
section .text
align 4
MultiBootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM
dd MultiBootHeader
dd MultiBootHeader
dd stack+STACKSIZE
dd stack+STACKSIZE
dd start
; reserve initial kernel stack space
STACKSIZE equ 0x4000 ; that's 16k.
start:
mov esp, stack+STACKSIZE ; set up the stack
push eax ; pass Multiboot magic number
push ebx ; pass Multiboot info structure
call _kmain ; call kernel proper
cli
hang:
hlt ; halt machine should kernel return
jmp hang
section .bss
align 4
stack:
resb STACKSIZE ; reserve 16k stack on a doubleword boundary
kernel 200+x
命令告诉GRUB加载内核时,您将看到屏幕上弹出一个关于从哪里加载所有内容的“multiboot-kludge”消息。输入boot
将加载您的内核并完成设置!在Mac上直接操作是不可能的,因为Mac使用EFI作为它们的引导程序(有点像)。处理这种问题的最佳方法是下载Sun VirtualBox并创建一个Linux虚拟机 - 这样做还有另一个优点,即您可以拍摄快照,以便如果出现问题,您始终可以回滚(在编写I/O例程时易于损坏硬盘)。
我使用rEFIt制作引导程序,使Windows和Linux与Mac引导程序兼容(或不那么麻烦)。
如果您想要一个Mac虚拟机环境,我听说Q很好,我个人使用过VMWare的Fusion。