概要
Linuxを実行可能なマルチコアシステムを実装する上では、Linuxカーネルの理解は欠かせません。
本記事は、RISC-V向けLinuxカーネルの実装を読み、筆者が思い込みを解消した備忘録です。
本編
筆者は現在、RISC-VのCPU (コア) を複数搭載したマルチコアシステムを開発しています。 また、筆者は過去にLinux on LiteX-VexRiscvを用いたマルチコアRISC-V SoCのシミュレーションについて紹介しました。
本記事は、Linux on LiteX-VexRiscvのノリでデバイスツリーを作成し、自分の環境で利用したところ、システムが起動しなかったというお話です。
Linux on LiteX-VexRiscvが配布するLinuxカーネルのイメージはv5.14のものです。 この環境において、筆者はシステムに実在するCPUコア数を超える数のCPUをデバイスツリーに登録した状態でシステムを起動しようとしました。 すると、セカンダリCPUの起動時に少々待ってからCPUnの起動に失敗した旨が表示されました。
[ 0.040410] smp: Bringing up secondary CPUs ... [ 1.100982] CPU1: failed to come online [ 2.166129] CPU2: failed to come online [ 3.231268] CPU3: failed to come online [ 3.232132] smp: Brought up 1 node, 1 CPU
これを見た筆者は「Linuxは賢いなあ。ほなコア数増やしてもええようにデバイスツリーにたくさん書いといてもええんや。」と思い込んでしまいました。
ところかわって筆者の環境、筆者は上のように思い込んだままデバイスツリーに実際よりも多くのコアを記述しました。 すると、いつまでたってもカーネルが立ち上がってきませんでした。
これはおかしいと思い、システムのCPUのプログラムカウンタを確認したところ、どうやら無限ループに陥っていることがわかりました。
その無限ループはlinux/arch/riscv/kernel/smpboot.c
で定義される__cpu_up
関数内のようでした。
筆者の環境はLinuxカーネルv5.0を採用しており、__cpu_up
関数は待機対象コアが起動するまで無限ループするという実装になっていました。
一方で、Linux on LiteX-VexRiscvが採用するv5.14では、起動を試みてから約1秒待機し、コアが起動していなければメッセージを表示して終了するという実装になっていました。
やってしまいましたな。
上記の変更はcommit e15c6e3で行われたようです。
RISC-V向けLinuxカーネルの開発もv5.0と比べてかなり進んでいる可能性を実感しました。
かくして、筆者は思い込みを解消し、カーネルv5.0を使っている間はひとまずコア数を実在とデバイスツリーで一致させるという方針を取ることにしました。 思い込みはよくないと身をもって知るとともに、そろそろ新しいバージョンのカーネルを使い始めたほうがいいのではないかと感じました。