これらのチュートリアルに従って単純なカーネルを作成し、それを GRUB を使用してロードしました。コンパイルの指示が機能せず (ld は -T オプションを見つけることができませんでした)、最終的にコンパイルされたファイルを取得したとき、それは Macho 形式でした。これらのファイルを Mac でコンパイルする際の正しい手順は何ですか。
編集:
Ubuntu仮想マシンでコードをコンパイルしたので、kernel.binファイルがあります。では、カーネルを実行する起動可能なイメージを作成するにはどうすればよいでしょうか?
3 に答える
これを機能させるには、いくつかのことを行う必要があります。
まず、nasm、gcc、およびldがマッチョな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
とマッチョカーネルが読み込まれ、設定が完了します。
Mac は EFI をブートローダーとして (一種の) 使用するため、Mac 上でこれを直接行うことはできません。この種のものに対する最善の策は、Sun VirtualBox をダウンロードして Linux VM を作成することです。これには、スナップショットを作成できるという追加の利点があります。 I/O ルーチンを書き始めます)。
私は rEFIt を使用して、Windows および Linux のブートローダーを Mac ブートローダーと互換性があるようにしました (またはそれほど厄介ではありません)。
MacのVM環境が欲しいならQがいいと聞き、個人的にはVMWareのFusionを使ったことがあります。