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 経由なハロワとのこと。ふむ。これはシリアルなアレが来ないと試験はできませんですな。とは言え、中身は掘削させて頂きます。
つうかキモは初期化の手順と出力の手順がマニュアルのどこに書いてあるのか、という事になるのかどうか。とは言えマニュアルにはレジスタの仕様が書き連ねてあるだけだな。むむ。
初期化の手順的には

ここまで控えてマニュアル見てみるか。ちなみに 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
    • Flag Register
    • 5 番目のフラグは TXFF とありますね
    • FIFO は enable になってるので _the TXFF bit is set when the transmit FIFO is full_ という事なのか
  • 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