web-dev-qa-db-ja.com

Linux /組み込みLinux-カーネルと追加のBSP固有のコンポーネントを理解する

* tldr; Linux /組み込みLinuxの世界がどのように機能するかを一般的に理解したいと思います。 Linuxのメインラインを取得し、それをさまざまなプロセッサと周辺機器を搭載したボードに最初からコンパイル/デプロイするには、何をする必要がありますか。

現在どのように機能しているのか:

Linuxを任意のボードで実行する手順:

  • UBoot(組み込み用)またはGRUB(desktop/x86 SOM)のソースを取得する
  • 特定のシステム用にuBootまたはGRUBを変更し、特定のチップを初期化するコードを記述し、メモリとコンソールを起動して実行するために必要なインターフェイスを取得します
  • UBoot/GRUB config.txtを変更して、上記のコードを構成します
  • これらをコンパイルしてボードにデプロイし、ブートローダーコンソールが起動して対話できることを確認します
  • カーネルメインラインソースを取得する
  • 「makeconfig」を使用して、使用可能なドライバーとモジュールを選択します(この時点で、これらの選択によりソースが変更されます。これらの設定が保存されている場所は、メインラインのgitクローンと一致しなくなります)(ソース管理でこの.configファイルを追跡します。今後の参考)
  • Busyboxやデスクトップの代替などのツールを入手しますか?ソースディレクトリにインストールする
  • UcLibcまたは他のライブラリを取得し、ソースディレクトリにインストールします
  • 特定のチップ用のクロスコンパイラツールチェーンを使用してカーネルソースをコンパイルする
  • ボード用のデバイスツリーファイル.dtbを作成します(組み込み/デスクトップ?またはデスクトップの両方が使用しませんか?)これにより、ドライバーが物理ピンに接続されます
  • Uboot/GRUBおよびTFTP /シリアルコンソールまたはメモリカードなどを使用して、コンパイルされたカーネルイメージをロードします。
  • 起動し、ドライバーとデバイスツリー構成に応じてシリアル/ SSHなどを介したシェルアクセスを確認します
  • ボード固有の構成用にuEnv.txt(埋め込み)またはmysteryfile.txt(デスクトップ)を変更しますか?これは本質的に、カーネルの起動手順をブロックまたは追加するスクリプトですか?デスクトップに相当するものは何ですか?
  • apt-必要なパッケージとドライバーを入手する
  • ドライバーとアプリケーションコードを記述し、テストします(ドライバーを手動でロードします)
  • 上記で実装されたハードウェアとドライバーを説明するためにデバイスツリーファイルを追加します(これらは作成された最初のBSPとは別のものです)
  • これらをカーネルイメージに含めるには、カーネルを構築し、これらすべてのソースを含むファイル構造を作成し、フォルダー構造にファイルmodを構成します(Linuxメインラインへの追加/ mod)
  • Linuxメインラインとmod用に別々のフォルダーを作成し、modをコピーしてファイルを直接上書き/メインラインの3番目のステージングフォルダーに追加することができます。これにより、すべての追加とメインライン以外のmodを別々にソース制御できるようになります。

SSHで接続できるベースシステムを入手でき、この時点ですべての一般的なコンポーネント(ビデオ、USB、マウスなど)のドライバーがある場合は、この時点でほとんど何でもできます(X11サーバー、LXDE、ネットワーキングなど)?どのドライバーをブートローダー/ BIOSで処理する必要があり、どのドライバーが純粋にカーネルドメインにあるのですか?

カーネルビルドを構成するためのKconfigファイルがあります。これは理にかなっており、私が見たカーネルモジュール開発ドキュメントはこれをうまく説明しているようです。

ランタイム構成を処理し、どのデバイスをロードする必要があるかを処理するuEnv.txtやconfig.txtなどのファイルもあります。どのデバイスをロードする必要があるかを決定するデバイスツリーBLOBもありますか?

これらのファイルの魔法の文字列はどのようにカーネルに結び付けられますか?これらの変更は特定のボードのメインラインに対して行われますか? HDMIを有効にするかどうかを判断するには、これらを読み取る必要があります。これは、デスクトップバージョンのLinuxにあるコードとまったく同じコードにすることはできません。

ドライバーがメインラインに入った後も、メインラインから独立して開発されていますか?たとえば、私はいくつかのドライバーを使用していましたが、それらがメインラインに含まれているというメモがあります。これは、それ自体で直接ダウンロードすることができなくなったことを意味しますか?私が従った手順では、ボードのヘッダーとソースをダウンロードし、コンパイルしてインストールしました。メインラインにある場合は、代わりに今すぐそこからプルする必要がありますか?

背景と具体的な考え

私はEEであり、マイクロコントローラーとWindows開発の経験がありますが、Linuxの経験はあまりありません。私の質問の枠組みは、「この任意の(Linuxコンパイラが利用可能な)プロセッサと、これらの周辺機器から始めた場合、Linuxリリースを構築するためにどのように(そして私のオプションは何ですか)」です。

ブートローダー:

RPI2とBBB(Beaglebone Black)固有のドキュメントとハウツーを見つけることができましたが、ブートローダーのようなより高度なトピックに入ると、何が起こっているのかを漠然と説明するためのパン粉はほんのわずかです。たとえば、RPI2には3ステージのブートローダーがあり(読んだところ、完全にuBootベースのようには聞こえません)、BBBにはより「従来の」uBootベースのブートローダーがあります。新しいBBx15には、起動元を選択できるジャンパーがあります。

デスクトップシステムはGRUB(IIRC)を使用し、組み込みシステムは通常uBootを使用します。RPIは起動時にGPUを使用し、別のROMから第1段階のブートローダーを読み取ります。これは利用可能なすべての情報。ボードの独自のバージョンをスピンしたい場合(議論のために、これは実際には実用的ではありません)、uBootに加えて何が起こっているのですか?BBx15のuBootには、以下を可能にする追加の変更がありませんか?ジャンパーブートの選択?

Linuxは起動のステージングについて何か知っていますか、それとも実行後にこれに気づいていませんか? BBBはuBootを使用してイメージをeMMCからRAMにロードし、RPI2は3ステージのブートローダーを使用します。 BBBはARMプロセッサを使用してこれを行うと推測していますが、RPI2はGPUを使用しています。電源を入れると、ARMプロセッサが実行を開始し、これらのロード手順をステージングするために何を変更する必要がありますか?GPUはARMコードを完了するまで、リセット時にROMを保持しますか?GPUはブート手順の一部は、実行するコードがuBootコードから取り出されることを意味します。つまり、このGPUを備えていない他のシステムはuBootコードで実行する必要がありますか?この手順全体は、2番目または3番目を変更した場合にLinuxを完全にGPUだけで実行できるステージブートローダー(カーネルがGPUツールチェーンでコンパイルされている場合)?

第3段階のブートローダーとconfig.txtは実際にはuBootだけですか?

使用中のボードのヘッダーについて。これらは、オーバーレイされたドライバーが含まれているメインラインからのヘッダーだけですか、それともこれに何か他のものがありますか? 「ヘッダー」は、それが実行を開始したものである場合、単なるメインラインヘッダーですか?

組み込みマイクロコントローラーの開発では、HALレイヤーを使用することに慣れています。 HALには、周辺機器をセットアップし、ドライバーがそれらのリソースを指すようにする関数スタブがあります。ボードサポートパッケージには通常、これらのHALスタブが問題のボード用にすでにコーディングされています。ここではLinux開発といくつかの類似点が必要だと確信していますが、これらの部門がどこにあるのかよくわかりません。

BuildrootやYoctoなどのパッケージがあります。これらは、含めるARMプロセッサとドライバの選択を自動化するインターフェイスを備えたLinuxメインラインにすぎませんか?

3
GPIB

私が遊んだルーターハードウェアでの私の小さな経験から、これはただ1つのことをするために拾ったばかげた小さなハードウェアであると言うことができます。

ハードウェアレベルでは、それは簡単です。

U-Bootには、ブートローダーだけでなく、PC用語でのBIOSもあります。したがって、ブートローダーのみではなく、すべてのハードウェアを初期化します。起動時に、CPUはそれを直接(たとえばFLASHから)実行し、次に何をするかを決定しますが、通常はそれ自体をメモリに再配置します。次に、必要な処理を実行します。フラッシュピースから構成を読み取り、指定されたアドレスにイメージをロードして、そこで制御を転送します。特別なことは何もありませんが、知っておくことが重要です。

U-Boot(ルーターハードウェアに組み込まれている)は、ルートファイルシステムにまったくアクセスしません。代わりに、カーネルイメージ全体(通常は圧縮)専用のスペースがあります。したがって、少なくともルーターでは、/ boot/vmlinuzファイルはありません。

RPIは確かに、独自の独自のブートシーケンスを使用しています。彼らはユーザーがSDフラッシュに置くクローズドソースバイナリを持っています。第1段階の初期化コードはCPUまたはボード上のどこかにハードコードされています。そして、それらはGPUの後にARMコアを開始し、コード全体がGPU用に実行されます。それについての詳細はすでに見つかっているかもしれませんが、そうでない場合: https://raspberrypi.stackexchange .com/questions/10489/how-does-raspberry-pi-boot

それで、私はルーターを楽しんで、ソースコードから完全に小さなサーバーにルーターを再構築したので、自分の構築シーケンスをリストすることができます。

  • プラットフォーム用のu-bootを入手して構築する
  • Linuxカーネルを構築する
  • ユーザースペースを構築します(通常、フラッシュ上でもカーネルとユーザースペースは分割されます)
  • プログラマーのフラッシュにu-bootするフラッシュ
  • ボードへのはんだフラッシュ
  • UART経由でボードに接続します
  • それを起動し、u-bootがすべてのハードウェアを適切に初期化することを確認します
  • tftpカーネル、ボード内のフラッシュに書き込みます
  • tftp rootfs、ボード内のフラッシュに書き込みます
  • リセットし、すべてが正常に機能することを確認します
  • rootfsを微調整:権限を設定し、tftpを介してデフォルト設定をプリロードします
  • 画像全体をダンプし、多くのデバイスでフラッシュします

Linuxカーネルは、ボードをサポートできる場合とできない場合があります。確認してください。たとえば、ルーター用に最新のカーネルを取得してビルドすることはできません。 RPiと同じです。独自のカーネルツリーがあります。これは組み込みの世界でよく発生し、Linuxカーネルで直接サポートされている(通常は汎用の)プラットフォームはごくわずかです。そのための準備をしてください。

ユーザースペースに関しては、必要なものを選択し、必要なものと残りのスペースの数の間でニーズのバランスをとることができます。通常、埋め込みでは、何かを圧縮するか、不要なものを取り除くか、またはその両方を行います。

これがいくつかの光を当てることを願っています。さらに質問がある場合は、コメントへようこそ! :-)

2
user140866