掲載記事一覧
Last updated Sat, Jan 10, 2004

第三部開始に向けて
 私達は18回におよぶ連載を通じて、どのような環境に置かれても、自力で道を切り開けるだけの基礎体力を身につけました。そこで、いよいよGCCプログラミング工房第三部の幕開けです。これからしばらく、PC/AT ハードウェアの最深部を探訪する旅が続きます。

 UNIX USERの読者の方々であれば、カーネルに興味を持ち、そのソースツリー解読に挑戦した経験をお持ちの方は多いことと思います。しかし、その挑戦のほとんどは、最初のブートプロセスで頓挫してしまったのではないでしょうか?カーネルの起動を完全に理解するためには、周辺デバイスに関するハードウェアレベルの知識が必要とされるため、これは仕方がありません。

 ところが、書店に足を運んでみれば分かりますが、キーボードやVGAディスプレイ、フロッピーディスクやRS-232Cなどの基本I/O装置を、機械語レベルで直接制御する方法に触れた書籍は、現在絶滅に近い状況です(DOS時代であれば、まだ入手可能だったのですが)。このため、OSに興味を持つ->ソースリスト読破に挑戦する->ブートプロセスで頓挫->指南書を探す->見つからず断念・・という、悪循環が続いています。

 システムプログラマーとして優れた資質を持ちながら、適切な指導を受けることができないために、その才能を開花できずにいる人達の数は、かなりの数に上るのではないのでしょうか?これは、極めて残念かつ嘆かわしいことです。

 一方で、「なぜ、今さらそんな古めかしい技術にこだわるのか?」と疑問をお持ちの方もおられるかと思いますが、私はこれまでの経験から「すべての応用は基本の延長線上にある」と考えています。Linuxの本質は、Linus 氏が学生時代に慣れ親しんだ386マシンをハードウェアレベルから「究める」ことで私達の視界に入ってくるはずです。遠回りに見えるかもしれませんが、この第三部をくぐり抜ければ、カーネル山への登山口はすぐそこまで迫り、なおかつその頂上も見据えることができるでしょう。

平成15年6月12日

西 田 亙 (NISHIDA Wataru)

過去のバナーメッセージ

GCCプログラミング工房へのお便り

2004年2月号 GCCプログラミング工房 第25回 幻の90x60テキストモード p133-148

VGA シリーズ最終回の今回は、ビデオ信号のタイミング制御を行い、テキストモードを自在に設定します。誌上では 90x60 モードしか実演していませんが、水平軸・垂直軸のパラメータ設定を適切に行うことで、横112桁・縦72行など知らない人が見たらビックリするようなテキストモードも実現可能です。ビデオディスプレイに負担がかからない範囲で、ビデオタイミングのチューニングに挑戦してみてください。(編集担当 渡辺氏)

ソース一式および FreeDOS 起動ディスク

gcc-25.tar.gz

記事中で使用したソースファイル集です。make 一発で実行ファイルが出来上がります。

gcc-25-freedos.img.gz

今回作成したプログラムを含む、FreeDOS 起動ディスクイメージです。dd if=gcc-25-freedos.img of=/dev/fd0 で、FDに書き込めばそのまま利用できます。

2003年6月号 GCCプログラミング工房 第19回 セグメントを操る p127-140

GCCプログラミング工房・第三部最初のテーマは、リアルモードセグメントです。x86は自身がもつ歴史のしがらみから、16ビットリアルモードと32ビットプロテクトモードのふたつの顔を持っています。

PCがROM-BIOSを通じて起動すると、リアルモード上でハードウェアの初期化を行った後に、ブートプログラムを実行します。ブートプログラムは、具体的にはハードディスクもしくはフロッピーディスクの先頭セクター(512バイト)に書き込まれており、このプログラムは後続のブートローダーやカーネルを読み込みます。

重要なことは、この読み込みまで(画面へのテキスト表示、キー入力、ディスクからの読み込みなど)の段階で、OSはリアルモードBIOSのお世話になっているという点です。すなわち、最新OSと言えども、一旦リアルモードBIOSの力を借りなければ起動できないのです。

このため、Linux/*BSDなどのPC-UNIXやWindowsはすべて、リアルモード上で動作する自前のブートストラッププログラムを有しています。すべては、このブートストラップから始まる訳です。

ところが、リアルモードの世界には、古来数々のプログラマーを悩ませてきた「セグメント」という鬼門が存在します。今回は、このセグメントに本連載流の新しい切り口で迫ります。(編集担当 渡辺氏)

訂正

  なし

リファレンスリスト

ソースリスト tgz ファイル

記事中で使用したソースファイル集です。

2003年5月号 GCCプログラミング工房 第18回 スタック操作・免許皆伝 p127-140

 GCCプログラミング工房第二部の最終回です。octopusで培った知識を活用し、x86-LinuxにおけるC言語での引数渡しの謎を解明します。引数という概念は、C言語初心者にはなかなか難しいものですが、機械語レベルからスタック機構を理解できていれば、それほど難解なものではありません。

 特にシステムプログラミングでは、引数を自在に操る能力が必要とされるため、Cソースを一瞥しただけで、スタック上に配置された引数やリターンアドレスが、バイト型式でイメージできなければなりません。

 今回は、自動変数と引数の正体をスタック機構の観点から詳細に解析することで、C言語の仕組みに迫ります。経験を積んだプログラマーと言えども、可変引数の技術背景を正確に理解している人は少ないでしょう。stdarg.hに記載されたお仕着せのマクロに頼る事なく、自力でprintfをコーディング出来た時、あなたはスタック操作免許皆伝の境地に達していることでしょう。

 ここまで来れば、もはや重厚長大な標準Cライブラリーは必要ありません。後は、実践を通じて応用力を身につけていきましょう。次回からは、GCCプログラミング工房・第三部が幕を開けると同時に、短期連載「Linuxから目覚めるぼくらのゲームボーイ!」が始まります。ご期待ください。(編集担当 渡辺氏)

訂正

  1. p128 リスト3 引数の表記が上下入れ替わっています
  2. p131 図2右側 ptr[1], ptr[0],ptr[-1]に全て&を前置
  3. p131 図2説明 スタック内のアドレス --> スタック内の第一引数のアドレス
  4. p133 左カラム上から8行目 40044C08 --> 8049638

リファレンスリスト

ソースリスト tgz ファイル

記事中で使用したソースファイル集です。

2003年4月号 GCCプログラミング工房 第17回 Cハッカーへのスタック p131-140

 今回はいよいよ octopus にスタック機構を実装します。push/popの2命令を組み込むだけで、プログラム構造は一気に深みを増し、Nested callなどの複雑な処理が可能になります。スタックは人類の一大発明と言えるでしょう。

 push/popだけでサブルーチン呼び出しを記述するとなると大変なので、人間はさらにcall/ret命令を生み出しました。なんという快適さ!総集編として電子オルガンをコーディングした上で、octopusに別れを告げましょう。

 最後にGNU Debugger GDBを用いて、x86-Linux-GCCにおけるスタックの動きを追います。32ビットCPUと言えども、その基本構造はシンプルなoctopusと大差ないことがお分かり頂けることと思います。(編集担当 渡辺氏)

訂正

  1. p131 右カラム下から2行目 出力バッファ --> 入出力バッファ
  2. p132 図1・popの説明 spを1減らす --> spを1増やす
  3. p133 実行例3 リターンアドレスのである --> リターンアドレスである
  4. p134 右カラム下から3行目 31番地未満 --> 32番地未満
  5. p137 右カラム下から1行目 mainも入れると --> crt>main>functionという

リファレンスリスト

ソースリスト tgz ファイル

記事中で使用したソースファイル集です。

2003年3月号 GCCプログラミング工房 第16回 本格仮想機械への序章 p121-130

 今回は、これまで手塩にかけて育て上げてきた octopus に、演算処理・ジャンプ・条件分岐・サブルーチン分岐命令を実装します。この結果、octopus は本物のCPUと比べても見劣りしないレベルまで一気に進化しました。

 コンピューターの特徴のひとつは高速な演算処理ですが、これだけでは電卓に毛が生えた程度の価値しかありません。コンピューターの最も重要な特性は、繰り返し処理と条件分岐にあると言っても過言ではないでしょう。

 しかし、人間はこれだけでも飽き足りず、ついにサブルーチンを発明します。今回は最も原始的なサブルーチン呼び出し機構である、JSR (Jump to SubRoutine、別名 BRL: BRanch and Link)命令を実装しました。JSR命令を含んだアセンブリソースをハンドアセンブルすることで、アセンブラーはなぜ2回に分けてソースリストを処理する必要があるのか(いわゆる2-pass)、その理由が明らかになります。アドレス解決は、今後リンカーローダーの働きを理解する上で、大変重要になる概念ですから、この機会にしっかり把握しておきましょう。

 最後に、自分の手で作り上げた命令を実際に使用して、レジスターベース・サブルーチンの限界を理解します。(編集担当 渡辺氏)

訂正

  1. p121 左カラム上から4行目 キーボード入出力 --> キーボード入力
  2. p121 左カラム下から1行目 終了させるのには --> 終了させるためには
  3. p128 左カラム上から4行目 LEDは --> キーボードLEDの
  4. p128 右カラム上から3行目 アセンブルすると --> アセンブル第一段階では

リファレンスリスト

ソースリスト tgz ファイル

記事中で使用したソースファイル集(第17回のソースターボールと同一)。

2003年2月号 GCCプログラミング工房 第15回 キー入力処理を究める! p121-130

 第15回では Linux 上でのリアルタイムキー入力に挑戦します。DOS 上のプログラミングとは異なり、UNIX 上でキーボードが押されているかどうかをリアルタイムで判断するのは容易なことではありません。この難問を解決するためには、汎用端末制御インターフェースを操る必要がありますが、具体例としてコントロールCを始めとする制御コードの入力も可能にした柔軟性のあるキー入力ルーチンを作成します。

 また、記事中ではシグナル処理についても触れています。UNIXの醍醐味であるプロセス間通信の基本を学びながら、SIGINT, SIGALRMなど実践で役立つシグナルの数々とそのプログラミングテクニックを紹介しました。将来、UNIX 上のアプリケーションを作成する際に、必ず役立つことと思います。

 最後に、Linux特有のキーボードモード制御の方法を紹介し、プログラム中でASCIIコード、システムスキャンコード、Linuxスキャンコードの3種類を使い分ける実例を示しました。Linuxアプリケーションで左右のシフトキーを判別したり、ファンクションキー、ALTキー、カーソルキーからのユーザー入力を受け付けるためには、必須のテクニックです。この機会に是非マスターしておきましょう。(編集担当 渡辺氏)

訂正

  1. p124 実行例2 Ctrl+\キーとCtrl+Cキーの説明が入れ替わっています
  2. p125 左カラム下から11行目 SIGALRM処理 --> sig_alarm 関数

リファレンスリスト

ソースリスト tgz ファイル

記事中で使用したソースファイル集です。

2003年1月号 GCCプログラミング工房 第14回 指先からの旅 p105-120

今月はキーボードスキャンコード可視化プログラムを作成した後に、キーボードコントローラーを制御してリピートレートを最大・最小に変更してみます。ここまで来れば、キーボード・ハードウェアを制覇したと言っても、過言ではないでしょう。

次に、得られた知識を実践で応用してみます。最初のテーマはシステムスキャンコードをキーボードマップに従い ASCII コードに変換するプログラムです。PC-UNIX や X-window では「キーボードマップ」という概念が用いられていますが、その実体となると曖昧模糊としたイメージしか湧かない方も多いのではないでしょうか?

今回は対象キーを中一段に限定してはいますが、本格的なキーボードドライバーのエッセンスを全て兼ね備えたプログラム keymap.c を用意しました。keymap.c を理解することで、「キーボードマッピング」の正体が明らかになることでしょう。プログラムを改造して、是非自分なりのマッピングを実現してみてください。キーボードに対する理解が飛躍的に深まること請け合いです。

最後に、コーディングで鍛えた知識が「最前線の現場」で使えるかどうか、腕試しをしてみましょう。お相手は Linux カーネルです。焦点をコードの重要ポイントに絞り込むことで、キーボード割り込みから Linux スキャンコード変換に至る全体像を俯瞰してみました。基本さえ把握できれば、最新OSの内部構造も比較的容易に理解できることを実感して頂ければ幸いです。応用はすべて基本の延長線上にあるのです。(編集担当 渡辺氏)

ここで皆さんにお詫びしておかなければなりません。次回タイトルは「スタック操作を直に体験」となっていますが、急遽「キー入力処理を究める!」に変更となりました。せっかくキーボードに関する知識が深まったにもかかわらず、アプリケーションプログラミングにおけるキー入力処理を解説せずに終わることは、余りに惜しいと考えたからです。

ということで、次回は電子オルガンが登場します。キーが「押された、離された」をリアルタイムにプログラム中で判断することは、一見簡単なように見えて実は非常に難しいテーマです。N88-BASIC/DOS 時代から続く、この難問を ioctl システムコールと Linux スキャンコードを応用することで見事解決してみましょう!

訂正

  1. p117 図Bタイトル PC/A --> PC/AT

リファレンスリスト

ソースリスト tgz ファイル

記事中で使用したソースファイル集です。記事中では紹介していない Makefile が用意されていますので、make 一発で実行ファイルが出来上がります。

スキャンコードは3度変貌する

記事中で「Linux スキャンコード」という言葉が登場していますが、これは私の造語です。Linux community で一般的に使われている訳ではありませんので、ご注意ください。なぜ独自の言葉を定義したかと言いますと、この言葉を用いた方がより多くの方が正しく理解できると考えたからです。

一般的には PC/AT におけるスキャンコードはキーボード・スキャンコード、システム・スキャンコードの2つと考えられています。前者は break code に 0xF0 を前置、後者は break code の最上位ビットをONにする訳ですが、106やJP106キーボードでは 0xE0 が前置された拡張キーが存在するため、カーソルキーや右リターンキー、右シフトキーなどの make code は複数バイトから構成されています。これはプログラマー側から見ると大変厄介な話であり、できれば統一された1バイトでスキャンコードを扱いたいところです。

そこで、Linux カーネルの開発者は独自にすべてのキーに対して1バイトのコードを割り当てました。 その判断自体は英断として評価されるべきでしょうが、例によって彼らはこの辺りの事情を文書化していません。唯一伺い知れるのはキーボード ioctl の KDSKBMODE における K_XLATE, K_RAW, K_MEDIUMRAW (次回解説)という特殊モードなのですが、「RAW と MEDIUMRAW の違い」が明記されていません(Rare とMediumrare にかけてネーミングしたのでしょうか?)。

このため、プログラマーの間にはかなりの混乱が生じているようです。私はこの問題は Linux スキャンコードという言葉を新しく定義し、キーコード処理の全体像を文書化することで、簡単に解決できるのではないかと考えています。


2002年12月号 GCCプログラミング工房 第13回 FreeDOS でキーボードを探る p129-140

ついに FreeDOS の登場です。「なぜ UNIX USER 誌上で DOS なのか?」という疑問を持たれた方も多いことでしょうが、今月号の内容および今後の連載を読み進めて頂ければ、私の真意は分かって頂けるのではないかと思います。

私はこれまで「教育環境として UNIX は果たして適切なのだろうか?」という疑問をずっと抱いてきました。完成された開発環境という意味において、UNIX はまさしく最高のクオリティーを私達に提供してくれる訳ですが、 I/O 処理や CPU ・メモリー操作などのコア部分になると強固な保護機構が働くため、一般人はアクセスできません。

一方、昔ながらの 8086 リアルモード・DOS は全てのリソースを「自らの責任において」自由自在にアクセスすることが可能です。もちろん、「システム暴走&リセット」が日常茶飯事になる訳ですが、人が成長するために失敗や危険は付き物でしょう。パイオニア精神豊かな若い人達には、「あれはダメ、これもダメのUNIX」よりも「傷だらけになる覚悟でやってみんかい!」という DOS の方が向いているような気がします。

なお、現在 FreeDOS project が配布しているブートフロッピーはハードディスクへのインストールを想定した物です。残念ながら、これでは気軽に FreeDOS を楽しむ訳にはいきませんので、今回は 第一回 Brainstorming in Ehime で使用した学習ディスクに改良を加えた起動ディスクを用意しました。

この学習用ディスクをフロッピードライブに挿入し、PCを再起動するだけで立派な 8086 開発環境が目の前に現れます。最近のPCは1GHz超の CPU と40GBのHDDが最低限の仕様になっているようですが、基本を学習するためにここまで豪華なマシンは必要ありません。386とフロッピードライブが付いた骨董品で十分なのです。最新OSを理解するために必要なエッセンスは、すべてこの愛すべきクラシックマシンから吸収することができることでしょう。

決して流行にとらわれることなく、幹となる基本技術をじっくり理解していきましょう。スピードが求められる現代において、これはいささか勇気を要する事ではありますが、長い目で見れば結局はこれが近道なのです。

さて、今月は FreeDOS を題材に用いて、GNU 開発ツールによる DOS アプリケーションの開発方法を紹介します。残念なことに、世の中には「GCC ではリアルモードプログラムは出力できない」という誤った情報が流れているようですので、この機会に誤解が解かれることを願っています。それにしても GNU 開発ツールの驚くべき柔軟性にはいつも感心させられます。この感覚をひとたび味わってしまうと、二度と市販のツールには戻れませんね(もちろん UNIX 環境も込みでの話です)。

最後に具体的なテーマとして「システムスキャンコードの可視化プログラム」をコーディングします。リアルモードの恩恵で、私達は割り込みコントローラーからキーボードコントローラーまでを自由自在に操作することが可能です。このような自由度は PC-UNIX 上では不可能でしょう。「キーを押すと make code、離すと break code」が出力されている様子を是非自分の目で確かめてみてください。getchar() 関数をOS上で使っている限り、決して拝むことの出来ない世界がそこにあります。 (編集担当 渡辺氏)

さて、次回「指先からの旅」は「キーボードスキャンコードを可視化」することから始まります。つまり、キーコードの源流を見極めるのです。その後、実際に自分でシステムスキャンコードを ASCII コードに変換するプログラムを作成してみましょう。自らコードを書き下ろすことで、知られざるキーボードマップの正体が明らかになります。乞うご期待!

訂正

  1. p132 右カラム上から18行目 u lol --> u 101

リファレンスリスト

FreeDOS 起動ディスクイメージおよび記事中ソースリスト tgz ファイル

学習用 FreeDOS フロッピーディスクイメージ、および記事中で使用したソースファイル集です。記事中では紹介していない Makefile が各ソースディレクトリに用意されていますので、make 一発で実行ファイルが出来上がります。

FreeDOS project

FreeDOS project のホームページ

FreeDOS software

FreeDOS 用公開ソフトウェア一覧

FreeDOS FTP

FreeDOS FTP server

FeeeCOM 内部コマンド一覧

FreeCOM の内部コマンド解説書

NASM

The Netwide Assembler

e3
e3 man

The e3 editor

debug

Clone of MS-DOS DEBUG command

配布ファイル gcc-prog-studio-13.tgz 内容

gcc-prog-studio-13
|-- gcc13-freedos.img
|-- hello
| |-- Makefile
| |-- crtbegin.S
| |-- crtend.S
| |-- dos-console.c
| |-- dos-console.h
| |-- dos-console.s
| |-- dos.ls
| `-- hello.c
`-- scancode
|-- Makefile
|-- crtbegin.S -> ../hello/crtbegin.S
|-- crtend.S -> ../hello/crtend.S
|-- dos-console.c -> ../hello/dos-console.c
|-- dos-console.h -> ../hello/dos-console.h
|-- dos.ls -> ../hello/dos.ls
|-- kbc.c
|-- kbc.h
`-- keyscan.c

・gcc13-freedos.img は起動フロッピーディスクイメージです。dd コマンドなどでフロッピーディスクに書き込んだ後に、起動ディスクとして使用してください。

・hello は DOS 版 Hello, world! プログラムを格納したディレクトリです。

・scancode ディレクトリには、システムスキャンコード読み取りプログラムが格納されています。

 

2002年11月号 GCCプログラミング工房 第12回 踊るキーボードLED p117-128

先月は 8253 と 8255、ふたつの周辺LSIの操作を通じて PC/AT の内蔵スピーカーを制御してみました。「I/O 制御と言っても、思いの外簡単だな」と感じて頂くことが出来たなら、前回の目的は達成です。

今月は、新たにキーボードコントローラーに挑戦します。普段毎日お世話になるキーボードですが、「どういう仕組みでキー入力できるのか?」と質問されて、スラスラと答えることが出来る人は世界広しと言えども、そう多くはないはずです。

しかし、心配は無用です。今月の記事をじっくり読み進めれば、「LED制御なんて簡単じゃん!」と言って頂けることでしょう。是非とも頑張って、コードの動きを追ってみてください。(編集担当 渡辺氏)

次回は FreeDOS 上で、.com プログラムを作成しキーボードコントローラーを使い倒します。作成にはもちろん我らが GNU 開発ツールを用います。一部で「GCC は 8086 リアルモードのコードを生成できない」という噂があるようですが、これは全くの誤りです(実際 Linux カーネルでも活用されていません)。来月は DOS 用の crt (C RunTime startup program) およびリンカースクリプトを作成し、ちょっとしたテクニックを使うことで GCC の能力を DOS 上で開花させます。

その上で、CPU リセットや、メモリーの32ビット化プログラムを作成してみましょう。8086 のセグメント機構についても併せて解説する予定ですので、将来オリジナルのOSを書いてみたいという方は必読です。

そうそう重要な事を忘れていました。次回は「スキャンコード」を自分の目で確認します。知られざるキー入力の舞台裏を覗いてみましょう。

訂正一覧

  1. p121 左カラム上から8行目 キーボードコマンドバイト --> デバイスコマンドバイト
  2. p121 右カラム上から7行目 (OBF)が0であること --> (OBF)がであること !注意!
  3. p121 表2 ディレイ時間 --> ディレイ時間(dly)
  4. p121 表2 ※1 ((1+bit65)X250msec --> (1+dly)X250msec
  5. p128 実行例2 2 (Caps Lock) --> 4 (Caps Lock)
  6. p128 実行例2 2 (Scroll Lock) --> 1(Scroll Lock)
  7. p128 今月のGNU TIPS LDEパラメータバイト --> LEDパラメータバイト

リファレンスリスト

記事中ソースリスト tgz ファイル

記事中で使用したソースファイル集です。記事中では紹介していない Makefile が各ソースディレクトリ(keyled, octopus2)に用意されていますので、make 一発で実行ファイルが出来上がります。

The Undocumented PC キーボードコントローラー・プログラミングに関する最も詳細な資料が掲載されています。詳細は「お勧めの書」をご覧ください。

2002年10月号 GCCプログラミング工房 第11回 素手でスピーカを操る p121-132

今月のテーマは「音」です。日頃聞き慣れた内蔵スピーカーから、一体どのようにして音が出ているのか、ハードウェアレベルから理解します。

今回の記事は I/O 操作だけではなく、「ひとつの目的を実現するためには様々なプログラミング・レベルが存在するのだ」という点に、重きを置いています。最も手近な方法である echo コマンドに始まり、putchar 関数、ioctl 関数、I/O ポート直接操作、と全部で4つのプログラミング・レベルを紹介しました。

是非とも全レベルをご自分で実践してみてください。その上で、4つのレベル全体を見渡してみると良いでしょう。各レベルにはそれぞれ長所・短所が存在していることがお分かり頂けると思います。echo コマンドや putchar 関数はとても簡単で、OSの違いを越えて実行可能ですが、音の高さや長さなど細かいところは制御できません。I/O ポート直接操作は最も高度な知識が必要ですし、コーディングに手間もかかりますが、ハードウェアの性能を最大限まで引き出すことが可能です。

どのレベルが一番優れている・・という訳ではありません。出来るだけ多くのレベルからアプローチできると、プログラミングの幅は指数関数的に広がり面白くなるのだ、という事を実感して頂きたかったのです。

富士山の姿を思い浮かべてみてください。ただ一点だけから眺めるよりも、色々な場所から四季折々の海や田畑に囲まれた富士の美しい姿を楽しむ方が「粋」ですね。「より多くの視点を持つ」ことの重要性をプログラミングを通じて理解して頂ければ幸いです。(編集担当 渡辺氏)

さて、次回はキーボードの登場です。普段毎日お世話になるキーボードですが、その実体は内蔵スピーカー以上に闇に包まれています。連載1年目を迎える次号では、この厚いベールに包まれてきたキーボードの正体をハードウェアレベルから明らかにしていきます。

訂正一覧

  1. p128 左カラム下から3行目 プログラマブル・パラレルポート --> プログラマブル・周辺インターフェース
  2. p128 左カラム下から1行目 ポートを3つ --> ポート3つ
  3. p130 左カラム上から9行目 14〜17行で・・できるからです。
    この点について補足しておきます。const 宣言では型チェックが効きますが、その実体は.rodata セクションに配置される定数変数です。当然のことながら、マクロ定義では変数としては扱われず、機械語コード中のオペランドとして展開されます。よって、複数のソースファイル中でポート値(例えば pit_ctl)をconst 宣言で定義すると、多重定義エラーが発生しますので注意してください。static const 宣言であればこの問題は回避できますが、一般的にはマクロ定義が利用されています。
  4. p130 リスト11 25行目 ferquency --> frequency
  5. p130 右カラム上から4行目 LSBとMSBを読む --> LSB・MSBの順でロード

リファレンスリスト

記事中ソースリスト tgz ファイル

記事中で使用したソースファイル集です。

2002年9月号 GCCプログラミング工房 第10回 仮想機械 octopus 登場 p117-126

9月号より、いよいよアセンブリ言語の解説が始まります。当初はいきなり x86 CPU を題材に解説する予定だったのですが、やはりアセンブラー未経験者には無理があると判断しました。「難しいのなら、簡単な基本CPUを作ってしまえば良いではないか!」、ということで仮想機械 octopus 誕生となった訳です。

仮想機械と言えば Java が有名ですが、最近では Inferno も Dis という仮想機械に基づいています。さて、その仮想機械ですが、名前からすると随分難しそうなイメージですよね。でも、蓋を開けてみるとそうでもないんです。記事を読んで頂くと納得されると思いますが、CPUの基本構造をC言語でコーディングすることは、私達が呼吸する如く自然な作業です。少々、言い過ぎでしょうか?

まず最初にレジスターとメモリーを定義します。次に機械語のオペコード、オペランドをデザインし、これに呼び出しエントリーアドレスなどを組み合わせ構造体で表現します。後は、命令をメモリーからフェッチし、オペコードを判定し、プログラムカウンターをインクリメント、最後に該当する処理関数を呼び出すだけです。

たったこれだけのことですが、立派な仮想機械が誕生するのです。気に入らなければ、自分の好きなように命令を追加・修正すれば良いでしょう。思い通りのCPUが楽しめるなんて、ちょっと素敵ですね。

さて、今回の octopus type I の中で最も重要なポイントをお教えしておきます。ひとつは、命令コードがオペコードとオペランドモードのふたつのパートから構成されている点です。また、mov 命令のために複数のオペランドモードを実装しましたが、この概念も大変重要です。コンパイラーだけを使っているのであれば、機械語の命令コードを理解する必要はありません。しかし、リンカーやアセンブラーの存在、はたまた機械語の正体も知らずに一生を終えるプログラマーが果たして幸せなのかどうか、私は大いに疑問を覚えます。本連載読者の皆さんには、是非ともインストラクションマニュアルを解し、ハンドアセンブルでハードウェアを自由自在に操ることが出来るプログラマーになって頂きたいと思います。最後にCPUが命令をメモリーからフェッチ後、プログラムカウンターをインクリメントしている姿を頭の中にイメージできるようにしておきましょう。(編集担当 渡辺氏)

さて次回第11回ですが、これは我ながら面白い内容になりました、自信作です。PCには内蔵スピーカーが用意されており、音楽演奏も可能になっています。しかしサウンドチップが全盛の現在、PC-UNIX のコンソール画面でエラー音に使われるぐらいが関の山。次回は、老兵スピーカーにスポットライトを当ててみます。スピーカー回りのハードウェア構造を一から理解し、周辺LSIを制御することで、「OSに頼ることなく」メロディーを奏でてみます。ハードウェアを直接操る楽しさ、素晴らしさを味わって頂けることでしょう。乞うご期待!

訂正一覧

  1. p119 左カラム上から12行目 間違いではりませんが、oct_inst の "inst" は INSTruction 、すなわち命令コードの略です。
  2. p119 右カラム上から4行目 定数から --> 定数の
  3. p119 右カラム下から16行目 2種類の --> 2方向の
  4. p121 リスト6・24行 operation --> operand
  5. p123 右カラム中断 「この結果、」は「#define debug(format, args...) fprintf(fdebug, format, ## args)」を指します(## オペレーターを追加)。

リファレンスリスト

octopus ソースファイル

記事中で使用したソースファイルです。

2002年8月号 GCCプログラミング工房 第9回 make bzImage 制作技術 p125-134

Making of Linux シリーズもいよいよ最終回です。今回は、私達が日頃お世話になっている bzImage の誕生過程を詳細に解析します。bzImage は head.o, misc.o, piggy.o の3つのオブジェクトファイルから構成されていますが、圧縮カーネルは最後の piggy.o 中に納められています。

vmlinux のシンボル情報や .comment, .note セクションが削除された後に、バイナリーイメージに変換されます。このイメージに4バイトのバイナリーイメージ長と、3つのシンボルを加えたオブジェクトファイルが piggy.o です。バイナリーイメージが、一旦 piggy.o という名前の ELF 形式に変換される点に注目しましょう。head.o, misc.o は、この3つのシンボル情報をもとに圧縮カーネルイメージを展開します。piggy.o の作成テクニックは、Linux カーネルソースツリーの中でも最も高度な部分ですので、十分そのノウハウを味わいながら吸収してしまいましょう。

後半では前回紹介した Orphan functions を可視化するための改造をカーネルに施します。ちょっとしたハッキングですが、カーネルに手を加えることは決して恐れるようなことではありません(サーバーの場合は別です)。この「ショート・ハッキング」には、これまで学んできた知識が全て詰め込まれていますので、一文一文その意味を確認しながら是非お手元のカーネルに挑戦してみてください。カーネルの存在をより身近に感じることができるでしょう。(編集担当 渡辺氏)

上にも述べました通り、GCCプログラミング工房は次回から新しいステージに突入します。今後とも、ご支援のほどよろしくお願い致します。

訂正一覧

  1. p126 右カラム上から13行目 40〜50行 --> 40〜47行
  2. p127 図1 comment --> .comment, EFF形式 --> ELF形式
  3. p130 図2 __kstrtab_jiffies[] から出ている2本の矢印は間違い、正しくはシンボルテーブル真ん中の &jiffies / __kstrtab_jiffies 欄の先頭アドレスを指します。また後者の __kstrtab_jiffies は .kstrtab セクション中の "jiffies" 文字列を指します。

2002年7月号 GCCプログラミング工房 第8回 vmlinux 集約までの技 p117-126

予定では連載2回分で「making of Linux シリーズ」は終了するはずだったのですが、分量が増えてしまい第9回まで続くことになりました。今回は make clean / make distclean ターゲットの説明を行った後に、Linux カーネル七不思議のひとつである Orphan functions の謎に迫ります。Orphan functions は「カーネルソースファイル内で定義されているにもかかわらず、一度も呼び出されることのない不思議な関数群」を指す私の造語です。

Linux カーネルソースツリーに挑戦して間もない頃、コード内容から類推すると重要な初期化処理を行っているにもかかわらず、ただの一度も呼び出されていないという、謎の関数に出会いました。私の周りには相談する人もいませんでしたので、ネット上を丹念に検索したのですが、結局その正体は分からずじまい。カーネルの解読も、そこで頓挫したままでした。

当時の私と同じ疑問を持ちながら悶々とした日々を過ごしている方が世界中にいらっしゃると思いますが、今月の記事を読めばその悩みはきれいさっぱり氷解することでしょう。Orphan functions の秘密はリンカースクリプトに隠されているのです。(編集担当 渡辺氏)

さて、次回こそ bzImage 誕生のからくりが明らかになります。これまでに学んだ知識を活用して、Orphan functions の出所(関数名・ソースファイル名・ソース内行番号)を逐一表示するカーネル改造法を紹介します。自分自身の手でカーネルを「hack」してみましょう!

訂正 p.125 左カラム 上から9行目 init.d -> init.h

2002年6月号 GCCプログラミング工房 第7回 make config と make depend の意義 p97-106

数あるカーネル構築説明書のほとんどは「make menuconfig の後に、make dep; make clean; make bzImage を行う」と機械的に説明するだけです。しかし、それぞれの操作で一体何が起きているのか、それぞれのステップにはどういう意味があるのか、make dep は毎回必要なのか、などの疑問を持たれている方は多いことと思います。

第7・8回では、従来触れられることのなかったこれらの問題に切り込みます。今回は make config & make depend です。特に前者のコンフィグレーション作業は、カーネル構築だけでなく Linux 上でのシステムプログラミングや各種ツールのビルド時に大きく影響してくるため、裏側で何が起きているのか正確に把握しておく必要があります。あまり重要視されていないようですが、make *config は Linux システムにおける最大のピットフォールのひとつです。この機会にその正体を見極めましょう。

後半では、これまた明快な解説文書が存在しない CONFIG_MODVERSIONS オプションについて考察しています。CONFIG_MODVERSIONS に関するまともな解説は、私が知る限り "Linux Device Drivers 2nd Ed." 中の第11章 "Version Control in Modules" しかありません。しかし正直な話、私はこの説明を何度読み返しても理解できませんでした。結局カーネルソースを追跡して初めて理解できたのですが、どうもこの原因は開発者や解説者が無責任に用いている「用語」にあるようです。

現在出回っている解説中では CONFIG_MODVERSIONS オプションで有効になる機能は "Versioned symbol", "Version control" という名前で呼ばれています。しかし、私は正しくは "Identification tagged symbol" もしくは "Prototyped symbol" と呼ぶべきであると考えています。なぜならシンボル名に付加される識別コードには、関数や変数のプロトタイプが符号化されているのであって、カーネルのバージョン情報は反映されていないからです。Linux では、このように不適切な用語の使用によって、ユーザーに混乱をもたらしている事例がしばしば見受けられます。残念なことですが、情報を決して鵜呑みにすることなく、疑問を持った時は自分が納得できるまで調べ上げる姿勢が必要です。

なお文中で、C++の多重定義の舞台裏についても紹介しました。プロトタイプ宣言は単なる飾りではなく、堅牢なシステム構築のため積極的に利用されていることを理解して頂ければ幸いです。(編集担当 渡辺氏)

次回は make clean および make bzImage を解析します。特に bzImage ターゲット中では高度なテクニックが随所で使われており、GNU開発ツールを使いこなす上で必見です。記事中で、リンカースクリプトとCソースの見事なまでの連携プレーをご紹介します。また、Linux カーネル挑戦者が必ず遭遇する「Orphan functions」の謎にも迫ります。ご期待ください。

訂正

  1. p102 右かラム 6行目 acquire_console_sem --> console_conditional_schedule
  2. p104〜p105多数 donar --> donor 第5回のスペルミス続きです、申し訳ありません。ソースは修正しました。

リファレンスリスト

記事中ソースリスト tgz ファイル

記事中で使用したソースファイル集です。


2002年5月号 GCCプログラミング工房 第6回 Making of Linux p103-112

これから3回にわたり Linux カーネルの構築舞台裏を探っていきます。最近、Linux カーネルの内部構造に関する解説書はあちこちで見かけるようになりましたが、「どのような仕組みでカーネルが出来上がるのか?」という疑問に答えてくれる資料は、残念ながら見あたらないようです。幸い、私達はこれまでの連載を通じてGNU開発ツールに関する基本知識は十分身に付けていますので、Linux カーネル構築を解析していく作業はそれほど難しいものではありません。

初回は、カーネル起動シーケンスの概略、Linux カーネルソースツリーの全体像、vmlinux, bzImage の内部構造について解説します。この中で大事な点は、「Linux カーネルの実体は vmlinux である」ということ、そして「Linux の起動とは、物理アドレス 0x100000 以降に展開された vmlinux バイナリーイメージの先頭にジャンプすること」、この2点です。私達が普段お世話になっている bzImage はあまりに複雑であり、全てを理解することは大変困難です。まずは vmlinux に注目し、カーネルの実体を把握することが Linux 理解への早道でしょう。(編集担当 渡辺氏)

早いもので、本連載も無事6回を迎えることができました。これもひとえに読者の皆さんからのご支持のおかげだと感謝しております。連載を始めるにあたり、「はたしてこのような内容で受け入れられるだろか?」と随分心配していたのですが、杞憂に過ぎなかったようです。今後も本連載でしか読めないような、読み応えのある記事の執筆を心がけていきますので、ご支援よろしくお願い致します。

訂正一覧

  1. p105 実行例2 9行目 Makedile --> Makefile
  2. p111 図2 タイトル b2Image --> bzImage
  3. p112 図3 タイトル Makedile --> Makefile
  4. p112 図3 kevrnel/Makefile --> kernel/Makefile, vmlinuk.lds --> vmlinux.lds

2002年4月号 GCCプログラミング工房 第5回 モジュールによるカーネル圏内突入 p121-130

今回はこれまでに身につけた知識を実践の場で確認します。テーマはモジュールとカーネルの接点です。カーネルモジュールは今や Linux になくてはならない存在ですが、なぜ単純なオブジェクトファイルがカーネル内部の変数や関数にアクセスできるのか、その仕組みは意外と知られていません。Linux カーネルソースツリーを探索しながら、その謎を解明します。今月号を読んで頂ければ、なぜセクションの説明に3カ月分ものページを割いてきたのか、その理由を理解して頂けるのではないかと思います。(編集担当 渡辺氏)

さて、第6回はいよいよ Linux カーネルに迫ります。「Linux ソースツリーで一番おいしいところはどこだ?」と尋ねられれば、私は迷わず「それは Makefile とリンカースクリプトだ」と答えます。Cソースよりも、むしろこれらのファイルの中に、GNU開発ツールを用いて巧妙なシステムプログラムを構築するためのノウハウが凝縮されているからです。これまでにはない当連載独自の味付けで Linux カーネルを解析した上で、世界的カーネルハッカー達が編み出したその妙技を紹介する予定です。お楽しみに!

訂正一覧

  1. p121 左カラム上段付近 「天上」へ開けて --> 「天上」へ向けて
  2. p124 リスト2 誤植ではありませんが4行目は次の行へ連続していますので注意してください。
  3. p127 リスト5 3行目 #str --> #sym
  4. p129〜p130多数 donar --> donor 単純なスペルミスです、お恥ずかしい限り・・(滝汗)。ソースは修正しました。
  5. p130 今月の GNU TIPS モジュールの作成において、3つのパターン全てに -O2 が抜けています。以前説明した通り、最適化を行わないとインライン展開が行われませんので、コンパイルエラーが発生します。うっかり忘れてしまいました、申し訳ありません。

リファレンスリスト

cpp info ファイル PDF (368KB)

binutils ソースツリー上に含まれている cpp の info ファイルを PDF 化したものです(英文)。# と ## オペレーターの説明はこの中にあります。記事中では紹介できなかったのですが、3.5 章で使われているソースは両者を見事に使いこなしています。テクニックのひとつとして是非覚えておきましょう。

記事中ソースリスト tgz ファイル

記事中で使用したソースファイル集です。


2002年3月号 GCCプログラミング工房 第4回 セクション配置のからくり p109-120

今回はこれまで培ってきた知識を最大限に生かしながらセクション配置の免許皆伝を目指します。Cソース中には外部変数、静的変数、自動変数など様々なタイプの変数が存在しています。普段は、これらの違いについてあまり意識することはありませんが、実行コードをROM化するような場合は、変数と実行コードの配置を完全に把握・制御する必要があります。これを可能にするのが、リンカースクリプトです。

gcc プログラマーの人口はそれこそ数え切れぬほどの数でしょうが、リンカースクリプトをプログラムできる人間は非常に限られているようです。これまではリンカー、コンパイラー、ライブラリーの作成に関わる「スペシャリスト」だけが、知っていれば良いという風潮だったためです。

しかし、私はそうは思いません。リンカースクリプトは実行プログラムの「本質」を理解するために、必須の知識です。ここを目隠しして過ぎ去る訳にはいきません。私の経験からすれば、いざという時に我が身を助けてくれるのは、修得するのは大変だけれどもその実骨のある、本物の知識だけです。100の表層的な知識を身につけたところで、それは何の役にも立たないことを身をもって経験してきました。

今月は第1回から3回までの総集編とも言える内容になっており、これまで紹介したテクニックや知識が再三登場します。あやふやな点があれば、是非ともバックナンバーを読み返して再確認してください。そして、実際に自分の手でコーディング・ビルドを行い、その挙動を目で確かめてください。この作業を繰り返していけば、必ずや新しい知識と技術はあなたの血と肉になることでしょう。(編集担当 渡辺氏)

さて、次回のテーマはカーネルモジュール。これまでのユーザープロセス空間から一気にカーネル空間へとワープします。カーネルモジュールは今や Linux になくてはならない存在ですが、なぜ単純なオブジェクトファイルがカーネル内部の変数や関数にアクセスできるのか、その仕組みは意外と知られていません。Linux カーネルソースツリーを探索しながら、その謎を解明します。いわゆるカーネルハッキングですね。お楽しみに!

訂正

  1. p112 左カラム中段付近 voicl --> void

リファレンスリスト

記事中ソースリスト tgz ファイル

記事中で使用したソースファイル、リンカースクリプト、および NetBSD から拝借した a.out ヘッダーファイルです。


2002年2月号 GCCプログラミング工房 第3回 バイナリを操るリンカースクリプトの正体 p113-122

いよいよ影の千両役者、リンカースクリプトの登場です。前半部分ではかなりの分量を割いて、リンクの理解に必要不可欠なシンボルの概念をアセンブラの観点から解説しています。本連載を通じて一人でも多くの方に、アセンブリプログラミングへの興味をもって頂ければ幸いです。後半では一昔前まで一般的に利用されていた a.out フォーマットの実行ファイルを作成します。ELF はあまりに複雑であり、最初の学習材料には向かないと考えたからです。最後に示した a.out モジュールの組み込み方法は番外編スペシャルサービス。この中で、私自身がこれまで悩まされてきたカーネルハッキングの際に陥りやすいピットフォールの全てを紹介しています。(編集担当 渡辺氏)

訂正一覧

  1. p114 「いにしえのアセンブラ」ちなみにその当時は・・と前の段落のつながりがありません。私の校正ミスで、"a.out はAssembler OUtput の略でしたね。" の後ろにあった以下の段落が抜けてしまいました。

    現在では実行ファイルのデフォルト名も a.out になっていますが、本来は "assembler and linker output (al.out ?)" と表現すべきでしょう。未だに a.out がデフォルト名として使われているのは、まだリンカーが存在しなかった時代のアセンブラーが直接実行可能ファイルを生成していた名残なのです。

  2. p119 実行例6 これはOMAGIC形式のリンカースクリプトではありません。OMAGICのスクリプトを表示させるためには ld -m i386linux -N --verbose を指定します。

リファレンスリスト

as info ファイル PDF (1MB)

binutils ソースツリー上に含まれている as の info ファイルを PDF 化したものです(英文)。

ld info ファイル PDF (500KB) binutils ソースツリー上に含まれている ld の info ファイルを PDF 化したものです。英文ですが必読
記事中ソースリスト tgz ファイル

記事中で使用したソースファイル、および a.out 用のリンカースクリプトファイル i386linux.xbn です。もしもお使いのシステム中に OMAGIC 用のリンカースクリプトが用意されていない場合は、このファイルを用いて実行例7は ld -T i386linux.xbn -N -o hello-aout a.out としてください。


GCCプログラミング工房 号外 No.1 「ELF関連文書一覧」

本サイトのアクセス動向を見ていると、かなりの方がELF仕様書をダウンロードされています。それだけ、ELFに対する興味は深いのだと思いますが、残念ながらこの文書を読むだけではその全体像は見えてきません。あくまでも「仕様書」に過ぎないからです。ELFに関する情報は需要の割には不足しており、世界を見渡しても数えるほどしかありません。この号外ではその貴重な情報源を紹介しておきます(全て英文)。Linux Documentation Project の HOWTO 集にもELFを扱った文書はありますが、情報源としての価値は希薄です。

GCCプログラミング工房でも述べた通り、出来れば仕様書に従い簡単なダンプツールを組んでみることをお勧めします。ファイルフォーマットについてはこの方法で理解できますが、問題はライブラリーがどのような仕組みで実装されているかです。しかし、正直これはかなり難しい・・。共有ライブラリーを理解するためには、ELFだけでなく共有メモリーなど UNIX 環境でのメモリー資源の取り扱いまで詳細に把握する必要があるからです(実は、ここが一番面白いところでもあるのですが)。

GCCプログラミング工房では、まず静的にリンクされた実行可能ファイルを徹底理解するところからスタートします。静的リンクを理解できずして、ダイナミックリンクには到達できないからです。第3回ではいよいよリンカースクリプトが登場します。少しだけ種明かしをしますと、次号ではa.outフォーマットが登場します。ELFは最新のバイナリーフォーマットであり、入門者の教材としては少々荷が重すぎます。こんな時は、歴史をひもといて先人が歩んだ道を辿り直すのがベストだと私は考えています。物事を単純化することで、視界は随分開けるからです。若干遠回りになるかもしれませんが、ライブラリーの謎を解く日は、そう遠いことではないと思いますよ。どうか、お楽しみに!

ELF関連文書一覧

ELF 仕様書 (PDF 149KB) ELF フォーマット標準仕様書
プログラマーの立場から解説したELF (PDF 187KB) これを読めば crt ファイル群の意義がわかります。ダイナミックリンクのコーディング例も紹介されています。
System V Application Binary Interface (ABI) 仕様書

Caldera のサイト中に用意されている System V 関連文書集。X86 CPU 向けのELF に関する仕様は "Intel386 Architecture Processor Supplement Fourth Edition" を参照してください。

Linux Standard Base (LSB) 仕様書

LSB は乱立する Linux ディストリビューションに危機感を覚えた企業群が Linux の仕様を標準化するために共同して設置したプロジェクトです。オブジェクトファイルフォーマット、ライブラリー、システム管理ツール、パッケージ管理方法、シェル、など細部にわたり標準仕様の策定を行っている最中。しかし、その内容はまだ穴だらけで、仕様書の体をなしていません。参考資料のひとつとしては、使えるでしょう。

Linkers and Loaders Levine 氏による "Linkers and Loaders" のオンライン公開本。同書籍の和訳本が最近発売されたので、ご存じの方も多いでしょう。内容はELFやCOFFにとどまらず、様々なバイナリーフォーマットに言及していますが、「広く浅く」という感じは否めません。リンクの歴史と変遷について勉強するには最適ですが、各フォーマットの詳細を調べるには残念ながら役不足。現時点におけるリンク・ロードに関する唯一の参考書籍です。

2002年1月号 ブートシェルGRUBをマスターしよう! p64-73

Red Hat Linux 7.2 から正式採用された今話題のブートローダーGRUB の特別企画です。ただのインストール記事に終わることがないよう、構成に工夫を凝らしました。また、なぜ*_stage1_5 ファイルが必要になるのか、GRUB の動作機構についても考察を加えています。記事中でも触れた blocklist コマンドは是非とも試してみてください。ファイルシステムに対する理解が一気に深まること請け合いです!(編集担当 渡辺氏)

訂正一覧

  1. 冒頭で奥地氏の GRUB サポートページを紹介しましたが、このページは削除されたようです。現在、同氏は新しいサイトを構築中ですが、このサイトからは GNU GRUB 公式ページしかアクセスできません。奥地氏の日本語サポートページは読み物としても面白かったのですが・・。ちなみにこの新サイトのリンク集は一見の価値あり!
  2. p65 図1 /boot/grub/munu.lst --> /boot/grub/menu.lst
  3. p68 図2 HDD 残り31744B未使用 --> 残り22016B未使用
  4. p71 右段 Linux の圧縮カーネルイメージ(vmlinuz) --> (vmlinuz, zImage, bzImage)

リファレンスリスト

GRUB info ファイル PDF (468KB) ソースツリー上に含まれている GRUB の info ファイルを PDF 化したものです(英文)。
ブートとハードディスクのすべて

高安延匡氏によるブート解説サイト
ブートやパーティションに関する情報を求めるなら、世界広しと言えどもこのサイトしかありません。母国語で読めることを感謝しましょう。


ファイルシステム版レスキューディスクの作成方法については、今しばらくお待ちください。

2002年1月号 GCCプログラミング工房 第2回 glibcからの独立 p115-124

連載2回目にして、なかなか挑戦的なタイトル。今回はまずシステムコールについての説明から始めます。私は以前、低レベル入出力関数はシステムコールを直接実行しているものだとばかり思っていました。ところが、詳しく調べてみるとその実体はCライブラリー関数に他ならないことに気づき大ショック。「これじゃ、お釈迦様の手のひらの上をいい気になって飛び回っていた孫悟空と変わらんではないか〜〜!」と雄叫びをあげることしきり。今回、その雪辱を誌上で果たすことができたでしょうか?後半では、strip コマンドと dd コマンドまで担ぎ出しながら、バイト単位でのサイズ圧縮に血道を上げます。「なんか勘違いしてない?」という声も聞こえてきそうですが、完成した211バイトの Hello, world! はなかなかの傑作です。本当はGCCの拡張アセンブラ機能の詳細も紹介したかったんですが、ページ数が足りなくなってしまいました。連載を始めて分かったのですが、8ページもしくは10ページに内容をおさめるのは本当に難しい。初回の頃は分量がつかめず、割り当て8ページのところが特大ホームラン20ページ超になってしまいました(今でもそれに近かったりする・・)。担当の渡辺氏にはいつも締め切り間際まで削り込み作業にお付き合い頂いております、深謝。さて次回は、いよいよプログラム最後の味付けとも言える「リンカースクリプト」が登場します。乞うご期待!(編集担当 渡辺氏)

訂正一覧

  1. p120 右カラム 8行目 .-R --> -R (ドットが余分です)
  2. p121 図2 3行目 FC 00 00 00 の次の4バイトが2バイトずつに区切られていますが、これは1ワード(4バイト)単位です。このデータは表2の e_flags に相当します。
  3. p124 「次回は」この上なし愉快 --> 愉快この上なし
  4. p124 GNU TIPS 2行目の dd オプション if= --> of= 出力ファイルの指定

リファレンスリスト

ELF オリジナルダンプユーティリティー elfdump ソース ELFのダンプユーティリティーとして readelf がありますが、このプログラムは解読するには巨大すぎます。そこで、ELF仕様書をもとに独自の小型ダンプユーティリティーを作ってみました。ELFのファイル構造を追うには最適の教材です。
ELF オリジナルダンプユーティリティー elfdump screen shot その実行例。
ELF 仕様書 (PDF 149KB) ELF フォーマット解説書のスタンダード(英文)

2001年12月号 GCCプログラミング工房 第1回 コードサイズの謎 p131-138

記念すべき初連載第一回。今や PC-UNIX 界では「猫も杓子も gcc 」という感がありますが、果たしてどれだけのプログラマーが「gcc を使いこなしている」と言えるでしょうか?gcc が持つ潜在能力を最大限に引き出すためには、binutils のサポートが不可欠ですし、実行ファイルフォーマットELFに関する知識も必要になります。本連載は従来のCコンパイラー解説本の枠を超え、周辺ツールとの連携やELFの内部構造、はてはリンカースクリプトやアセンブラーまで取り上げながら、GNU 開発環境解説書の決定版を目指します。第一回目のタイトルは「コードサイズの謎」。ありきたりの Hello world を題材にして、なぜこれほど単純なプログラムのサイズが 4000 バイトを超えるのか、その謎に迫ります。(編集担当 渡辺氏)

訂正一覧

  1. p131 図1 ldd リンカー --> 依存ライブラリー表示
  2. p134 図2 ファイル内配置:プログラムヘッダーの記述 セクション数 --> セグメント数
  3. p137 「_start の正体」 実行例2 --> 実行例1
  4. p138 GNU TIPS gcc -o --> -c
  5.     同上  gcc -o 出力ファイル名を指定

リファレンスリスト

gcc ホームページ  
gcc スナップショット  
binutils ホームページ  
gcc 3.x info マニュアル (PDF 2.8MB)

"Extensions to the C Language Family" の章は必読、ただし英文

binutils info マニュアル (PDF 312KB) 英文
ELF 仕様書 (PDF 149KB) ELF フォーマット解説書のスタンダード(英文)
プログラマーの立場から解説したELF (PDF 187KB) これを読めば crt ファイル群の意義がわかる(英文)

2001年7月号 Linux カーネル2.4 におけるNAT とパケットフィルタ

Linux カーネル 2.4 の最大の目玉のひとつである Netfilter framework/iptables についての解説記事です。Netfilter が公開されてすでに久しいですが、相変わらず ipchains wrapper を利用しているユーザーが多いのは、やはり「使い方がよくわからない」からでしょう。これは Netfilter project が公開している技術文書に問題があると私は考えています。本記事では、一部のテクニカルタームの再定義まで行い私流に解説してみました(誌面に限りがあるため、言いたかったことの1/3位しか表現できていないのが心残りですが)。私の商業誌初出作品です。(編集担当 渡辺氏)

訂正

文中で「非モジュール形式でカーネルをコンパイルするとエラーになる」と大嘘を書いてしまいました。実は Netfilter をハッキングしていた際に、初期化関数のアドレスをグローバル化するために static を除去したところ、多重定義エラーが発生したため(数多くの初期化関数の中でなぜか Netfilter だけ・・)、やむなく関数名を変更したことがあります。この記憶を「パッチをあてた」と拡大解釈していたため、あのような大それた記述になったわけです。読者の皆様、申し訳ありませんでした。

ということで、お詫びの一文と共に記事中で述べることの出来なかった Netfilter コンパイル方法および各モジュールの解説を本サイト上で加筆しました。本文と併せてお読みください。
Your SysOp is Wataru Nishida , M.D., Ph.D.