トップ «前の日記(2011-06-16) 最新 次の日記(2011-06-18)» 編集



2011-06-17 :-(

_ 午前

0500 起床

0830 出勤

0900 テスト

_ 午後

1300 テスト

1700 退勤


1800 突発鶏の会

_ ,

椿姫[ 20051209#p13 ]は文学になっちゃってるのであれば {キャバ嬢,娼婦,飲み屋の店員} に惚れてしまうのはなんら可笑しいことではない

_ [NetBSD][マルチブート][翻訳]making netbsd multiboot-compatible - o'reilly media NetBSD のマルチブート環境を作る

by julio m. merino vidal


the i386 architecture is full of cruft required to maintain compatibility with old machines that go back as far as the 8086 series. technically speaking, these features aren't necessary anymore because any recent computer based on this architecture uses a full 32-bit operating system that could work perfectly fine without the legacy code. unfortunately, the compatibility hacks remain in place and hurt the development of new software.

i386 アーキテクチャは、8086 シリーズに遡るまでの古いマシンを維持するために cruft required している。技術的な話題としては、このアーキテクチャを基にした最近のあらゆるコンピュータは完全な 32 ビットオペレーティングシステムがレガシーコードが無くても完璧に動作するので、これらの機能はもはや必要とされていない。残念ながらここ( i386 アーキテクチャ )ではこの互換性ハックは生き残り、新しいソフトウェアの開発を悩ませる。

one of the details that has not changed for years is the i386 boot process. it was designed back in the days when computers had only floppy disk drives and machines had limited firmware. since then, the procedure has not suffered any change and it makes some tasks very complex; one of these is the configuration of multiple operating systems (oses) on a single machine.

ここ数年変化がないことのうち 1 つは、i368 ブートプロセスだ。これはコンピュータがフロッピーディスクドライブしか持っておらず、マシンが限られたファームウェアを使っていたころに設計されたものだ。その後、この手続きは苦労して変更されることなく、いくつかの処理はかなり複雑になった。そのうち 1 つは、1 台のマシンに複数のオペレーティングシステムを設定することだ。

the new firmware for intel-based machines, the extensible firmware interface (efi), resolves this issue by providing a more versatile boot process. other architectures have already provided improved firmware with nicer boot mechanisms, including, for example, the ability to load and execute an elf image straight from the machine initialization code. such is the case with openfirmware as shipped in powerpc macintoshes.

インテルベースのマシンの新しいファームウェア the extensible firmware interface (efi) は、多様なブートプロセスによってこの課題を解決した。他のアーキテクチャは、改善されたよりよいブート機構を持ったファームウェアが提供されている。たとえば、ロードする能力があったり、マシンの初期化コードから直接 elf イメージを実行できたりする。powerpc マッキントッシュの openfirmware のようなものだ。

even though alternative firmware implementations exist, the i386 architecture as we known it today will still be with us for a long time. therefore, it would be nice to resolve some of its limitations through software. this is what the multiboot specification attempts to do in the boot area: provide the ability to boot any operating system from a single boot loader, hence simulating an improved firmware.

他のファームウェアでは既に実装されているのに、i386 アーキテクチャでは今日に至るまでいまだに見たことがない。しかし、ソフトウェアの制限を通り抜けるようにした良い解決策がいくつかある。ブート領域でマルチブートするのである。これは、改良ファームウェアでシミュレーションすることにより、単独のブートローダーからあらゆるオペレーティングシステムをブートできるようになる。

i recently modified the netbsd's kernel to become multiboot-compliant. there are many code references in the text, but the main idea behind the essay is to introduce multiboot and show you that a real-world operating system can easily be converted to support this specification. please note that all code references point to the netbsd-4 stable branch to ensure that the code remains consistent with the explanations given here.

NetBSD のカーネルをマルチブートできるようにしてみた。大量のコードリファレンスがこのテキストに存在する。しかし主なアイデアはマルチブートを紹介する文章( 後述 )にあり、実際のオペレーティングシステムを簡単にマルチブート対応に変換することができるようになる。なお、全てのコードリファレンスは netbsd-4 stable ブランチを指しており、ここで説明したことがコードとして首尾一貫して残ることを保証する。

the i386 boot process (i386 ブートプロセス)

the traditional i386 architecture uses a very simple firmware known as the basic input/output system, or bios. the bios is in charge of initializing the hardware after powering up the machine and provides a low-level interface to access it from boot loaders and oses. unfortunately, it has inherited a lot of deficiencies from the past: these services are available from real mode only and they do not provide high-level abstractions for the underlying hardware.

伝統的な i386 アーキテクチャは、the basic input/output system または BIOS と呼ばれるじつに簡単なファームウェアを利用している。BIOS は、マシンの電源を入れたあとにハードウェアを初期化し、ブートローダーや OS がアクセスするための低レベルインターフェースを提供する。やっかいなことに、以下に示すような多くことを継承している。これらのサービスはリアルモードのみで有効であり、ハードウェアを高レベルに抽象化してはいない。

to put things in perspective, the bios is unable to access any on-disk filesystem (not even fat) and therefore cannot directly load any executable such as the os kernel. instead, all the bios does is load the first sector of the selected boot disk into a specific memory location (07c0h:0000h) and transfer the execution control to it. to make things worse, each os kernel has traditionally provided its own boot code tailored to its needs. for example, the old ms-dos os loaded from a fat disk and executed in real mode; on the other hand, newer systems can boot from a large variety of filesystems (fat, ntfs, ext2, and more) and need to run in protected mode from the very beginning because their kernels are too big to fit into the first megabyte of memory (all the memory addressable from real mode).

ここでの見方として、BIOS はディスク上のあらゆるファイルシステムにアクセスできないし( FAT は言うまでもない )、OS カーネルのようにあらゆる実行可能なものは直接接ロードすることができない。その代わり、全ての BIOS は、選択したブートディスクの最初のセクターをメモリ番地 07C0h:0000h にロードし、実行制御 { ってなに }をそこへ転送する。それが失敗した場合、各 OS カーネルは伝統的に自分自身のブートコードを必要なように仕立て上げることを提供する。例えば、古い MS-DOS OS は FAT ディスクかららロードされ、リアルモードで実行される。他に、より新しいシステムでは、様々な大きいファイルシステム( FAT, NTFS, EXT2 など )からブートする。それらのカーネルはメモリの最初のメガバイト( 全てのメモリアドレスはリアルモードに基づく )に格納するにはとても大きいので、しょっぱなからプロテクトモードで動作する必要があるだ。

the fact that each os needs its own boot loader causes a lot of problems when setting up several different systems on a single machine and poses a lot of questions that the user will most likely be unable to answer. what do you install in the mbr? where do you put each boot loader? why do you need to configure each of them independently? why do you need more than one?

OS 自身のブートローダーを使うと 1 つのマシン上でいくつかの異なるシステムを設定するときにたくさんの問題を引き起こすことになり、たくさんの問い合せが出るのだが、ユーザーはたいてい答えられない。MBR は何をインストールしてますか? ブートローダーはどこに設置していますか? それらを独立して設定する必要があるのは何故ですか? 1 つ以上必要なのは何故ですか?

it could be very convenient if there was a generic interface that decoupled the load and bootstrapping of an os kernel from its boot loader. this way, an os developer could focus exclusively on the task at hand and forget about writing a boot loader. similarly, boot loader developers could join forces to write a more complete utility or, alternatively, write their own with minimal code, while being able to boot any os that supported such interfaces (ideally all oses). the good thing is that the grub developers already had this idea in the past and developed such an interface: multiboot.

もしブートローダーによる OS カーネルのブートストラップとロードとを分離する共通インターフェースあるならば、これはとても簡単に出来る。この方法ならば、OS 開発者は手持ちの作業のみに集中できるし、ブートローダーを意識せずに済む。同様に、ブートローダー開発者はもっと完全なユーティリティを書くことに注力するか、インターフェースに対応したあらゆる OS ( 理想的には全ての OS ) がブートできるようになるまでの間はそれら自身の最小限のコードとともに書いたりできる。良いものとして、GRUB 開発者たちは後述するアイデアを既に使っており、マルチブートのインターフェースとして開発されている。

the multiboot specification ( マルチブート詳細 )

the multiboot specification (ms) defines a protocol between boot loaders and os kernels that allows any multiboot-compliant boot loader to load and execute any multiboot-compliant os kernel. this permits the end user to install a single boot loader in his machine and use it to boot any system directly, without having to chain-load different boot utilities.

the multiboot specification (MS) は ブートローダーと OS カーネルとのプロトコルを定義している。これにより、あらゆるマルチブート対応のブートローダーでロードし、あらゆるマルチブート対応の OS カーネルを実行することを許す。この権限は、異なるブートユーティリティを連鎖することなく、エンドユーザーが自分のマシンにブートローダー単体をインストールし、あらゆるシステムをじかにブートできるようにする。

in order to accomplish this abstraction, the ms defines two items:

これを果たすため、MS は 2 つの項目を定義している:

  • the multiboot header (mh) (マルチブートヘッダー (HM))

this is a 4-byte aligned data structure located within the first 8 kb of the os kernel image. it provides a magic number used to identify the file as being multiboot-compliant, a set of flags indicating specific kernel needs, and additional fields describing the structure of the binary. the latter are only used if the kernel is in the a.out format (with some exceptions); using elf makes things much simpler and also more versatile.

これは、OS カーネルイメージの最初の 8 KB に 4 バイトアライメントのデータ構造体を配置する。これは、マルチブート対応するためのファイルを見つけるマジックナンバーを提供する。

  • the multiboot information structure (mis) (マルチブート情報構造体 (MIS))

this is a data structure constructed by the boot loader and passed to the os kernel as part of the boot process. it includes information such as which disk is the boot disk, a memory map, the kernel parameters, where additional kernel modules are in memory (if loaded at boot time), etc.

これはブートローダーによって生成される構造体で、OS カーネルのブートプロセスの部分として通過する。これには、どれがブートディスクなのか、メモリーマップ、カーネルパラメーター、追加カーネルモジュールのメモリ内での場所( ブート時にロードするならば )等の情報を含む。

there is some interaction between the two structures in the sense that the mh may request the boot loader to set some fields in the mis for a successful boot. if the boot loader cannot fulfill the kernel's needs, the load will fail gracefully.

ブート成功時にブートローダーが MIS 内のいくつかのフィールドを設定するように MH が 要求する、というように、2 つの構造体の間には多少の作用がある。もしブートローダーがカーネルの要求を満たせないならば、ロードは綺麗に失敗するだろう。

if you're making good use of these two structures, it's trivial to write a simple binary file that acts as an os kernel - that is, a binary that is able to run standalone on the machine without any other os. see the boot.s, kernel.c, and related files that form the example kernel distributed alongside grub in the docs directory.

もしあなたがこれら 2 つの構造体を良く使えるならば、それは、OS カーネルのような単純なバイナリファイル( それはマシン上で何の OS も無しに独立して走ることが出来るバイナリだ )を書くことは取るに足らないだ。boot.s, kernel.c や、たとえば docs ディレクトリ内の GRUB と一緒に配布されたカーネルなど、関連するファイルを読むとよい。

it is also interesting to note that a multiboot-compliant boot loader will enter protected mode and set up a preliminary gdt for a flat memory model, so the kernel needn't do this by itself. of course, the kernel will have to reload the gdt with values of its own later in the initialization process, but the one set up by the boot loader is enough to get started. in some sense, it's possible to write the os kernel as if the real mode did not exist at all, as happens on other (saner) platforms.

マルチブート対応のブートローダーがプロテクトモードに入り、フラットメモリモデルのための予備 GDT を設定することについて記すことはとても興味深いことだ。だからカーネルは、カーネル自身がおこなう必要がない。もちろん、カーネルは、初期化後にカーネル自身の値と一緒に GDT をリロードできなくてはならないだろう。しかしブートローダーによるセットアップについては、すでに始めることができる。ある意味、それは、まるでリアルモードが全てに存在しないような OS カーネルを書くことを可能にすることであり、他の( たしかな )プラットフォームが発生するようなものだ。


_ [NetBSD][マルチブート][翻訳]making netbsd multiboot-compatible - o'reilly media NetBSD のマルチブート環境を作る(2)

the netbsd/i386 boot process (NetBSD/i386 のブートプロセス )

netbsd/i386 uses a two-stage boot loader. the first stage gets installed into a known physical location-typically, the first sector of the hard disk or partition in which the system is installed and spans over some other reserved free space in the filesystem. this little program, which is generally limited in size, has the required knowledge to read the second stage boot loader and transfer the execution control to it; this one installs into the root filesystem as /boot, so its physical location may vary across reboots: there is nothing in the filesystem that binds a file to specific disk blocks.

[[NetBSD/i386|http://www.netbsd.org/ports/i386/] は 2 ステージブートローダーを使っている。第 1 ステージは既知のインストール済みの物理配置を取得する。システム内のハードディスクかパーティションの最初のセクターはインストール済みであり、ファイルシステム内のいくつかの他の予約済み自由領域にわたっている。この小さいプログラムは、一般的にはサイズ制限されたものである。このプログラムは、第 2 ステージブートローダーを読み込み、それへ実行制御を転送するために必要な情報を持っている。これは root ファイルシステムの /boot へインストールする。そしてそれは、物理配置が再起動をまたいで変更されるだろう。ファイルシステムにディスクブロックの詳細に結び付けられたファイルは無いのである。

once the second stage boot loader receives control, it enters the flat protected mode (no paging, segments spanning the whole memory space), loads the kernel from disk, and runs it; it also accepts user input to choose which kernel to boot and which options to pass to it, if any. this loader also passes boot-time information to the kernel by means of the bootinfo framework. simply put, this is a table that contains information, all gathered by the boot loader, about the machine and execution environment, including:

第 2 ステージブートローダーが制御を受け取ったとき、フラットプロテクトモードに入っている( ページングは無く、セグメントはメモリ領域全体をまたいでいる )。ディスクからカーネルをロードし、走らせる。ブートさせるカーネルや、通過するためのオプション( あれば )を選択するためのユーザー入力も受け付ける。このローダーは、bootinfo フレームワークによるカーネルへのブート時の情報も通過させる。簡単に言うと、これは、以下に示すマシンや実行環境についてのブートローダーからの全ての情報を収集したものからなるテーブルである。

  • amount of available memory
  • the boot device
  • the kernel's filename
  • where the console is attached (e.g., serial line, local video card)
  • 有効メモリの統計
  • ブートデバイス
  • カーネルのファイル名
  • コンソールとして割り当てられたもの ( 例: シリアル線、ローカルビデオカード )

the src/sys/arch/x86/include/bootinfo.h file holds the complete list of possible values for bootinfo items. bootinfo is similar to the mis, although the information it includes is slightly different and, in some specific cases, more complete. in fact, this was one of the main headaches when adapting the netbsd kernel to support multiboot.

src/sys/arch/x86/include/bootinfo.h ファイルは、bootinfo アイテムとして利用可能な完璧なリストを持っている。bootinfo は MIS に似ている。この情報に含まれるものは少し違うが、いくつかの場合においてはまったく完璧だ。実際、これは、NetBSD カーネルがマルチブート対応を追加するときの主な頭痛の種のうちの 1 つであった。

later on, the kernel gets the execution control and proceeds by:


  1. storing the boot information (bootinfo or mis) in a safe place. see the native_loader function in src/sys/arch/i386/i386/machdep.c.
  2. detecting the cpu model in use (e.g., 386, 486, pentium).
  3. setting up a preliminary page directory and the corresponding page tables to remap the kernel's virtual addresses above 0xc01000000.
  4. enabling memory paging and jumping to high memory.
  5. continuing to boot and processing the boot information during its initialization.
  1. 安全な場所にブート情報( bootinfo または MIS )を保存する。src/sys/arch/i386/i386/machdep.c の native_loader 関数を参照
  2. 使用している CPU モデルを発見する( 例: 386, 486, pentium )
  3. 予備のページディレクトリをセットアップし、整合されたページテーブルをカーネルの仮想アドレス 0xc01000000 以降に再配置する.
  4. メモリーページングを有効にし、高メモリへジャンプする
  5. 引き続きブートし、初期化中のブート情報を処理する

one tricky thing is that the netbsd kernel runs, by design, at very high memory addresses (0xc0100000 and higher) for efficiency reasons: doing this allows the mapping of the kernel inside the processes' virtual address spaces without interferences. however, as mentioned earlier, the boot loader does not enable paging so it is impossible for it to put the kernel at such high addresses (unless the machine has lots of physical memory, but that is not the idea).

効率化のため{ ???? }、かなり高いメモリアドレス ( 0xc0100000 とかそれ以上 )において、設計により NetBSD カーネルが走るときに 1 つトリッキーなことがある。干渉がないカーネル内のプロセスの仮想アドレス領域を配置することを許可している。しかし、先に触れたように、ブートローダーはページングを有効にしない だから 高アドレスのようなところ( マシンがたくさんの物理メモリを積んでいない場合は例外だ )にカーネルを配置するのが不可能である。

the elf file format resolves this issue: each section in the image (text, data, bss, and so on) specifies which address is its starting virtual address, but also specifies its physical load address. the netbsd kernel's linker script takes advantage of this to generate an elf image mapped over 0xc0100000 but placed at the 0x00100000 physical address. note that the address is not 0x00000000 to ensure that the kernel does not overwrite any bios code and/or data stored below the first megabyte (the only address space accessible from real mode) when loaded.

ELF ファイルフォーマットは以下の問題を解決する。イメージ内の各セクション(text、data、bss とかいろいろ)は、アドレスが仮想アドレスから開始するように指定する。物理ロードアドレスも指定する。NetBSD カーネルのリンカースクリプトは、0x00100000 の物理アドレスに配置されている ELF イメージを 0xc0100000 以降に配置することについて優位性がある。なお、アドレスは 0x00000000 ではなく、カーネルがロード時に、あらゆる BIOS コードや最初の 1 メガバイトより下にあるデータストアを上書きしない( このアドレス領域だけはリアルモードからアクセスされる ) ことを保証する。

before paging is enabled, the kernel code is critical because it must be careful to not use the raw addresses generated by the linker (as they point to unavailable memory positions). the reloc macro resolves this by converting a given virtual address to its corresponding physical location. fortunately, once paging works, no more problems appear and this is basically a non-issue.

ページングが有効になる前はカーネルコードはクリティカルである。なぜならばそれはリンカが生成した生アドレス( 無効メモリ位置へのポインタのように )を使わないように注意しなければならないからだ。reloc マクロは、与えられた仮想アドレスから、一致する物理位置へ変換することによりこれを解決する。幸運にも、一度ページングが作用すれば、これ以上問題は現れないし、これは基本的には問題ではないのである。

making netbsd multiboot-compliant ( NetBSD をマルチブート対応にする )

due to some limitations in the native netbsd boot loader, i needed to boot netbsd using grub in a spare machine i used for kernel testing. when doing so, i found that native netbsd boot support in grub is very rudimentary, and even broken in several situations. for example, it does not set up the ksyms correctly, so ddb(4) backtraces are very difficult to understand. in addition, the upstream code does not support passing boot-time options to the kernel, but fortunately pkgsrc includes some local patches to resolve this issue.

NetBSD のネイティブなブートローダーにはいくつか制限がある。NetBSD を GRUB を使ってブートさせるために予備のマシンを用意し、カーネルをテストした。それをおこなったところ、GRUB 対応の NetBSD のネイティブなブート( ローダー? ) は、とても原始的であることが分かり、いくつかの場面でよく壊れた。たとえば、ブートローダーは ksysms を正しくセットアップしないので ddb(4) のバックトレースを理解するのにものすごく苦労する。さらに、アップストリームコード{ 最新のコード?? } はカーネルへのブート時オプションに対応していない。しかし幸運にもこの問題を解決するためのいくつかのローカルパッチが pkgsrc に含まれている。

there were two different solutions to my problems: fix grub to include full support for native netbsd boots or make the netbsd kernel multiboot-compliant. i chose the latter because i personally like the idea behind multiboot: it is more in the line of defining an abstract interface between two different system components. more importantly, though, is that changing the netbsd kernel alone has the advantage that the code in grub will not rot: the grub developers are the main developers of the multiboot specification and, because it has no netbsd-specific bits in it, they don't need to have a netbsd system available to ensure it is supported.

私の問題には 2 つの異なった解決策がある。GRUB をネイティブな NetBSD ブートローダーに完全に対応させるか、NetBSD カーネルをマルチブート対応させるかだ。私は後者を選んだ。なぜなら、前述のマルチブートのアイデアが個人的には好きだからだ。それは、2 つの異なるシステムコンポーネント間の抽象インターフェースにもっとコードを定義するものだ。もっと重要なことは、NetBSD カーネル単体を変更することは GRUB にあるコード対する優位性を無くすことはないだろうということだ。GRUB 開発者はマルチブート仕様の主な開発者であり、それゆえ、NetBSD の仕様には踏み込んでいない。彼らは NetBSD 対応を保証するために NetBSD システムを有効にする必要がないのである。{ NetBSD に特別に対応する必要がない、という感じか???? }

the first step was to define some high-level data structures to represent and manage the mh and the mis from within the kernel - something easy thanks to the detailed documentation about them. the results are in src/sys/arch/i386/include/multiboot.h.

最初のステップは、カーネル内の MH と MIS を表現したり管理するためのいくつかの高レベルデータ構造を定義することだった。それらについての詳細なドキュメントがあるのはありがたい。成果物は src/sys/arch/i386/include/multiboot.h にある。

then, the obvious move was to add an mh to the kernel so that grub could recognize it. to ensure that it was within the first 8kb of the image, i added it in the text section of src/sys/arch/i386/i386/locore.s alongside the kernel's entry point.

その後、明確な移動はカーネルに MH を追加したことだ。なので、GRUB は見分けが出来るようになった。それを保証するために、イメージの最初の 8 KB に収めた。カーネルのエントリーポイントの近くにある src/sys/arch/i386/i386/locore.s の text セクションに追加した。

this was not easy at all: the kernel's linker script had a bug that made the sections' physical addresses point to the virtual addresses. this forced me to use the address fields in the mh to indicate where to load the file, but grub was not honoring them for elf files. i had to come up with a fix for grub until a fellow developer, pavel cahyna, fixed the problem from its root: he rewrote the linker script to generate the appropriate physical addresses. nowadays, those extra fields in the mh are not used, and a mainstream grub image (distributed in virtually any gnu/linux distribution) can boot a netbsd kernel.

これは、以下のすべてにおいて簡単ではなかった。カーネルのリンカスクリプトには、セクションの物理アドレスが仮想アドレスを指すというバグがあった。これは私に、ファイルをロードするところでの MH のアドレス領域を使うことを強要した{???????????}。しかし GRUB はそれらの ELF 領域を受け入れていなかった {???????????}。GRUB の特別開発者 pavel cahyna がそれの root からの問題を適用するまでの間は GRUB を修正しておくことにした。彼は適切な物理アドレスを生成するためにリンカ―スクリプトを書き直した。今日では、それらの MH の特別領域は使われていないし、主流の GRUB イメージでは NetBSD カーネルがブート出来るようになっている( あらゆる仮想 GNU/Linux 配布物内の配布物においては )。

with the kernel recognized as a multiboot binary, i had to add the necessary code to parse the mis during boot and convert it to the native bootinfo format to minimize changes in the overall kernel. keep in mind that i was just adding another entry point to the kernel, not removing the old one, so both needed to coexist. this was tricky because of the virtual address space change that happens during bootstrap, as explained earlier: some mis handling needed to happen before the kernel enabled paging to avoid corrupting important information (basically, the ksyms).

マルチブートバイナリとして認められたカーネルにおいて、ブートしている間の MIS を解析し、カーネル全体を多少変更しネイティブな bootinfo 形式へ変換に必要なコードを追加した。私はカーネルに他のエントリポイントを追加しただけであり、エントリポイントを置き換えたわけではない。それらは同時に存在する必要があるのだ。ということを覚えておいてほしい。これはトリッキーだ。なぜならば前述したように、ブートストラップの間に仮想アドレス空間を変更するからだ。いくつかの MIS ハンドリングは、重要な情報( 基本的には ksysms )の欠落を回避するためのカーネル有効ページングが発生する前に必要となるからだ。

the c code that handles this is rather delicate and, therefore, i kept it as short as possible. once the kernel has enabled paging, the real mis parsing is done and the kernel continues its boot procedure. you can see all of this in the src/sys/arch/i386/i386/multiboot.c source file.

ハンドルする C コードは、これは多少 微妙であるんだが、なるべく短く出来るように保った。一度カーネルが有効ページングしたら、リアル MIS 解析は完了し、カーネルは自身のブート手続きを続ける。src/sys/arch/i386/i386/multiboot.c ソースファイルで全てを見ることができる。

at last, i would like to comment on another area that was difficult to manage. the native boot loader loads the netbsd kernel and stores it in memory following a specific memory layout: the kernel is first, followed by an integer that registers how many symbols the kernel has, followed by a minimal elf image that contains the kernel's symbol and string tables. when using grub, these tables load in different and unpredictable locations.

最後に、私は管理するのが難しい他の領域についてコメントしたい。ネイティブブートローダーは、NetBSD カーネルをロードし、以下に示すメモリ配置へ設置する。カーネルは最初にある。次に、カーネルがどれだけのシンボルを持っているかの整数値がある。次に、カーネルシンボルと文字列テーブルを含んだ最低限の ELF イメージがある。GRUB を使う場合、これらのテーブルは異なる場所、予測できない場所からロードされる。

a first step in resolving this problem was to reserve some space in the kernel to copy the symbols table to the appropriate place on the fly, but this proved to be a very ugly hack. a recent fix moved the symbols table to just after the kernel (taking care not to overwrite it or other important information during the move). the kernel also has a specific function to initialize the ksyms global table based on a memory region (not necessarily a complete elf image). you can see this in the ksyms_init_explicit function defined in src/sys/kern/kern_ksyms.c.

この問題を解決するための最初の手順は、カーネルがシンボルテーブルを適切な場所へダイレクトにコピーできるように、いくらかの領域を予約することだ。しかしこのやりかたは実に酷い hack だ。関連した fix はシンボルテーブルを、ちょうどカーネルの後ろへ移動する( 移動させている間にカーネルや重要な情報を上書きしないように注意 )。カーネルは、メモリ領域をベースにした ksyms グローバルテーブル( 必ずしも ELF イメージではない )を初期化するための特別な関数も持っている。ksyms_init_explicit 関数の定義は src/sys/kern/kern_ksyms.c で見れる。

conclusion ( 終わりに )

if all operating systems supported the multiboot specification, users would be happier than they are now: a very advanced boot loader supporting all operating systems would most likely exist, and its installation could be trivial. plus, these users would not need to care about the installation of an os disabling another os.

すべてのオペレーティングシステムがマルチブート対応したならば、利用者はいまよりも幸せになるだろう。ブートローダーがかなり進歩してすべてのオペレーティングシステムに対応ことがもっともありがたいことである。そしてそれは、インストール作業が取るに足らないことになるだろう。さらに、これらの利用者は、OS インストール作業で他の OS を無効にすることに注意する必要がなくなるだろう。

personally, i found the process of making the netbsd kernel multiboot-compliant to be a very interesting and instructive task. furthermore, because almost all linux distributions nowadays install grub by default, it is now a lot easier to set up a dual-boot machine with both linux and netbsd. further steps involve splitting the kernel in two different sections within the elf binary in order to map each of them at separate virtual addresses. this could simplify some of the issues that arise in the code that runs before paging is enabled.

個人的にはマルチブート対応 NetBSD カーネルを作成する作業はとても面白かったし、タメになった。そのうえ、いまどきのほとんどすべての Linux ディストリビューションは既定で GRUB をインストールするので、今や Linux と NetBSD の両方でデュアルブートマシンをセットアップすることはとても簡単である。さらに先のステップとしては、されたカーネル、分割された仮想アドレスの各々へマップするための ELF バイナリ内の 2 つの異なるセクションで、カーネルを分割することだ。これはページングが有効になる前に走るコードで発生するいくつかのシンプルな課題で出来る。

now it is your turn to adapt your favorite operating system to this protocol and attempt to get your modifications into the mainstream sources!


julio m. merino vidal studies computer science at the fib faculty in barcelona, spain.