将内核编译为mac上的二进制文件

时间:2010-07-22 20:08:34

标签: macos binary linker kernel grub

我正在按照these教程制作一个简单的内核,然后我将使用GRUB加载。编译说明不起作用(ld找不到-T选项),当我最终得到一个编译文件时,它是Macho格式。在Mac上编译这些文件时要采取的正确步骤是什么 修改
我在Ubuntu虚拟机上编译了代码,所以我有了kernel.bin文件。现在我该如何制作运行内核的可启动映像?

3 个答案:

答案 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。