我正在按照these教程制作一个简单的内核,然后我将使用GRUB加载。编译说明不起作用(ld找不到-T选项),当我最终得到一个编译文件时,它是Macho格式。在Mac上编译这些文件时要采取的正确步骤是什么
修改
我在Ubuntu虚拟机上编译了代码,所以我有了kernel.bin文件。现在我该如何制作运行内核的可启动映像?
答案 0 :(得分:4)
为了实现这一目标,您需要做一些事情。
首先,您需要确保nasm,gcc和ld正在创建macho i386二进制文件。这意味着将-f macho
传递给nasm,将-m32
传递给gcc,将-arch i386
传递给ld,否则你将得到x86_64强壮的二进制文件。
其次,GRUB不支持男子气概二进制文件 - 它只提供对ELF二进制格式的开箱即用支持。但这不是问题 - 您可以通过使用多引导头来告诉GRUB如何做以启动您的男子气概内核。
特别是,您需要在多引导头中设置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部分的末尾所在的位置。在男子气概中,它就在那里,所以设置它等于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
完成此操作后,当您告诉GRUB使用kernel 200+x
命令加载内核时,您会在屏幕上看到一条“multiboot-kludge”消息,其中包含有关从何处加载内容的信息。输入boot
将加载您的男子气概内核,您将被设置!
答案 1 :(得分:3)
你无法直接在Mac上执行此操作,因为Mac使用EFI作为其引导程序(种类)。对于这类东西,最好的选择是下载Sun VirtualBox并制作一个Linux VM - 这有额外的优势,你可以拍摄快照,所以如果事情变成梨形,你总是可以回滚(当你的时候很容易破坏HD)开始编写I / O例程。
答案 2 :(得分:0)
我使用rEFIt使用Mac引导程序为Windows和Linux兼容(或不那么讨厌)制作引导加载程序。
如果你想要一个Mac VM环境,我听说Q很好,我亲自使用过VMWare的Fusion。