3

これらのチュートリアルに従って単純なカーネルを作成し、それを GRUB を使用してロードしました。コンパイルの指示が機能せず (ld は -T オプションを見つけることができませんでした)、最終的にコンパイルされたファイルを取得したとき、それは Macho 形式でした。これらのファイルを Mac でコンパイルする際の正しい手順は何ですか。
編集:
Ubuntu仮想マシンでコードをコンパイルしたので、kernel.binファイルがあります。では、カーネルを実行する起動可能なイメージを作成するにはどうすればよいでしょうか?

4

3 に答える 3

4

これを機能させるには、いくつかのことを行う必要があります。

まず、nasm、gcc、およびldがマッチョなi386バイナリを作成していることを確認する必要があります。これは-f macho、nasm、-m32gcc、および-arch i386ldに渡すことを意味します。そうしないと、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とマッチョカーネルが読み込まれ、設定が完了します。

于 2011-07-18T11:15:44.370 に答える
3

Mac は EFI をブートローダーとして (一種の) 使用するため、Mac 上でこれを直接行うことはできません。この種のものに対する最善の策は、Sun VirtualBox をダウンロードして Linux VM を作成することです。これには、スナップショットを作成できるという追加の利点があります。 I/O ルーチンを書き始めます)。

于 2010-07-30T18:14:28.320 に答える
0

私は rEFIt を使用して、Windows および Linux のブートローダーを Mac ブートローダーと互換性があるようにしました (またはそれほど厄介ではありません)。

MacのVM環境が欲しいならQがいいと聞き、個人的にはVMWareのFusionを使ったことがあります。

于 2010-08-05T23:08:26.877 に答える