序 文
ディジタル家電や携帯電話など，組み込みシステムの複雑化にともない，組み込み機器用の次世代 OS として，Linux に対する興味が高まってきている．これからの組み込みシステムはインターネット接続が標準となり，無線ネットワークや電源ネットワークを介してお互いに通信可能となると考えられる．それにより個々に稼動していた各種のサービスが統合され，従来とくらべてはるかに高度な機能を提供する可能性が期待される．あらゆる機器接続の実現を考えた場合，複雑なシステムを構築するためには Linux のような高度な基盤 OS が不可欠となってきていている．
組み込み Linux が注目を集めている理由として，以下の 4 点を考えることができる．
第 1 は，Linux がファイルシステムやネットワークシステムをはじめからコンポーネントとして含んでいることである．従来のリアルタイム OS（以下 RTOS）の多くは，ファイルシステムやネットワークシステムをミドルウェアとして提供しており，原則として開発者は開発システムに適したファイルシステムやネットワークシステムを選択できる．
しかし実際には，これらのソフトウェアを開発システムの特性に応じて変更することはたいへん困難なため，RTOS ベンダから提供されるものをそのまま利用しているのが現状である．この現状をふまえると，ファイルシステムやネットワークシステムをミドルウェアとして提供する従来の RTOS に対し，それらを標準でサポートしている Linux のほうが，一貫したシステムを構成しやすい．
第 2 には，Linux のカーネルインターフェースが，UNIX をベースにした国際標準のカーネルインターフェースである POSIX に準拠していることである．POSIX は世界的にもっとも普及しているカーネルインターフェースであり，POSIX に基づく多くの研究・教育が存在し，多くの書籍や刊行物も出版されている．このため，POSIX インターフェースをマスタしているプログラマが世界中に多数存在する．開発コス
ト削減が大きな課題である現在，組み込みシステムで POSIX に基づくOS を用いることは，教育コストの削減やグローバルな開発体制を容易に実現可能という点で，たいへん魅力的である．

4

第 3 には，Linux がオープンソースアプローチという方式により開発されていることである．設計図にあたるソースコードが公開されているため，開発者が世界中の地理的に離れた場所に点在していても事実上共同開発が可能となる．この方式では 1 人のコーディネータが他の開発者から提示された変更をチェックし，変更が好ましい場合はマスターソースコードに変更を追加する．開発されたソフトウェアは無償で入手可能であり，興味がある人ならば誰でもテストできる．テスト結果はコーディネータにフィードバックされ，さらに誰かほかの開発者により改良されていく．潜在的に多数のプログラマがテストやバグの修正を行うため，従来に比べてすばやく安定したソフトウェアの構築が可能となる．一般に基盤ソフトウェアは開発にコストがかかるわりには利益が少なく，従来は少数の機関で基盤ソフトウェアを開発していたため莫大な開発費が必要だった．一方，オープンソースアプロー
チでは，前述したように異なる組織に属する多くのプログラマが無償でソフトウェア開発を行う部分が多い．オープンソースアプローチの利用により，ほかの人が開発したソフトウェアの利用に対価を要求することは難しくなるが，開発コストの削減がもっとも重要な項目である場合は，きわめて好ましいアプローチといえる．
第 4 には，Linux 上には多くのライブラリやミドルウェアが存在し，それらのインターフェースがデファクトスタンダードとなっているた
め，移植性の高いアプリケーションやミドルウェアを構築することが可能である．たとえば，マルチメディア処理のためのインターフェー
スや GUI のためのインターフェース，それらに基づいたディジタルテレビ用のインターフェースなど，さまざまな標準インターフェースが提供され，それらのインターフェースを用いたアプリケーションやインターフェースの明細を記述したドキュメントも完備されつつある．
また，世界中のオープンコミュニティにサポートされているため，時代に応じた新しいテクノロジが導入される可能性が高い．
以上の理由により，組み込み Linux は今後複雑化する組み込みシステ
ムを支える OS として最適な OS であり，将来の組み込みシステムを大きく飛躍させる可能性をもっているということができる．

中島 達夫

早稲田大学 理工学部 情報学科 教授

5

第1部

第技術解説編

1章
Linux を使った組み込みシステム開発
木内 志朗

本章では，組み込みシステムを開発するとき，Linux を採用することで何が変わるのかを明らかにする．スケジューリングの実行単位やデバイスドライバ，リアルタイム性，メモリサイズ，開発手順/開発環境，オープンソースの考え方などについて，Linux を使った場合と一般的なリアルタイム OS を使った場合でどう異なるのかを解説する．
(編集部)

はじめに組み込みシステムの開発パラダイムが大きく変わろうとしています．20 年以上前に，商用のリアルタイム OS（以下 RTOS）が登場して以来，組み込みシステ
ムでは，さまざまな RTOS が使われてきました．そして現在，この組み込みシステム向け OS の選択肢として，Linux が注目されています．

できるわけです．

1 Linux について
1.1

概要Linux は，マルチタスク，仮想メモリ，共有ライブ
ラリ，デマンドローディング，メモリ管理，TCP/IP

Linux は，もともとデスクトップ環境向けに開発さネットワーク機能などを含んだ UNIX クローンの OSれたため，ハードディスク上で動作し，コンソールやです．1991 年に Linus Torvalds 氏により Linux の原ディスプレイなどをもったシステム構成だと思われが型が開発されてからすでに 10 年以上にわたり，修正/ちですが，カーネルやシステムの構成により，ファイ拡張が続けられています．現在（本稿執筆時点）のルシステムを ROM/RAM 上に構築した「ディスクレLinux の最新バージョンは安定版が 2.4.20，開発版がスシステム」や，login コンソールなどを必要としな2.5.59 であり，http://www.kernel.org/からダウい「ヘッドレスシステム」としても使用できます．つンロードができます（図 1）．

まり，組み込みシステムの OS として使用することが現在，このカーネルツリーで正式にサポートされている CPU アーキテクチャには，x86，Alpha，SPARC，〔図 1〕Linux 最新バージョンのダウンロードサイト

68K，PowerPC，PowerPC64，ARM，SH，S/390，
MIPS，PA-RISC，IA-64，VAX，AMD x86-64，CRISなどがあり，他の OS とは比べものにならないほど豊富な CPU をサポートしています．また，アーキテクチャに依存するコードと共通部分が分かれているため，他のアーキテクチャへの移植も比較的容易にできます．

1.2

組み込み Linux の動向

日本のサーバ環境としては，Linux が現在約 35.5%の普及率（日本 Linux 協会のデータによる）ですが，組み込みシステム分野においては，これから急速に伸び

6

第1章〔表 1〕ワールドワイドでのアプリケーション別の組み込みLinux 出荷予測

Linux を使った組み込みシステム開発〔図 2〕ワールドワイドにおける組み込み Linux，ソフトウ
ェア，開発ツール，サービスの市場規模

2000 年

2005 年

20002001

2002

テレコム/データコム

13.2

126.7

金額（百万$） 28.2

55.2

89.8 140.5

コンシューマエレクトロニクス

8.9

121.1

FA

1.4

14.2（百万ドル）
350

1

8.7300分

野リテイルオートメーション

年

OA

0.9

6.6

250

軍事/航空

0.9

9.4

200

自動車（情報系）

0.7

7.4

150

ストレージ/サーバ

0.6

6.6

100

医療

0.4

4.050

※単位：百万※ツール，サービスなどは除く

2003

2004

2005

213.3 306.6

306.6
213.3
140.5
89.8

28.2

55.2

0（年）
2000 2001 2002 2003 2004 2005

出典：VDC（Linux's Future in the Embedded Systems Market, May 2001）

出典：VDC（Linux's Future in the Embedded Systems Market, May 2001）ていくと思われます．

●ロイヤリティフリー

2000 年は，「組み込み Linux 元年」とでもいうべき

商用 RTOS のほとんどは，搭載製品に対してロイ年で，各メーカーが製品化への検討や試作を始めましヤリティが発生します．また，自社製の RTOS を使た．現在では，Linux を評価する段階はある程度終わ用していても，ネットワークやファイルシステムなどり，実際に製品搭載に向けた開発が数多く行われていは自作できず，結局はロイヤリティがかかるソフトウます．2002 年の前半には，いくつかの製品が市場にェアコンポーネントを購入することすらあります．こ出てきました．のロイヤリティは，直接製品の価格に影響してくるの

現在，組み込み Linux を採用，あるいは採用を検討で，Linux のようなロイヤリティフリーでファイルシしている製品として，通信機器，通信インフラといっステムやネットワーク機能をサポートしている OS はたテレコム/データコム分野と，携帯電話，PDA，デ魅力です．

ィジタル TV などをはじめとするディジタルコンシュ●デバイスドライバが豊富

ーマ機器の二つの分野への採用が急速に伸びています（表 1）．など豊富なデバイスドライバがすでに開発されていま

米国の VDC のデータによれば，現在 55 百万ドルの組み込み Linux やサービス市場が，2005 年には 6 倍の306.6 百万ドルに成長するという予測もされています（図 2）．

す．
●ネットワークプロトコルスタックやミドルウェアが豊富
Linux では，デスクトップ環境で培われた豊富なでは，なぜ今，組み込み Linux が急速に普及しているのでしょうか？

シリアル，イーサネットをはじめ USB，IEEE1394

組み込み Linux を選択する理由としては，次のような点があげられます．
●ソースが入手可能

GUI，Java やプロトコルなどが，オープンソースコミ
ュニティから入手可能です．
●安定している安定という面では，すでにサーバでの実績がありまLinux の場合，完全にオープンソースであるため，す．また，強力なメモリ保護機能により，一つのプロ問題の切り分けが容易であり，他の RTOS に比べイセスが問題を起こしてもシステム全体への影響を最小

ンターネットや書籍などから多くの情報を容易に入手限にできます．

できます．また，商用 RTOS の場合，海外に本拠地その反面，組み込み Linux については，それほど情をもっているベンダが多く，会社の合併やサポート体報が豊富ではないため，次のような点で採用に不安感制の問題などが生じた場合，いざとなれば自分達でメをもっている開発者も多いのではないかと思います．

ンテナンスしていくことができるというオープンソー

Linux の知識をもった組み込みシステムのエンジニスの安心感のために，Linux を採用している企業もあアの不足るようです．

組み込み Linux についての情報不足

7

第1部

第1部

技術解説編

〔図 3〕
RTOS におけるタスクのイメージ〔図 5〕Linux のプロセスの状態遷移
システム
RTOSカーネル

生成
シグナル

停止状態

シグナル

タスク
タスク

実行可能状態

スケジューリング

実行状態

終了

ゾンビ状態

タスク
入出力

停止状態

入出力

物理アドレス空間〔図 4〕Linux におけるスレッドのイメージ

ドレスと論理アドレスが同一のフラットなメモリ空間
システム

で動作します．RTOS におけるタスクはメモリ空間をLinuxカーネル共有しており，タスクごとのメモリ保護などは行われプロセス

プロセスていないのが一般的です（図 3）．ただし，プロセスモ

スレッド

スレッド

デルを採用している RTOS も存在しています．

スレッド

スレッド

スレッド

スレッド

論理アドレス空間

論理アドレス空間
物理アドレス空間

一方，Linux ではプロセスという単位でスケジューリングが行われます．プロセスはそれぞれ独立した仮想メモリ空間をもっています．それぞれのプロセスのメモリ空間は独立しており，他のプロセスのメモリ空間にアクセスすることはできません．Linux のカーネ
ル自体もプロセスと独立したカーネル空間で動作しており，プロセスからカーネルの資源にアクセスするこメモリサイズとはできません．

リアルタイム性

また，Linux は POSIX のスレッド（pthread）もサポ開発ツールの不足ートしています．スレッドは，プロセスの中に存在すライセンス問題る最小の処理単位であり，一つのプロセス内でスケジそれぞれの点について，次項より詳しく説明していューリングされます．ただし，Linux のスレッドの実きます．

装では，メモリ空間を共有したプロセスとして実装されており，スケジューラなどはプロセスと同様に同一RTOS との比較による
2 Linuxの解説のスケジューラでスケジューリングされています．ス
レッドはメモリ空間を共有しているため，スレッド間組み込みシステムの開発者で，かつ Linux に精通しで共有するリソースへアクセスする場合，RTOS と同ている技術者は多くありません．そのために，導入を様にセマフォなどによる排他制御が必要となります．

ためらっている開発者が非常に多いのが実情のようで

アプリケーションプログラムから見ると，Linux のスす．

レッドは RTOS でのタスクに似ているといえるかも

ここでは ITRON や商用 RTOS と組み込み Linux をいくつかの点で比べてみることにより，組み込み OSとしての Linux を説明していきます．

2.1 RTOSタスクとLinuxプロセス/スレッドの違いしれません（図 4）．
Linux のプロセスの状態遷移を，図 5 に示します．
一般的な RTOS とそれほど違わないことがわかると思います．
簡単なプロセスとスレッドのプログラム例を示しま多くの RTOS では，「タスク」がカーネルによってす．リスト 1 では，プロセスの生成を行っています．

スケジューリングされる実行単位です．CPU の MMU

次に，同様の処理をスレッドで行った例をリスト 2 に（Memory Management Unit）を使用せずに，物理ア示します．

8

第1章〔リスト 1〕プロセスの生成Linux を使った組み込みシステム開発〔リスト 2〕リスト 1 と同様の処理をスレッドで行う/* プロセスの生成 *//* スレッドの生成 */#include <sysy/types.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <pthread.h>#include <unistd.h>main(){
pid_t new_PID;
int status;
new_PID = fork();switch (new_PID) {case 0 :/* 子プロセスの処理はここから始まります */printf("I am the child!!¥n");sleep(2);exit(1);break;
case -1 :/* 何かエラーが発生しました */exit(errno);
break;
default :/* 親プロセスの処理の続きです */printf("I am the parent! my child's
PID is %d¥n", new_PID);/* 子プロセスが終了するのを待ちます */wait(&status);
break;}
exit(0);
}

2.2

メモリ管理

void *thread_function(void *arg);main(){
int res;pthread_t new_TID;
void *thread_result;/* スレッドを生成します */res = pthread_create(&new_TID, NULL,thread_function, NULL);
if (res != 0)
exit(EXIT_FAILURE);/* 子スレッドの終了を待ちます */res = pthread_join(new_TID, &thread_result);
if (res != 0)
exit(EXIT_FAILURE);
exit(0);}/* 生成されたスレッド */void *thread_function(void *arg){
printf("I am New thread! -thread_function()¥n");sleep(3);/* スレッドを終了します */pthread_exit("Bye!");}プロセスのところでも説明しましたが，メモリモデ
ルがフラットな RTOS と異なり，Linux は MMU を使段がシステムコールによってサポートされています．

用してメモリ管理をしています．ユーザープロセスにRTOS では，排他制御や同期手段としてセマフォがはそれぞれ仮想メモリ空間を割り当て，カーネル自体使用されますが，Linux も当然のことながらセマフォはカーネル空間で動作します．Linux のメモリ空間は，をサポートしています．mutex や状態変数について4K バイト（サイズが異なるアーキテクチャもある）ごも，もともと UNIX や POSIX でもっているものなのとのページで管理されています．

で，Linux は当然サポートしています．タスク間の通カーネル空間は，カーネルの初期設定時にマッピン

信手段としてはメッセージキューやメールボックスをグされると，その後変更されることはありませんが，使用しますが，Linux ではパイプといった処理で実現プロセスに割り当てたユーザー空間は，このページ単可能です．また，イベントフラグにしても，Linux の位で連続したメモリに割り当てられるともかぎらず，シグナル処理で同等の機能をもたせることが可能でディスク上にスワップされることもあります．しかし，す．まとめると表 2 のようになります．

このページング機構のおかげでシステム全体のメモリを効率よく使用することができます．

2.3

タスク，プロセス間の同期/通信手段

2.4

デバイスドライバ

ITRON などの場合，デバイスドライバという標準的な API（アプリケーションインターフェース）が現在RTOS を使用したマルチタスクシステムの場合，タのところないため，明確にデバイスドライバとタスクスク間の同期を行う際，カーネルにより同期，通信なという分け方をしていない実装も大半を占めているよ

どのシステムコールが用意されています．Linux におうです．VxWorks や pSOS+ といった商用 RTOS では，いても，同様のプロセス/スレッド間での同期/通信手それぞれデバイスドライバの API をもっており，元9

第1部

技術解説編

〔表 2〕
RTOS，Linux の同期/通信手段の比較

RTOS 同期/通信Linux 同期/通信セマフォ（バイナリ/カウンティング）

SVR4 セマフォ

mutex

POSIX mutex，状態変数共有メモリ

共有メモリ

メッセージキュー/メールボックス

パイプ/FIFO，SVR４キュー

イベントフラグ

シグナル

タイマ

POSIX タイマ/アラーム，sleep()/usleep()となる考え方が UNIX 系に近いものなので，比較的Linux の割り込み処理は，トップハーフとボトムハLinux のデバイスドライバについてもイメージしやすーフ（Linux 2.4 では，タスクレットやソフト IRQ）のいと思います．しかし，実際には ITRON や他の商用二つの構造に分けることができます．たとえばトップRTOS いずれの場合もタスク内の処理で直接 I/O へのハーフでは，デバイスからデータを取り組むだけといアクセスを行っている例が多いようです．周期的にったリアルタイム性が厳しい処理を行い，その後，ボI/O ポートを監視する，あるいはデータ入出力を行う

トムハーフ処理でそのデータを処理するなどといったといった処理をすべてタスクが直接行っています．

実装がされます．データの処理が終わるとボトムハー

一方，Linux の場合，基本的にプロセスから直接ハフ処理は，wake_up_interruptible()システムコードウェアへのアクセスはできません．Linux の場合，ールなどにより，スリープしているプロセス〔具体的I/O などのデバイスをアクセスする際には，デバイスには Dev_Read()〕を起床させます．

ドライバで行う必要があります．Linux のデバイスドソースで見ると，リスト 3 のようになります．特定ライバの構造は，図 6 のようになります．プロセスがのデバイス用ではなく，何もしない架空のキャラクタwrite()システムコールを発行すると，カーネル空デバイスドライバです．コメントを読んでいただけれ間に移り，登録されているデバイスドライバの読み込

ば，デバイスドライバの構造がイメージできると思い

み処理〔Dev_Read()〕を実行します．

ます．デバイスドライバといっても，それほど複雑なDev_Read()では，デバイスからのデータを読み込むのですが，この図では，割り込みハンドラがデータを取り込むまで，interruptible_sleep_on()シものではないことがわかります．

2.5

スケジューリングステムコールによりスリープします．ハードウェアかほとんどの RTOS では，タスクごとの優先順位ベらの割り込みが発生し，割り込みハンドラが実行されースのスケジューリングが行われています．つまり，ます．

各タスクがそれぞれ優先順位をもっており，優先順位が高いタスクが常に実行されます．
これに対して，Linux のスケジューリングはタイム〔図 6〕Linux のデバイスドライバの構造シェアリングをベースにしており，各プロセスに対しデバイスドライバて平等に CPU 時間を割り当てるようにスケジューリ

Dev_read(...).
.

ングされています．
Linux の基準時間（Tick）はデフォルトで 10ms なのですが，この Tick の倍数でしかスケジューリングさプロセス.
.
.
read(...).
.
.

割り込み待ちinterruptible_sleep_on().
.
.
割り込みハンドラf.
（トップハーフ）
.
.
.

done

ボトムハーフタスクレット
wake_up_interruptible()

れないと勘違いしている人も多いようです．Linux のIRQ!

スケジューリングされるタイミングは，割り込みハン
ドラ終了時，システムコール終了時とアイドル時です．
したがって，Tick 刻みでスケジューリングされるプロセスもあれば，非同期に発生する割り込み終了後や，システムコール終了後にスケジューリングされるプロセスもあります．
ただし，Linux カーネルはプリエンプティブなカー
ネルではないので，割り込みハンドラ終了時には必ず10

第1章

Linux を使った組み込みシステム開発〔リスト 3〕キャラクタデバイスドライバのコード例/* サンプル キャラクタ デバイスドライバ （Linux Kernel Version 2.4 以降）*/#if defined(CONFIG_MODVERSIONS)#define
MODVERSIONS#include <linux/modversions.h>#endif#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/tqueue.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <asm/uaccess.h>#define MYDRIVER_MAJOR 240#define MYDRIVER_NAME "Test Driver"/* デバイスメジャー番号 *//* デバイス名 */DECLARE_WAIT_QUEUE_HEAD(mydriver_zz);/* interruptible_sleep_on() 用のキュー *//*********************************************************************** ＜割り込みハンドラ（トップハーフ）＞*/
void mydriver_interrupt(int irq, void *dev_id, struct pt_regs *fp){/* デバイスからデータを取り込みます *//* 割り込みの後処理としてタスクレットの実行フラグをセットします． */tasklet_init(&mydriver_tasklet, mydriver_task, (unsigned long)dev_id);tasklet_schedule(&mydriver_tasklet);return;}/*********************************************************************** ＜割り込み後処理（タスクレット）＞*/
void mydriver_task(unsigned long data){/* 割り込みハンドラが取り込んだデータを加工したりします． *//* スリープしている プロセスを起床させます． */wake_up_interruptible(&mydriver_zz);
return;}/*********************************************************************** ＜オープン処理＞* この関数は，アプリケーションから open()が呼ばれたときにコールされ* ます．
*/
static int mydriver_open(struct inode *inode, struct file *file){
int rc;/* デバイスの初期化やワークエリアの確保、初期化タイマなどの設定などを書きます．*//* デバイスの割込みハンドラを登録します． */rc = request_irq(IRQXX, mydriver_interrupt, SA_SHIRQ, MYDRIVE_NAME, NULL);
if (rc) {return -EBUSY;}
MOD_INC_USE_COUNT;
return 0;}/*********************************************************************** ＜リリース処理＞* この関数は，アプリケーションから close()が呼ばれたときにコールされ
* ます．

11

第1部

技術解説編

〔リスト 3〕キャラクタデバイスドライバのコード例（つづき）*/
static int mydriver_release(struct inode *inode, struct file *file){/* ワークエリアの開放，タイマの削除などの処理を書きます．*/
MOD_DEC_USE_COUNT;
return 0;}/*********************************************************************** ＜読み込み処理＞* この関数は，アプリケーションから read()が呼ばれたときにコールされ* ます．
*/
static ssize_t mydriver_read(struct file *file, char *buf, size_t count, loff_t *offset){
unsigned char data[10];/* デバイスからデータを読み込みます．ここでは，実際にデータを読み込むのは，デバイスドライバと仮定して，スリープさせます． */interruptible_sleep_on(&mydriver_zz);/* ペンディングされているシグナルを確認します． */if (singnal_pending(current))
return -EINTR;/* ボトムハーフ処理で発行された wake_up_interruptible()によって，起床し以下のコードが実行されます． *//* data はカーネル空間ですので，カーネル空間からユーザー空間の buf にデータをコピーします． */if (copy_to_user(buf, &data, sizeof(data)))return -EFAULT;
return mydriver_final_count;} else {return -1;}}/*********************************************************************** ＜書き込み処理＞* この関数は，アプリケーションから write()が呼ばれたときにコールされ* ます．
*/
static ssize_t mydriver_write(struct file *file, const char *buf, size_t count, loff_t *offset){char data[10];/* デバイスに書き込むデータ buf は，ユーザー空間のデータですので，カーネル空間の data にコピーします */if (copy_from_user(&data, buf, sizeof(data)))return -EFAULT;/* ここで，data の値をデバイスに書き込みます */return sizeof(data);}/*********************************************************************** ＜ファイル構造体＞* この構造体で，このデバイスドライバへの各操作に対応する関数ポインタ* を指定しています．
*/
static struct file_operations my_fops = {read:mydriver_read,
write:
mydriver_write,
open:
mydriver_open,
release: mydriver_release,};

12

第1章

Linux を使った組み込みシステム開発〔リスト 3〕キャラクタデバイスドライバのコード例（つづき）/*********************************************************************** ＜ドライバ初期設定＞* この関数は，モジュール登録時（insmod）に呼ばれます．ドライバを* スタティックリンクしてある場合は、カーネルの初期化時に呼ばれます．
* 処理としては，カーネルにデバイスドライバを登録し，必要な変数や* 構造体などを初期化します．
*/
static int __init my_init_module(void){/* カーネルにデバイスドライバを登録します．その際にドライバ名とデバイスのメジャー番号を指定します．

*/
res = register_chrdev(MYDRIVER_MAJOR, MYDRIVER_NAME, &my_fops);
if (res) {printk("init_mydriver: register_chrdev() failed, rc==%d¥n", res);return -EIO;}
return 0;}/*********************************************************************** ＜ドライバ終了＞* この関数は，モジュール終了時に呼ばれます． 通常，登録されたドライバ* を削除します．
*/
static void __exit my_cleanup_module(void){/* カーネルからデバイスを削除します */unregister_chrdev(MYDRIVER_MAJOR, MYDRIVER_NAME);
return;}module_init(my_init_module);/* モジュール/ドライバ登録 */module_exit(my_cleanup_module); /* モジュール/ドライバ終了 *//* サンプルドライバ END */スケジューリングされるわけではありません．これにどが含まれます．Linux の場合，これ以外にメモリ空ついての説明は後で行います．

間やファイル，ユーザーなど多くの情報をもっていま

2.6

リアルタイム性

す．また，MMU を切り替える処理も含まれるため，どうしても RTOS に比べると重くなってしまいます．

組み込みシステムでは，一定時間ごとに行う処理や，また，Linux はプリエンプティブなカーネルではあ割り込みが発生してから処理を実行するまでの時間なりません．カーネルのコードは，割り込まれたり他のどという，何らかの時間的な制限をもっています．

プロセスにデータを変更されないことを前提として処組み込みシステム＝リアルタイムシステム

理を続けているところもあります．たとえば，システということではありませんが，大半の組み込みシステムコール中に割り込みが発生し，割り込み処理からスムにはリアルタイム性が要求されます．

レッドやプロセスの起動をかけた場合でも，割り込み実際に，一般の RTOS では，コンテキスト時間や終了後ただちにスケジューリングされるのではなく，割り込みマスク時間というのは，数μ s から何十μ sシステムコールが終了するまで行われません（図 7）．

程度だと思います．各 RTOS ベンダが提示している

したがって，タイミングによっては割り込みからの応コンテキストスイッチや割り込みマスク時間などのデ答性が非常に悪くなります．

ータは，測定時間やどこからどこまでをコンテキスト

また，割り込みからの応答性を考えた場合，割り込スイッチ時間といっているかという点などが各ベンダ

みマスクしている時間についても考慮する必要がありにより異なるため，データシートの情報だけで純粋なます．Linux では，もともと x86 ベースで開発が行わRTOS の性能を比較することはできません．一方，れてきたため，割り込みレベルごとにマスクするのでLinux の場合，一般の RTOS よりはるかに時間がかかはなく，cli()，sti()といった割り込みすべてをマります．

スクするように実装されている箇所が多くあります．

RTOS のコンテキストには，レジスタ，スタックな

もともとリアルタイム性を重視して作られていないの

13