CでRaspberry PiのOSを書く


19

Baking Piチュートリアルはすでに見つけましたが、アセンブリ言語のみを使用しています。最初のレッスンに従いましたが、代わりにCを使用する方法をすでに疑問に思っています。つまり、彼らが高レベルの言語を発明したのには理由があるのです。Cコードをオブジェクト(.o)ファイルにコンパイルして、コンパイルしようとしました

.section .init
.globl _start
_start:

bl main

loop$:
b loop$

別のオブジェクトファイルにリンクし、それらを一緒にリンクして、取得しkernel.imgます。その後、すでに存在するカーネルを自分のものに置き換えましたが、Cコードは実行されません。私が書いたCコードは、OK LEDをオンにしてから戻ります(それからになりますloop$: b loop$)。しかし、OK LEDは数回ランダムに点滅し、その後消灯します。これが私のCコードです。

int main(int argc, char ** argv) {
    volatile unsigned *gpioAddr = (volatile unsigned *)0x20200000;
    *(gpioAddr + 4) = 1 << 18;
    *(gpioAddr + 40) = 1 << 16;
    return 0;
}

Raspberry Piでのオペレーティングシステム開発にCを使用するにはどうすればよいですか?

私はそれがコードのエラーではないことを疑います(ただし、私は単なる愛好家です)。Cのセットアップは複雑かもしれませんが、これを行うのは初めてではありません。知る限り、現在支配的なすべてのOSは主にCで書かれているため、プロセスを説明する記事が必要です。私もステップのリストに非常に満足しているので、それらのステップをグーグルで検索して、おそらく少し広義の質問をすることができます。

注:上記のCコードに相当するARMアセンブリは問題なく機能します。LEDが点灯します(少し点滅した後)。Raspberry Piが正常であることを示す(希望)と思います。


Cは、Unix用の移植可能なアセンブリ言語として設計されました。LinuxはCで書かれています。どのように行われるかを見ると、時間をかなり節約できます。
トールビョールンラヴンアンデルセン

1
@ThorbjørnRavnAndersen私はLinuxのソースを読むつもりはないと思います。Linuxは、私が知りたいものよりもはるかに複雑であるため、興味深い部分がわかりにくくなっています。
11684

1
ええと、いくつかのLEDを「接続」します。
11684

1
ありがとう、でも私はほとんどのことを自分でやりたい。それは学習プロジェクトです。
11684

1
OSの書き方について、これまでどこでも質問を見たことがないことを認めなければなりません。そして、いくつかの興味深い答えがあります。それは...ちょうど狂気である
ピョートル・クラ

回答:


14

数年前に非常に単純なカーネルを作成し、386で実行しました。長年、ベアメタルプログラミングを行っていませんが、大まかに言うと、次のようなアセンブラコードを記述する必要があります。

  • 起動プロセス中の割り込みを無効にします
  • Piにメモリコントローラーがある場合は、セットアップする必要があります
  • タイマーティックを設定します
  • 割り込みコントローラーを構成する
  • Cコードを実行できるようにスタックを設定します

スタックの設定は簡単です。使用されていないメモリを見つけ、そのアドレスをスタックポインタとして使用されるレジスタにロードします。

Cコードでは、メモリプールやスレッドテーブルなどのOSデータ構造を初期化する必要があります。Cライブラリ関数を使用することはできません。そのようなものを自分で記述する必要があります。

単純なマルチタスクOSを作成する場合は、いくつかのアセンブラールーチンを作成してCPUレジスタをスタックに保存し、別のスレッドのスタックからレジスタ値の異なるセットをロードする必要があります。また、異なるスレッドを作成するためのAPIを作成する必要があります。


1
この答えとジョルジュデュペロンのどちらかを選ぶのは難しい。私はこれを受け入れ、もう一方に賛成票を投じました。
11684

13

私はあなたのコードを詳しく見ていませんが、あなたは正しい軌道に乗っているようです。以下を確認してください:

  • _start記号は確かにあなたのアセンブリファイルとあなたのCファイルをコンパイル&リンクする際に使用したもの(とあるmain()代わりに使用されていません)
  • を呼び出すときmain()は、Cの呼び出し規約を使用する必要があります。
    • 呼び出し後の命令のアドレス(returnC のステートメントで使用される戻りアドレス)をスタックにプッシュします。
    • 関数の引数をプッシュします。あなたの場合、2つの32ビット値(合計8バイト)をプッシュできますが、物事を簡単にするために引数を削除してint main() { ... }
    • 戻り値のためにスタック上にスペースを確保してください
    • これらのことをどの順序でプッシュすべきか覚えていない
    • C関数が何を期待しているかを正確に知るには、それを逆アセンブル(objdump -S main.o)し、スタックをどのように操作するかを調べます。
  • 呼び出し規約を尊重しない場合、Cコンパイラによって生成されたアセンブリコードがスタック上のリターンアドレスを改ざんする可能性があり、あなたの場合はリターンアドレスをプッシュしなかったため、リターン命令はどこかにジャンプしますに行く代わりに、ランダムにloop$

OSDevのwikiには非常に便利ressourceになります-それは主にx86の開発に関係だが、ほとんどの情報はまだラズベリーパイにも適用可能です。

いくつかのraspberry-pi osdev固有のリソース:


この答えとスティーブの答えを選ぶのは難しい。私はあなたに賛成票を与え、もう一方を受け入れました。5 repの違いを後悔しています。
11684

OSDev wikiは良いです-そしていくつかの特定のRasPiのものさえあります
ウォーリー14

2

発生する可能性のある主な問題は、Cライブラリとプロローグコードです。独自のコードが実行を開始する前に開始され、スタック、ヒープをセットアップし、他の多くの有用なことを行います。ただし、ベアメタル用のプログラムを作成する場合は、OSが下で実行されていないため、これらの関数を呼び出さないようにすることをお勧めします。そのためには、Cライブラリの修正バージョンや、独自のシンボルで定義または置換されたグローバルシンボルが必要です。このプロセスには少し関与しているため、「Bake Pi」の人々はチュートリアルにアセンブリを使用することを選択しました。


私の質問に答えてくれてありがとう(そして遅くまで返信して申し訳ありません)。しかし(サプライズ!)まさにそれについて学ぶためにpiを購入しました。これは、低レベルのプロセスを伴うものです(個人のファイル/メール/写真を破壊するリスクがある高価なデスクトップではやめたいです)。スタックの設定方法、またはそれを説明する記事/チュートリアル/リソースを追加してください。(そして、Cを実行するために他に何が必要か)。
11684

2

代わりにこれを試してください:

http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/

また、x86のエクスペリエンスは少し異なります。一般的なARMベアメタルOSプログラミングに適用される場合があります。しかし、Piの場合は、gpuが最初に起動し、OS(?)コードのかなり前に設定されるのが残念です。


1
もう少し詳しく説明すると、回答のリンクが壊れた場合はどうなりますか?
ダースベイダー

それはまだそこにありますが、ここに来る人のために、「バルブベアメタル」をグーグルして、OSDEVシリーズを試してみてください(私が苦労してクロスデベロッパーを通過するには、フォーラムを読んでください。私はあなたがグーグル「OSDEVフォーラム6か月のクロス」)
デニスNg

私はこれがさらに古い質問に対する古い答えであることを知っています、ページはダウンした場合に備えてweb.archive.orgにあります。
匿名

1

s-matyukevich/raspberry-pi-os

https://github.com/s-matyukevich/raspberry-pi-os

このすばらしいレポジトリは、Cブートストラップと、非常に複雑なトピックの両方を実行します。

さらに、Linuxカーネルがどのように処理するかを調べ、Linuxカーネルコードに注釈を付けます。

最小限のセットアップの最初のチュートリアルをご覧くださいhttps : //github.com/s-matyukevich/raspberry-pi-os/tree/43f682d406c8fc08736ca3edd08a1c8e477c72b0/src/lesson01/src

強くお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.