ARM RaspberryPi Tutorial C を云々してみる
とりあえず、Makefile は CFLAGS なナニを修正しないとコンパイルできませんでした。
35,36c35 < #CFLAGS := $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS) < CFLAGS := $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) --- > CFLAGS := $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS)
動かす前に書いてある事を読みつつ控えてみたいと思います。
C なプログラムは三つの引数を受け取る形になってますね。GPU bootloader は r0, r1, r2 でカーネルに引数を、とのこと。boot.S ではこれらは操作していません。つうか
// Call kernel_main ldr r3, =kernel_main blx r3
で、引数が、というあたりは確認の必要あり。で、それぞれのレジスタは
- r0 が起動元のデバイス? 通常 0 だけど firmware 依存
- r1 が ARM Linux Machine Type で RPi は 0xc42 (bcm2708 の値)
- r2 が ATAG なアドレス (後述とのこと)
UNUSED なマクロで云々してるのは最適化でコンパイラが文句を言わないように、とのこと。ちなみに上記命令は
- ldr で kernel_main なアドレスを r3 に load して
- blx はリンク付き分岐と命令セットの切り替え
とあります。bl な命令は r14 に戻り番地 (というか次の命令の番地か) を退避とありますね。つうか引数な関係については記述が無いな、と思ってたらパラメータを略してた場合は
- r0-r3 が入力パラメータとして使用されます
- r0 が出力値として使用されます
- r12 および r14 は破損している可能性があります
という記述があったのでそーゆー事なのだろうと理解することに。
あと、boot.S の解説で .text_boot というセクションがリンカスクリプトによってカーネルイメージのいっちゃん最初に配置されるよう云々、とありますね。あと、boot.S の最初らへんのコードは C の BSS および stack な領域を初期化してますね。そして確かに r0 から r2 は全く操作をしていないことも分かります。
リンカスクリプトについては以下のあたりがアレなのかどうか。
/* Starts at LOADER_ADDR. */ . = 0x8000; _start = .; _text_start = .; .text : { KEEP(*(.text.boot)) *(.text) }
0x8000 が実行開始されるアドレスなのでここにテキスト置いてしかも boot.S を先頭に、という事ですね。あと 4096 で ALIGN してるのは RPi な page size が 4096 だから、という記載もあり。
Hello World kernel
最初の、はコンパイルは通ったんですが、動かす気持ちにはならないですね。次に出てくるソレは serial 経由なハロワとのこと。ふむ。これはシリアルなアレが来ないと試験はできませんですな。とは言え、中身は掘削させて頂きます。
つうかキモは初期化の手順と出力の手順がマニュアルのどこに書いてあるのか、という事になるのかどうか。とは言えマニュアルにはレジスタの仕様が書き連ねてあるだけだな。むむ。
初期化の手順的には
- CR レジスタ 0 書き込み
- GPPUD なレジスタ 0 書き込んで 150 cycle 待機
- GPPUDCLK0 なレジスタ 14 および 15 番目のフラグを立てて 150 cycle 待機
- GPPUDCLK0 なレジスタ 0 書き込み
- ICR レジスタ 0x7FF 書き込み
- IBRD レジスタ 1 書き込み
- FBRD レジスタ 40 書き込み
- LCRH レジスタ 4、5、6 番目のフラグを立てる
- IMSC レジスタ 1、4、5、6、7、8、9、10 番目のフラグを立てる
- CR レジスタ 0、8、9 番目のフラグを立てる
ここまで控えてマニュアル見てみるか。ちなみに uart_putc 手続きでは
という形なのかどうか。
GPIO Pull-up/down の手順
はマニュアル 101p に出てますね。とは言え、14 および 15 なフラグが何にあたるか、というのがアレ。そろそろ出かける仕度をせねば、なので一旦ここでエントリ投入します。
続き
アド部で云々しつつながらで。GPIO14 が TXD0、GPIO15 が RXD0 に割当てられている事はマニュアル 102p から確認。複数の機能にアサインされてますが、特に何らかのスイッチがある訳ではない、という理解で良いのかな。
これで UART 0 な TX/RX を使うことができるようになった、という理解で良いのかな。で、以降で以下の順で云々、なんですが
- ICR レジスタ 0x7FF 書き込み
- ICR は Interrupt Clear Register とありますね
- フラグが全部立ってるので全ての割込みが初期化、なのかどうか
- IBRD レジスタ 1 書き込み
- Integer Baud rate divisor とあります
- FBRD レジスタ 40 書き込み
- ここの設定はコメントにありますね
// Set integer & fractional part of baud rate. // Divider = UART_CLOCK/(16 * Baud) // Fraction part register = (Fractional part * 64) + 0.5 // UART_CLOCK = 3000000; Baud = 115200. // Divider = 3000000/(16 * 115200) = 1.627 = ~1. // Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
- LCRH レジスタ 4、5、6 番目のフラグを立てる
- Line Control Register
- Enable FIFOs、8bits Word length
- IMSC レジスタ 1、4、5、6、7、8、9、10 番目のフラグを立てる
- ここ、割込みの設定みたいですね
- マニュアル 188p および 189p あたり
- Interrupt Mask Set Clear Register
- CR レジスタ 0、8、9 番目のフラグを立てる
- Control Register
- UART enable、TX および RX enable
あと、出力云々なあたりか。
- FR
- DR
- Data Register
うーん、これってこんな作法なのかな。以下な処理の記述になっているので
// wait for UART to become ready to transmit while (1) { if (!(mmio_read(UART0_FR) & (1 << 5))) { break; } } mmio_write(UART0_DR, byte);
transmit FIFO が full になるまで wait という事なの?
とりあえず
Baking Pi 方面に戻ります。
ぐげ
! を見落してました。full でなければ書き込み、なんですねorz