以前の QEMUで学ぶベアメタル開発 で、OSを一切使わずにARMとRISC-Vを起動させました。3つのファイルで1,242バイト、という話です。その次に必ず出てくるのが「で、この上にOSを載せるべきなのか」という問いでした。
載せる候補は、ざっくり3つあります。FreeRTOS、Zephyr、そして組み込みLinux。名前は聞くのに、どこで線を引くのかは意外と語られません。「リアルタイム性が要るならRTOS」と言われても、リアルタイム性が要らない組み込み機器のほうが珍しいわけで、それでは選べません😅
そこで今回は、調べるだけでなく同じ仕事を3通りで書いて、Mac上のQEMUで実際に動かして測りました。焼かれるサイズ、手で書いた行数、そして「片方の処理が長引いたとき、もう片方の周期は守られるか」の3つです。
結果を先に言うと、サイズは素直に増えたのに、手で書く量は素直に増えませんでした。そして「RTOSを入れれば周期が守られる」という思い込みも、12バイトで崩れました。
実験は3つあります。章タイトルに【承前】と付いている章は、直前の章の続きです。
【前置き】ベアメタルの次にある、ひとつの分かれ道
組み込みのソフトは、下から順に3つの層のどれかに置かれます。
この3つは「性能の順位」ではありません。CPUの使い道を誰が決めるかが違うだけです。ベアメタルは自分、RTOSは優先度をもとにスケジューラ、Linuxはほぼおまかせ。そしておまかせにできる代わりに、いつ動くかを約束しにくくなります。
用語集
今回は略語が多いので、先に並べておきます。
| 用語 | 平たく言うと | なぜそれが効くのか |
|---|---|---|
| RTOS (Real-Time OS) | 「この処理は必ず○ミリ秒以内に始める」を守ることを最優先に作られたOS | 速いOSという意味ではない。遅くてもいいから、ばらつかないことに価値がある |
| ベアメタル | OSを載せず、自分のプログラムがCPUを丸ごと使う書き方 | 間に挟まるものが無いので、いちばん小さく、いちばん速く起動する |
| タスク/スレッド | RTOSの上で並行に走る仕事の単位。FreeRTOSは「タスク」、Zephyrは「スレッド」と呼ぶ | ひとつずつ独立した無限ループとして書ける。順番の管理から解放される |
| スケジューラ | 次にどのタスクを動かすかを決める係 | ここが「優先度の高いほうを必ず先に」と決め打ちしているのがRTOSの肝 |
| プリエンプション | 動いている仕事を途中で止めて、優先度の高い仕事に切り替えること | これが無いと、長い処理が終わるまで他が待たされる |
| MMU / MPU | メモリに仕切りを入れる回路。MMUは住所の付け替えまでできる高機能版 | LinuxはMMUが要る。MPUしか無いマイコンではRTOSかベアメタルになる |
| PREEMPT_RT | Linuxカーネルを「途中で止められる」ように作り替えた仕組み | 2024年に本流へ入った。Linuxでも遅延を抑えられるようになった |
| LTS (Long Term Support) | 長期間、修正だけを提供し続けると約束された版 | 組み込みは製品寿命が10年超えもある。選定の決め手になりやすい |
| 機能安全 (IEC 61508 など) | 「壊れても人を傷つけない」ことを証明するための規格 | 証明の材料(開発記録・テスト記録)が要る。OS側が用意していないと自前になる |
| Kconfig / デバイスツリー | 使う機能とつながっている部品を、設定ファイルで宣言する仕組み | Zephyrの土台。使わない機能はそもそもビルドされないので、大きな土台でも小さく焼ける |
【下調べ】3つの選択肢を同じ切り口で並べる
まず、性格の違いを表にしました。数字の出典は次の章にまとめてあります。
| FreeRTOS | Zephyr | 組み込みLinux | |
|---|---|---|---|
| 正体 | カーネルだけ | カーネル+ドライバ+設定の仕組み一式 | 汎用OSを小さく仕立てたもの |
| ライセンス | MIT | Apache-2.0 | GPLv2(カーネル) |
| 母体 | Amazon(AWS) | Linux Foundation | Linux Foundation ほか |
| 必要なメモリ | 数KB〜 | 十数KB〜 | MMUと数十MB〜 |
| 起動 | 100ms未満 | 1秒以上 | |
| ドライバ | 自分で用意する | ボード定義に含まれる | 豊富にある |
| ネットワーク・BLE | 別部品を足す | 同梱 | 同梱 |
| 向いている規模 | 仕事が数個〜十数個 | 通信もUIも要る機器 | 画面・アプリ・更新が要る機器 |
いちばん大事な違いは1行目です。FreeRTOSは「カーネルだけ」、Zephyrは「一式」。この差が、あとの実測にそのまま出てきます。
【下調べ】2026年の3つは、それぞれどこにいるのか
Zephyr ── 10年目に入り、認証は「まだ」
Zephyrは2026年3月4日で10周年を迎えました。貢献者は3,000人を超え、対応ボードは1,000を超えています(Zephyr Project)。
リリースは4月と10月の半年周期で、最新は 4.4.0(2026年4月14日)。現行のLTSは 3.7.0 で、2029年7月まで維持されます。次のLTSは 4.6(2027年4月予定)(Zephyr公式ドキュメント)。
注意が要るのは機能安全です。よく「Zephyrは認証を目指している」と紹介されますが、公式ドキュメントを読むと、IEC 61508 の SIL 3 / SC 3 を目標に作業中で、対象範囲は「TBD(未定)」と書かれています(Safety Overview)。2026年8月時点で認証は取れていません。安全規格が要る案件で「Zephyrなら通る」と見込むのは、まだ早い段階です。
FreeRTOS ── 変化は静かだが、寿命の話をしている
FreeRTOS 202604 LTS が2026年5月1日に公開されました。カーネルは v11.3.0、サポート期間は2年です(AWS)。
中身で目を引いたのは、派手な新機能ではなく次の2つでした。
- MPUが要求する領域の数を減らした。減った分をアプリ側の保護に回せる ── メモリ保護を実際に使う現場が増えている裏返しに見えます
- coreSNTP v2.0.0 が2038年問題に対応。今日出荷した機器が、寿命の最後までTLS証明書を検証できるように、という理由づけでした
「10年以上動き続ける前提で作られている」という空気が、リリースノートの文言に出ています。
組み込みLinux ── リアルタイムが「標準装備」になった
大きな出来事は2024年9月20日、PREEMPT_RT が本流のカーネルにマージされたことです。v6.12 が最初の対応版で、以後は外部パッチを当てなくてもリアルタイム構成が選べます(Linux Foundation Wiki)。
作る側の土台であるYoctoは、6.0(Wrynose・2026年4月)がLTSで2030年4月まで、ひとつ前の 5.0(Scarthgap)が2028年4月までという並びです(Yocto Project)。製品の寿命に合わせてLTSを選ぶという、RTOS側と同じ話がここにもあります。
採用の実態
2026年の集計では、開発者の採用率は 組み込みLinux 46% / FreeRTOS 29% / Zephyr 21% とされています(embeddedbits)。合計が100%を超えるのは、1つの製品で複数を併用しているから。大きなCPUでLinux、脇のマイコンでRTOS、という組み合わせが珍しくありません。
【実験の準備・Mac】同じ仕事を3通りで書いて、QEMUで動かす
ここからは実測です。p959 と同じくQEMUを使うので、実機は買っていません。
| 項目 | 内容 |
|---|---|
| ホスト | Mac(M4) |
| エミュレータ | QEMU 11.0.2 |
| ボード | mps2-an385(Arm Cortex-M3・25MHz) |
| コンパイラ | Arm GNU Toolchain 15.3.Rel1(3つとも同じもの) |
| FreeRTOS | FreeRTOS-Kernel V11.3.0 |
| Zephyr | v4.4.0 |
題材はできるだけ単純にしました。
- 仕事A:500ミリ秒ごとに1行出力する
- 仕事B:1200ミリ秒ごとに1行出力する
出力は 時刻(ミリ秒) 名前 の形にして、あとからホスト側で集計します。時刻はボードの中の時計で数えているので、Macの負荷には影響されません。
まずベアメタル版。1本のループの中で、自分で時刻を見て振り分けます。
int main(void)
{
unsigned int next_a = 500;
unsigned int next_b = 1200;
uart_init();
systick_init();
for (;;) {
unsigned int t = now_ms();
if ((int)(t - next_a) >= 0) {
uart_event("A", t);
next_a += 500;
}
if ((int)(t - next_b) >= 0) {
uart_event("B", t);
next_b += 1200;
}
}
}
次にFreeRTOS版。2つの仕事が、それぞれ独立した無限ループになります。
static void task_a(void *arg)
{
TickType_t last = xTaskGetTickCount();
for (;;) {
vTaskDelayUntil(&last, pdMS_TO_TICKS(500)); /* 500ms周期で起こしてもらう */
uart_event("A", (unsigned int)xTaskGetTickCount());
}
}
int main(void)
{
uart_init();
/* 最後から2番目の数字が優先度。Aのほうが高い */
xTaskCreate(task_a, "A", configMINIMAL_STACK_SIZE, NULL, 3, NULL);
xTaskCreate(task_b, "B", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
vTaskStartScheduler(); /* ここから先は戻ってこない */
}
そしてZephyr版。main にタスクを起こす処理すら出てきません。
static void task_a(void *p1, void *p2, void *p3)
{
int64_t next = 500;
for (;;) {
k_sleep(K_TIMEOUT_ABS_MS(next)); /* 「この時刻に起こして」と頼む */
printk("%lld A\n", k_uptime_get());
next += 500;
}
}
/* 数字の小さいほうが優先度が高い。Aのほうが高い */
K_THREAD_DEFINE(tid_a, 640, task_a, NULL, NULL, NULL, 3, 0, 0);
K_THREAD_DEFINE(tid_b, 640, task_b, NULL, NULL, NULL, 4, 0, 0);
ベアメタルとFreeRTOSでは、UARTに文字を出す処理を同じソースで共有しています。Zephyrは自前のコンソールを持っているので、そこだけは同じにできませんでした(この差は後で効いてきます)。
【実験1・3構成】焼かれるサイズと、手で書いた行数を比べる
まず、できあがったものの大きさです。
| 実装 | ROM(焼かれる) | RAM(使う) | ファイル数 | ビルド時間 |
|---|---|---|---|---|
| ベアメタル(OSなし) | 453 B | 4 B | 5 | 0.07秒 |
| FreeRTOS 11.3.0 | 3,500 B | 6,400 B | 6 | 0.35秒 |
| Zephyr 4.4.0 | 14,100 B | 7,647 B | 3 | 12.81秒 |
ここまでは想像どおりです。土台が厚いほど大きい。Zephyrはベアメタルの31倍ですが、それでも14KBに収まっています。使っていない機能はKconfigの段階でビルドされないので、一式そろっている割には小さいと言えます。ここは正直、もっと大きいと思っていました。
RAMの6,400Bのうち6,144BはFreeRTOSのヒープ(configTOTAL_HEAP_SIZE)で、タスクのスタックはここから切り出されます。設定値をそのまま書いただけなので、詰めればもっと減ります。
【承前】予想が外れた ── 手で書く量がいちばん多いのはFreeRTOS
次に「自分で書いた行数」を数えました。カーネルのソースは含めず、手で用意したファイルだけです。ここで予想が外れました。
FreeRTOS版が3つの中でいちばん多い207行になりました。ベアメタル版より27行多いのです。
理由ははっきりしていて、FreeRTOSがカーネルしか持っていないからです。起動処理(startup.s)、メモリ配置を決めるリンカスクリプト、UARTのドライバ ── ベアメタル版で書いたものは1行も減りません。そこに FreeRTOSConfig.h が丸ごと増えます。
Zephyrはその逆で、起動処理もUARTもデバイスツリーもボード定義の側にすでにあるので、書いたのは main.c(38行)と CMakeLists.txt と prj.conf の3つだけでした。
つまり 「RTOSを入れると書く量が減る」はZephyrには当てはまり、FreeRTOSには当てはまりません。FreeRTOSが減らすのは行数ではなく、「いつどれを動かすか」を考える手間のほうです。これは同じ「RTOS」という言葉でくくると見えなくなる違いでした😳
そのかわり、ビルド時間は Zephyr 12.81秒 対 FreeRTOS 0.35秒=約37倍。書き換えて試すたびに待たされるので、体感でいちばん違うのはここです。
【実験2・3構成】片方の仕事が800ms居座ったら、もう片方はどうなるか
ここからが本題です。仕事Bに800ミリ秒かかる処理を足しました。センサーの読み出しや暗号処理を想定した、CPUを離さない処理です。
仕事Aは500ミリ秒周期なので、Bが居座っている間にAの出番が1〜2回来ることになります。
結果を、Aが本来出るべき時刻からどれだけ遅れたかで見ます(0〜9600ミリ秒の19回分)。
| 実装 | 最大の遅れ | 平均の遅れ | 100ms以上遅れた回数 |
|---|---|---|---|
| ベアメタル(素朴なループ) | 700 ms | 221.1 ms | 19回中 9回 |
| FreeRTOS 11.3.0 | 0 ms | 0.0 ms | 0回 |
| Zephyr 4.4.0 | 0 ms | 0.0 ms | 0回 |
実際のログの一部です。左が正常時、右がBに800ミリ秒の処理を足したときです。
ベアメタル(通常) ベアメタル(Bが800ms居座る)
500 A 500 A
1000 A 1000 A
1200 B 1200 B
1500 A 2000 A ← 500ms遅れ
2000 A 2000 A ← 取りこぼした分を続けて撃つ
2400 B 2400 B
2500 A 3200 A ← 700ms遅れ
3000 A 3200 A
予定表どおりに並ぶ左に対して、右はずれたまま、まとめて撃ち直しているのが分かります。100ミリ秒以上ずれた回が19回中9回ですから、ほぼ2回に1回は約束を守れていません。
一方、FreeRTOSとZephyrは1ミリ秒もずれませんでした。Bが800ミリ秒回り続けていても、優先度の高いAが割り込んで先に動くからです。ここは期待どおりでした。
【承前・ベアメタルで切り分け】12バイトで直った
ここで一度立ち止まりました。この比較は、ベアメタルに不利すぎないかという疑いです。
ベアメタル版の書き方が素朴すぎるだけかもしれません。そこで、Aの処理を、1ミリ秒ごとに必ず呼ばれるタイマー割り込みの中へ移しただけの版を作りました。差分は本当にこれだけです。
void SysTick_Handler(void)
{
ticks++;
/* Aの仕事を「割り込みの中」でやってしまう。
メインループが何をしていようと1msごとに必ず呼ばれるので、周期は崩れない */
if (ticks % 500u == 0u) {
uart_event("A", ticks);
}
}
結果です。
| 実装 | ROM | Bが800ms居座ったときのAの最大の遅れ |
|---|---|---|
| ベアメタル(素朴なループ) | 453 B | 700 ms |
| ★ベアメタル(Aを割り込みで) | 465 B | 0 ms |
| FreeRTOS | 3,500 B | 0 ms |
| Zephyr | 14,100 B | 0 ms |
12バイト増やしただけで、遅れは0ミリ秒になりました。
つまり、この題材で言うかぎり 「周期を守れるかどうか」はRTOSの有無で決まっていません。決めていたのは処理をどこに置いたかだけでした。
【ここから整理】では、RTOSは何を代わりにやっているのか
実験2でひっくり返った結論を、素直に書き直します。
RTOSは「守れるようになる道具」ではなく、「守り方を、優先度という宣言で書けるようにする道具」
仕事が2つなら、置き場所は人間の頭の中で決められる。今回は12バイトで済んだ。問題は、仕事が10個になったとき。しかも互いに「Aが終わるまでBは待つ」といった待ち合わせが混ざったとき、その配置を人間が手で決め続け、変更のたびに全部を見直せるか ── そこが分かれ目になる。
今回の題材の弱点も正直に書いておくと、仕事が2つしかなく、しかも互いに何も待ち合わせていません。この条件はベアメタルにいちばん有利です。逆に言えば、この条件でRTOSを入れる理由は薄いということでもあります。
もうひとつ、割り込みの中に処理を置く手には代償があります。割り込みの中では待てません。今回はUARTに数バイト出すだけだったので通りましたが、ここで「センサーの応答を待つ」ようなことを書くと、時計そのものが止まります。置ける場所には限りがあり、その限りを守るのは人間の役目です。RTOSはその役目を引き取ってくれます。
【整理】組み込みLinuxはどこから必要になるのか
ここは実測していません。QEMUで測ったのはベアメタル・FreeRTOS・Zephyrの3つだけなので、Linuxについては出典つきの数字として扱います。
線引きははっきりしていて、MMU(メモリの仕切りを作る回路)があるかどうかです。MMUが無いマイコンにはLinuxは載りません。逆にMMUがあるなら、次の3つのうちどれかが要るときにLinuxが視野に入ります。
- 画面とアプリが要る(ブラウザ、地図、動画)
- 既存の資産を使いたい(Python、OpenCV、データベース、コンテナ)
- 出荷後に中身を入れ替え続ける(アプリの追加・差し替え)
数字で言うと、起動時間は RTOSが100ミリ秒未満、Linuxが1秒以上。必要なメモリは RTOSがRAM 2MB未満・Flash 4MB未満、Linuxが RAM 16MB超・Flash 32MB超。処理を切り替えるときの遅れは Zephyrが5マイクロ秒未満、PREEMPT_RT入りのLinuxが50〜200マイクロ秒 とされています(embeddedbits・2026)。
10倍から40倍の開きがありますが、「50〜200マイクロ秒では足りない」用途がどれだけあるかを先に考えたほうが実務的です。モーター制御や無線の下回りなら足りません。ボタンを押してから画面が変わるまでなら、まったく問題になりません。
そして現実の製品では、両方載っていることがよくあります。大きなCPUでLinuxが画面とネットワークを持ち、脇の小さなマイコンでRTOSがモーターとセンサーを持つ、という分担です。採用率の合計が100%を超えるのはこのためでした。
【整理】いつどれを選ぶか ── 判断表
ここまでを、状況から引ける形にまとめます。
| こういうとき | 選ぶもの | 理由 | 覚悟すること |
|---|---|---|---|
| 仕事が1〜3個で、待ち合わせが無い | ベアメタル | 数百バイトで済む。今回は453B | 仕事が増えたときの作り直し |
| 電池で年単位で動かす | ベアメタル or FreeRTOS | 寝ている時間を細かく作れる | 省電力の作り込みは自前 |
| 仕事が5個以上/待ち合わせがある | FreeRTOS | 優先度で宣言でき、カーネルは3.5KB | ドライバと起動処理は自分で書く |
| すでにベアメタルの資産がある | FreeRTOS | 起動処理もリンカスクリプトもそのまま使える | 行数はむしろ増える |
| BLE・Wi-Fi・USBが要る | Zephyr | 同梱されていて、設定だけで有効にできる | ビルドが遅い(今回は37倍) |
| いろいろなボードに載せ替える | Zephyr | デバイスツリーでボード差を吸収する | 仕組みを覚えるまでが重い |
| 10年以上サポートする | ZephyrのLTS or FreeRTOSのLTS | Zephyr 3.7.0は2029年7月まで/FreeRTOS 202604 LTSは2年 | LTSは新機能が入らない |
| 機能安全の認証が要る | 商用RTOS を検討 | Zephyrは2026年8月時点で未認証(作業中・範囲もTBD) | 費用がかかる |
| 画面・アプリ・出荷後の入れ替えが要る | 組み込みLinux | 資産が桁違いに多い | MMUと数十MB、起動1秒以上 |
| 速い応答と豊かな機能を両方 | Linux + RTOS の併用 | 役割でチップを分ける | 2つ分の開発と、間の通信 |
【整理】2026年の潮流
調べていて、3つの流れが見えました。
①「証明できること」への圧力が上がっている。 Zephyrが機能安全の作業を続け、FreeRTOSがMPUの領域数を減らし、リリースノートで2038年まで話をする。どれも「壊れないこと」ではなく「壊れないと示せること」に向かっています。ここは、まだ答えが出ていない領域でもあります。Zephyrの認証は2026年8月時点で未完で、公式にも範囲は未定と書かれています。
② 寿命の話が前に出てきた。 ZephyrのLTSは5年(3.7.0は2029年7月まで)、YoctoのLTSは4年(6.0は2030年4月まで)、FreeRTOSのLTSは2年。製品の寿命に合わせてLTSを選ぶのが当たり前になり、その期間の長さ自体が競争になっています。組み込みは10年20年の世界なので、「今いちばん新しい版」を選ぶのが正解とは限りません。
③ 境界が薄くなった。 PREEMPT_RTが本流に入ったことで、Linuxは「リアルタイムには使えない」と切り捨てられなくなりました。逆にZephyrはネットワークもBLEもファイルシステムも持っていて、かつては「Linuxが要る」と言われた機能の一部を引き受けています。両側から歩み寄っていて、真ん中の判断がいちばん難しくなっているのが2026年の姿だと思います。
つまずき集
- ★Homebrewの
arm-none-eabi-gccにはCライブラリが入っていない。stdint.hが見つからずに止まります。FreeRTOSはmemsetを使うので、これだけではリンクできません - ★
brew install --cask gcc-arm-embeddedは管理者パスワードを要求して止まる。ダウンロード済みの.pkgをpkgutil --expand-fullで展開すれば、管理者権限なしでそのまま使えます(p968 でGPTK 4に使ったのと同じ手です)PKG=$(ls ~/Library/Caches/Homebrew/downloads/*arm-gnu-toolchain-*.pkg) pkgutil --expand-full "$PKG" /tmp/tc mv /tmp/tc/Payload ~/devel/rtos_p981/toolchain/arm-gnu-15.3 - FreeRTOSの設定で
configUSE_16_BIT_TICKSとconfigTICK_TYPE_WIDTH_IN_BITSの両方を書くとビルドが止まる。11系では後者だけを書きます - ★Zephyrのworkspaceは全部取ると数GBになる。
west updateに必要なモジュールだけを並べれば済みます(今回はcmsis cmsis_6 picolibc seggerの4つで、1.4GB) - ★時間の測定にホスト側の時計を使わない。QEMUの中の時計(SysTick)で数えた値を出力に混ぜておけば、Mac側が重かろうと結果は変わりません
- ⚠停止用のタスクを最高優先度にしてはいけない。10秒後に終了を知らせるタスクを優先度いちばんで作ったところ、そのあと他のタスクが二度と動かなくなりました。集計の窓を0〜9600ミリ秒に揃えて回避しています
まとめ
Zephyr・FreeRTOS・組み込みLinuxを同じ切り口で並べ、前の2つとベアメタルをQEMUで実際に動かして測りました。
- ★焼かれるサイズは素直に増える。453 B(ベアメタル)→ 3,500 B(FreeRTOS)→ 14,100 B(Zephyr)で31倍。それでもZephyrが14KBに収まったのは予想外だった
- ★★手で書く行数は単調に減らない。180 → 207 → 46 と山になる。FreeRTOSがいちばん多く、ベアメタルより27行多い
- FreeRTOSはカーネルしか持っていないので、起動処理・リンカスクリプト・ドライバが1行も減らない
- Zephyrはそれらがボード定義の側にあるので、書いたのは
main.c38行を含む3ファイルだけ - → 「RTOSを入れれば書く量が減る」はZephyrにしか当てはまらない
- ★ビルド時間はZephyrがFreeRTOSの約37倍(12.81秒 対 0.35秒)。体感でいちばん差が出るのはここ
- ★★「重い処理に周期を壊される」のはRTOSの有無ではなかった
- 素朴なループのベアメタルは最大700ms遅れ・19回中9回が100ms超
- ところがAを割り込みの中に移すだけで0msになり、増えたROMは12バイト
- → RTOSは「守れるようになる道具」ではなく、「守り方を優先度という宣言で書けるようにする道具」
- ★Zephyrの機能安全は2026年8月時点で未認証。IEC 61508 SIL 3 を目標に作業中で、対象範囲も公式に「未定」と書かれている。認証が要る案件で当てにするのはまだ早い
- Linuxの線引きはMMUの有無。PREEMPT_RTが本流に入って遅延は50〜200マイクロ秒まで来たが、起動1秒以上・RAM 16MB超という条件は変わらない
始める前にいちばん知りたかったのは「どこで線を引くのか」でした。測ってみて、線は思っていたところに引かれていませんでした。
「リアルタイム性が要るならRTOS」と言われて、ずっと腑に落ちなかったのですが、理由が分かった気がします。リアルタイム性は、RTOSを入れなくても手に入るのです。今回は12バイトでした。RTOSが引き取ってくれるのは、それを人間が手で設計し続ける仕事のほうでした。だから「仕事がいくつあるか」「互いに待ち合わせるか」で選ぶことになります😊
そしてFreeRTOSとZephyrを「どちらもRTOS」とひとくくりにしていたのも、間違いでした。片方はカーネルだけ、もう片方は一式。行数が逆転したのを見て、ようやく別物として見えるようになりました。
使った材料はCのソースが数本と、QEMUだけです。ボードは買っていないので、同じ手順を踏めば手元でも同じ表が作れると思います。
それでは、今回はここまで。最後までありがとうございました😊