$30 off During Our Annual Pro Sale. View Details »

BareMetalで遊ぶ Raspbeery Pi ミニキャンプ北陸2016ver/BareMetal RaspberryPi Security minicamp Hokuriku 2016

BareMetalで遊ぶ Raspbeery Pi ミニキャンプ北陸2016ver/BareMetal RaspberryPi Security minicamp Hokuriku 2016

セキュリティミニキャンプ北陸2016で利用した講義資料です。

Copyright Toshifumi NISHINAGA
License: CC-BY-SA-NC 4.0

Toshifumi NISHINAGA

May 13, 2018
Tweet

More Decks by Toshifumi NISHINAGA

Other Decks in Programming

Transcript

  1. BareMetal で遊ぶ Raspberry Pi
    ミニキャンプ北陸 ver
    Toshifumi NISHINAGA
    2016/12/04
    この作品はクリエイティブ・コモンズ・表示 - 非営利 - 継承 4.0 国際・ライセンスで提供されています。
    このライセンスのコピーを閲覧するには、 http://creativecommons.org/licenses/by-nc-sa/4.0/ を訪問して下さい。

    View Slide

  2. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    BareMetal 開発ってなに?
    • BareMetal とは?
    • (組み込みの分野では) OS などの入っていないコンピュータのこと
    • BareMetal 開発とは?
    • BereMetal なコンピュータの上で動くプログラムを作っていくこと
    2
    2016/12/04

    View Slide

  3. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    導入〜 L チカは簡単?〜
    • L チカ( LED Blink )とは
    • LED を点滅させるだけの”簡単“なプログラム
    • 低レイヤー版 Hello World
    • Linux の起動した Raspberry Pi では,シェルを叩くだけで”簡
    単”に L チカができる
    • $ sudo echo 47 > /sys/class/gpio/export
    • $ sudo echo out > /sys/class/gpio/gpio47/direction
    • $ sudo sh –c ‘echo 1 > /sys/class/gpio/gpio47/value’
    • $ sudo sh –c ‘echo 0 > /sys/class/gpio/gpio47/value’
    3
    2016/12/04

    View Slide

  4. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    導入〜 L チカは本当に簡単?〜
    • 本当に簡単ですか?
    • ドライバがなかったら?
    • GPIO1 の初期化,設定,出力のための処理を全て書く必要がある
    • Linux が起動していなかったら?
    • CPU の初期化, C 言語が動くための初期化,その他いろいろ行う必要がある
    • 以上の状況でも,同じように L チカは簡単といえますか?
    4
    補足 1: デジタル信号の入出力を行う外部装置(ペリフェラル)
    2016/12/04

    View Slide

  5. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    これからも L チカを簡単にするために
    • 何故 L チカが”簡単に“できるか
    • Raspberry Pi に Linux を移植した人がいる
    • ドライバを書き,簡単に GPIO を使えるようにした人がいる
    • これからも L チカを”簡単”に行っていくためには
    • Linux の移植やドライバ実装を自分たちで行う必要がある
    • 使う側から作る側になるために
    • まずは低レイヤーの学び方を学ぶところから始めよう!
    5
    2016/12/04

    View Slide

  6. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    この講義の目的と得られるもの
    • 低レイヤー知識とその学び方を身につける
    • 電源投入からプログラムが動くまで
    • クロスコンパイル環境の作り方(簡略版)
    • Makefile を使ったプログラムのビルド方法
    • データシートの探し方,読み方
    • ペリフェラルの使い方
    6
    2016/12/04

    View Slide

  7. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    目次
    1. コンピュータ基礎知識
    2. 低レイヤー資料の読み方探し方
    3. クロス開発環境の構築
    4. C 言語を動かそう
    5. LED Blink(L チカ )
    2016/12/04 7

    View Slide

  8. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    コンピュータ基礎知識
    2016/12/04 8

    View Slide

  9. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    コンピュータ基礎知識
    • コンピュータを構成する要素は以下の 2 つに分類される
    • ハードウエア
    • ソフトウエア
    2016/12/04 9

    View Slide

  10. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    ハードウェア
    • コンピュータの目に見える物理的な機械の部分
    • 一般的に,以下の装置によって構成される
    • 中央演算処理装置
    • CPU (大切なので次頁で解説)
    • 主記憶装置
    • メインメモリ (RAM)
    • 補助記憶装置
    • HDD, SSD など
    • 入力装置
    • キーボード,マウスなど
    • 出力装置
    • ディスプレイ,スピーカーなど
    CPU
    主記憶
    入力 出力
    補助記憶
    : データの流れ
    2016/12/04 10

    View Slide

  11. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    中央演算装置 ( 以降, CPU)
    • 演算や制御の中心となる装置
    • 次のような機能が存在する
    • Register
    • 計算に必要な数値を一時的に格納する機能.
    • 計算は基本レジスタに対し行われ,結果もレジスタに入る.
    • レジスタが扱える値は限り 1 がある
    • PC( プログラムカウンタ )
    • 次に実行する命令の場所 ( メモリアドレス 2) を示すカウンタ
    • その他,説明を省略
    2016/12/04 11
    補足 1 : 64-bit マシン (x86_64) なら 64-bit まで.計算結果が 64-bit 以上になる時,溢れた分は ( 基本 ) 消える
    補足 2 : CPU は一般的にメインメモリに置かれたプログラムを逐次実行するようになっている .
    CPU は PC の示す場所から命令を取り出し,実行する.

    View Slide

  12. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    例 : ARM のレジスタ
    • 汎用レジスタ (R0-R12)
    • 計算など自由に使えるレジスタ
    • R0 ~ R12 の 13 本ある
    • スタックポインタ (SP=R13)
    • スタックの先頭メモリアドレスを指すレジスタ
    • リンクレジスタ (LR=R14)
    • 関数の戻りメモリアドレスを指すレジスタ
    • プログラムカウンタ (PC)
    • 次に実行する命令のメモリアドレスを指すレジスタ
    2016/12/04 12

    View Slide

  13. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    ソフトウェア
    • ハードウェアを制御するプログラムのこと
    • 以下のようなものは全てソフトウエアに分類される
    • ファームウェア
    • BIOS や UEFI など
    • OS
    • Windows , Mac , Linux , *BSD など
    • アプリケーション
    • Word や Excel など
    2016/12/04 13

    View Slide

  14. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    実行可能なプログラムの作り方
    1. コンピュータにしてほしいことを書いたソースコードを作る
    2. ソースコード以下の手順で実行可能なプログラムに変換する 1
    1. プリプロセス : ソースコードの文法チェックなどを行う
    2. コンパイル : ソースコードをオブジェクトコードに変換する
    3. リンク : 実行に必要な複数のオブジェクトを結合する
    2016/12/04 14
    補足 1: この一連の工程をビルド (build) や make という

    View Slide

  15. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    ソースコードとオブジェクトコード
    • ソースコード ( 略 : ソース )
    • 人間がコンピュータにやってほしいことを記述したコード
    • 中身はテキスト ( 人間が読める )
    • コンピュータでは直接実行することができない
    • オブジェクトコード ( 略 : オブジェクト )
    • コンピュータで直接実行できる形式のコード
    • 中身は 0 または 1 で構成されたバイナリ ( 普通の人間は読めない )
    • ソースコードはコンパイラを使ってこの形式に変換される
    • この変換することをコンパイルという
    2016/12/04 15

    View Slide

  16. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    コンパイル
    • コンパイラ (compiler) を使ってソースコードをオブジェクト
    コードの形式に変換すること
    2016/12/04 16
    #include

    int main(void)
    {
    print(“hello\
    n”);
    return 0;
    }
    コンパイラ
    010101000010
    111010111010
    101010100101
    010101011010
    101010101010
    101010101010
    101000101110
    101011010110
    10
    ソースコード オブジェクトコード

    View Slide

  17. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    リンク
    • リンカ (linker) を使ってプログラムの実行に必要な複数のオブ
    ジェクトを結合すること
    • プログラムをメモリのどこに置けばよいかなどの設定も行う
    2016/12/04 17
    リンカ
    0101
    0100
    0010
    オブジェクトコード
    オブジェクトコード
    0101
    0100
    0010
    0101
    0100
    0010
    010101000010
    111010111010
    101010100101
    010101011010
    101010101010
    101010101010
    101000101110
    101011010110
    10

    View Slide

  18. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Tips: コンパイルとビルド
    • Q.
    • gcc でコンパイルするとそのまま実行可能ファイルができるのはな
    ぜ?
    • 「ビルド」 と 「コンパイル」 は同じ意味ってこと?
    • A.
    • Linux 等で特にオプションを付けずに実行すると,コンパイルとリン
    クが自動で行われ, a.out という実行可能ファイルが得られます
    • 例 : gcc hogehoge.c
    • -c オプションを付けるとコンパイルだけ行えます
    • gcc –c hogehoge.c
    • 「ビルド」 と 「コンパイル」 は厳密には別ですが,同じ意味で使って
    いる人も多いのであまり気にしなくて良いと思います.
    2016/12/04 18

    View Slide

  19. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    低レイヤー資料の
    読み方探し方
    2016/12/04 19

    View Slide

  20. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    低レイヤー資料の読み方探し方
    • 今回使用する Raspberry Pi は ARM アーキテクチャの SoC(Syst
    em on Chip) を使用しているので,それに関連する資料を集め

    • しかし……
    • ARM の SoC は資料が各所にばらけていて集めづらい
    • 理由
    • CPU コアやアーキテクチャを設計している所( ARM )と
    SoC を製造している所( Broadcom など)が違うため
    • 資料を探す前に SoC , CPU コア, CPU アーキテクチャの違いを学ぶ
    2016/12/04 20

    View Slide

  21. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    SoC, CPU, CPU アーキテクチャの違い
    • SoC(System on Chip)
    • 必要なシステム全てを1つのチップに集積する半導体の設計手法
    • 本資料では CPU やペリフェラル(外部装置)を集積したものを SoC
    と呼ぶ
    • CPU コア(プロセッサ)
    • SoC の中で計算等を行う部分
    • CPU アーキテクチャ
    • CPU コアの基礎設計
    • ここが同じ CPU は命令セットなどの基礎設計部が共通.
    • ペリフェラル
    • UART (シリアル通信)等を行うための外部装置.
    • CPU と一緒に SoC へ搭載される.
    • ARM 社またはチップベンダ (Broadcom 社など ) が設計している
    21
    SoC
    CPU コア
    UART Timer USB SPI
    2016/12/04

    View Slide

  22. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    RasPi の SoC , CPU ,アーキテクチャ
    • SoC(System on Chip)
    • Broadcom 社の BCM2835
    • CPU コア(プロセッサ)
    • ARM1176JZF-S
    • 補足 : ARM11 はプロセッサファミリ名
    • CPU アーキテクチャ
    • ARMv6KZ アーキテクチャ
    2016/12/04 22
    SoC(BCM2835)
    CPU コア
    (ARM1176JZF-S)
    UART Timer USB SPI

    View Slide

  23. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    各資料の場所
    • SoC
    • 基本は SoC を製造しているメーカー(チップベンダ)のサイトにある
    • 例外: BCM2835 の資料は RasPi の公式サイトにある
    • https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peri
    pherals.pdf
    • CPU コア ( プロセッサ ) , CPU アーキテクチャ
    • ARM 社のサイトにある.アーキテクチャは要登録.
    • http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301h/DDI0301H_arm1176jzfs_r0p7_trm.p
    df
    • https://silver.arm.com/download/download.tm?pv=1057882
    • ペリフェラル
    • 基本的には SoC の資料に書かれている
    • ARM 社の作ったペリフェラルについては ARM 社のサイトにも資料がある
    • こちらの方がわかりやすい場合もある
    23
    2016/12/04

    View Slide

  24. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    資料の読み方
    1. 目次を見て知りたい機能について書かれたページ番号を見つける
    2. 初めに特徴 (feature) や概要 (outline, summary) ,簡単な使い方
    (How to use 的なもの ) が書かれているので,大まかな機能や使
    い方を把握する
    • 図がある場合は図を先に見て,頭のなかにイメージを作る
    3. 手順 1. と 2. を繰り返し,目的の機能を見つけ,読んでいく
    • それでもわからない時
    • Google などで検索して,解説している記事や,その機能を使って実装され
    たコードを読んで理解する
    2016/12/04 24

    View Slide

  25. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    クロス開発環境の構築
    2016/12/04 25

    View Slide

  26. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    セルフコンパイルとクロスコンパイル
    • セルフコンパイル
    • プログラムをコンパイルするコンピュータ ( ホスト ) の CPU アーキテクチャ
    と,プログラムを実行するコンピュータ(ターゲット)の CPU アーキテク
    チャが同じコンパイルのことをセルフコンパイル,開発のことをセルフ開発
    という.
    • クロスコンパイル
    • ホストとターゲットが異なるコンパイルをクロスコンパイル,開発のことを
    クロス開発という.
    • ToolChain( 開発環境 )
    • 開発に必要なもの (binutils, gcc 等 ) をまとめて toolchain という
    • クロス開発環境のことは cross toolchain という
    • 「ターゲットアーキテクチャ名 cross toolchain 」等で検索すると情報が見つかる
    2016/12/04 26

    View Slide

  27. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    なぜクロス開発環境が必要か
    • パッケージ管理ソフトで入れられるのは基本セルフ開発環境の

    • ホストのパソコンは x86_64 アーキテクチャ,
    ターゲットの Raspberry Pi は ARM アーキテクチャ
    なので,クロス開発環境が必要
    27
    2016/12/04

    View Slide

  28. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : クロス開発環境構築
    • ミニキャンプではこの節の残りの説明・演習を省略します.
    • クロス開発環境は予めビルドを行い,パスも通してあります.
    • 興味のある方は,後日試してみてください.
    2016/12/04 28

    View Slide

  29. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    クロス開発環境の作り方
    • ビルド済み環境 (Prebuild toolchain) を持ってくる
    • メリット :ダウンロードして展開するだけで利用できてお手軽
    • デメリット :特定環境用のものがない場合がある
    • 自分でビルドする(今回行ったのはこちら)
    • メリット : 特定環境に特化した toolchain が作れる.
    • デメリット : ビルドのための学習コストや時間がかかる.
    29
    2016/12/04

    View Slide

  30. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Tips: ARM のビルド済みクロス開発環境
    • CodeSourcery
    • Lite edition は無料.
    • Linaro Toolchain
    • https://wiki.linaro.org/WorkingGroups/ToolChain
    • Raspberry Pi 公式
    • https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/gc
    c-linaro-arm-linux-gnueabihf-raspbian-x64
    30
    詳細は http://elinux.org/Toolchains 参照
    2016/12/04

    View Slide

  31. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    クロス開発環境を自分で作る
    • 普通のやり方
    • 以下の手順で作る
    1. binutils (アセンブラ等)をビルドする
    2. お互いに依存する gcc と libc1 を交互にビルドする
    • 便利なツールを使って作るやり方
    • Crosstool-NG( ← 今回つかったのはこちら )
    • Yocto2
    • Buildroot2
    31
    補足 1: C 言語の基本的な関数 (printf など ) を提供するライブラリ
    補足 2: どちらも組み込み Linux イメージを作るためのプロジェクト,ツール
    2016/12/04

    View Slide

  32. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Crosstool-NG
    • クロス開発環境を作るための
    ツール
    • TUI でアーキテクチャ等を設定
    すれば,後は自動でクロス開発
    環境ができる
    32
    2016/12/04

    View Slide

  33. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : クロス開発環境構築
    • 作業用ディレクトリを作る
    • $ mkdir ~/ctng && cd ~/ctng
    • テンプレートを取得
    • $ ct-ng arm-unknown-eabi
    • 細かい設定に入る
    • $ ct-ng menuconfig
    • 細かい設定
    • MMU を無効化
    • Target options -> Use the MMU のチェックを外す
    • アーキテクチャを設定
    • Target options -> Emit assembly for CPU に arm1176jzf-s をセット
    • システムコール実装の無効化
    • C-library -> Disable the syscalls supplied with newlib
    がチェックされていることを確認(理由は BareMetal で遊ぶ Raspberry Pi, 6 章参照)
    33
    2016/12/04

    View Slide

  34. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : クロス開発環境構築
    • ビルド
    • $ ct-ng build.4
    • Tips: 4 は並列ビルド数
    • パスを通す
    • 1 時間ほど待つと $HOME/x-tools/arm-unknown-eabi/ 以下にクロス
    開発環境ができるので,以下のコマンドでパスを通す
    • $ echo ’export PATH=$PATH:$HOME/x-tools/arm-unknown-eabi/bin’ >> $HOME/.bashrc
    • $ source $HOME/.bashrc
    34
    2016/12/04

    View Slide

  35. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    C 言語を動かそう
    2016/12/04 35

    View Slide

  36. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    開発用ディレクトリ
    • ホームディレクトリ以下に「 ledblink 」という開発用ディレク
    トリがあります.
    • 以降,ソースコード等はこの ledblink ディレクトリ以下に置い
    て作業してください
    36
    2016/12/04

    View Slide

  37. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    BareMetal で C 言語を動かすためには
    1. 電源 ON からプログラムが動くまでの動作を知る
    2. リンカスクリプトを作る
    3. スタートアップコードの作成
    1. スタックポインタの設定
    2. BSS のクリア
    3. main を呼ぶ
    4. Makefile を作る
    5. make する
    2016/12/04 37

    View Slide

  38. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    電源 ON からプログラムが動くまで
    • Raspberry Pi の場合
    1. 電源 ON
    2. GPU が SD カードからファームウェアを読み込んで実行を開始する
    3. GPU がメインメモリの有効化などを行う
    4. GPU が SD カードから kernel.img(config.txt で書き換え可 ) をメイ
    ンメモリの 0x8000 番地にロードする
    5. CPU のプログラムカウンタ (PC) を 0x8000 に設定して CPU に処理を
    渡す
    6. kernel.img が 0x8000 番地から実行を開始する
    2016/12/04 38
    参考 URL: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=6685

    View Slide

  39. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    リンカスクリプトを作る
    • リンカスクリプトとは?
    • リンカに対しプログラムをメモリのどこに置くかなど指示するための
    スクリプト
    • 以下の様なことを指示することができる.
    • セクション(後述)の配置
    • エントリポイントとなるシンボル名(関数名)
    • 何故リンカスクリプトが必要なの?
    • 基本的にマイコン等のメモリ配置はターゲットごとばらばらなので,
    リンカはプログラムをメモリのどこに置けばよいかわからない.
    • なので,リンカスクリプトを書いて各ターゲットのメモリ配置を教え
    る必要がある
    39
    2016/12/04

    View Slide

  40. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    リンカスクリプトの役者紹介
    • OUTPUT_ARCH( arch )
    • アーキテクチャの指定を行う.今回は arm を指定
    • ENTRY( entry point )
    • プログラムの実行開始地点となるシンボルを指定する.今回は _start を指定.
    • MEMORY
    • メモリ空間及びその空間の属性(読み書き可など)を定義する.
    • ROM と RAM が分かれているような環境(マイコン等)では必須.
    • RAM のみ用いる今回は書かなくても動いているが,本当は書いたほうが良い
    • SECTION { ... }
    • プログラムの各セクション配置を定義する.最低限 以下を書けば動く ( 動いた ) .
    • .text : 実行可能プログラムのあるセクション
    • .data: 初期値を持つ変数の値が格納されるセクション
    • .rodata: 定数が格納される.書かなければ .data に統合される.
    • .bss: 初期値を持たない変数等が格納されるセクション.
    40
    2016/12/04

    View Slide

  41. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    リンカスクリプトの役者紹介
    • ALIGN(4096)
    • メモリの区切り (Align) を 4096byte に設定する.
    • . = 0x00008000;
    • 現在地点のアドレスを設定する.上記の次の行に書かれたセクションは,設定されたアド
    レスから開始される.
    • __hoge__ = . ;
    • 現在地点のアドレスにシンボルをつける.
    • シンボルをつけたアドレスは,アセンブリや C 言語等から利用できる.
    • C 言語で利用する例: extern void *__hoge__;
    • BSS 領域(後述)のクリア等のために使用する.
    • その他について
    • 実際に書かれたリンカスクリプトを読んで覚える
    • 坂井さんの「リンカ・ローダー実践開発テクニック * 」などを読む
    41
    * 坂井 弘亮 , 「リンカ・ローダー実践開発テクニック」 ,CQ 出版社
    2016/12/04

    View Slide

  42. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : リンカスクリプトを読む
    OUTPUT_ARCH(arm)
    ENTRY(_start)
    SECTIONS
    {
    . = 0x8000;
    .text : { *(.text*) }
    . = ALIGN(4096);
    __rodata_start = .;
    .rodata : { *(.rodata*) }
    . = ALIGN(4096);
    __rodata_end = .;
    __data_start = . ;
    .data : { *(.data*) }
    . = ALIGN(4096);
    __data_end = . ;
    __bss_start = . ;
    .bss : { *(.bss*) }
    . = ALIGN(4096);
    __bss_end = . ;
    }
    42
    2016/12/04

    View Slide

  43. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    リンカスクリプトで作ったメモリ配置
    43
    0x00000000
    0xffff
    .text
    0x00008000
    .rodata
    メモリアドレス シンボル名
    .data
    .bss
    __rodata_start
    __rodata_end
    __data_start
    __data_end
    __bss_start
    __bss_end
    2016/12/04

    View Slide

  44. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    スタートアップコードの作成
    • C 言語を動かせるようにするために,
    以下を行うスタートアップコード (start.S) を書く
    • CPU モードの設定(今回は省略)
    • ベクタテーブルの設定(今回は省略)
    • スタックポインタの設定
    • BSS のクリア
    • main へ飛ぶ
    • 以降,各設定の説明及び記述例を示します.
    • 最初にアセンブリコードの書き方もちょこっと示します.
    44
    2016/12/04

    View Slide

  45. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Tips: アセンブリコードの用語説明
    • ラベル
    • ラベルが宣言された場所のメモリアドレスを値として持たせることができる.
    • 関数名やループのジャンプ先の指定のために利用する
    • 書き方 (_start 関数の定義 )
    • _start:
    • グローバル宣言
    • ラベルを別のソースからも参照できるようにする
    • 書き方 (_start 関数をグローバル宣言する )
    • .global _start
    • アライメント
    • コードのアライメントを byte 単位で設定する .
    ARM 命令の命令長は 32-bit(4-byte) なので 4 を設定する.
    • 書き方
    • .align 4
    45
    2016/12/04

    View Slide

  46. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    start.S のテンプレート
    .align 4
    .global _start
    _start:
    // ここに初期化のコードを書く
    // main を呼ぶ
    // 無限ループ
    b .
    46
    2016/12/04

    View Slide

  47. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    スタックポインタ (sp) の設定
    • C 言語は自動変数をメインメモリ
    上のスタック (Stack) 呼ばれる場
    所に置く
    • スタックはスタックポインタの初
    期メモリアドレスから,スタック
    ポインタの示すメモリアドレスま
    でを利用する
    • スタックポインタの初期メモリア
    ドレスを正しく設定しないと,メ
    モリアクセス違反でプログラムが
    動かなくなる
    2016/12/04 47
    プログラム
    スタック
    成長方向
    0x000000
    00
    0xffff
    スタックの初期アドレス
    スタックポインタのアドレス

    View Slide

  48. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    参考 : ヒープメモリとスタックメモリ
    • ヒープ (Heap)
    • プログラムが動的に獲得するメモ

    • malloc 関数等で確保して使う
    • 成長方向は(基本)下位アドレス
    から上位アドレス.
    • スタック (Stack)
    • 自動変数,引数,戻りアドレスな
    どを格納するためのメモリ
    • 成長方向は(基本)上位アドレス
    から下位アドレス.
    48
    プログラム
    ヒープ
    スタック
    成長方向
    0x000000
    00
    0xffff

    View Slide

  49. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    スタックポインタ (sp) の設定
    • Raspberry Pi(512MB モデル ) のメモリは
    0x00000000 – 0x20000000
    までを自由に利用可能
    • ただし一部は GPU が利用する
    • デフォルトでは 64MiB* , 最大 448MiB .
    • よって, sp には 0x1c000000 をセットする
    • ldr sp, =0x1c000000
    49
    GPU(64MiB)
    0x000000
    00
    0xffff
    Stack
    0x1c0000
    00
    .text
    .rodata
    .data
    .bss
    *: https://www.raspberrypi.org/documentation/confguration/confg-txt.md
    参考 URL に書かれた単位は MB ですが, MiB のほうが正しい……はず.
    0x200000
    00
    2016/12/04

    View Slide

  50. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    start.S(SP 設定後 )
    .align 4
    .global _start
    _start:
    // ここに初期化のコードを書く
    ldr sp, =0x1c000000
    // main を呼ぶ
    // 無限ループ
    b .
    50
    2016/12/04

    View Slide

  51. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    BSS のクリア
    • BSS
    • 初期値を持たない変数(グローバル変数)等が格納されるセクション
    • 0 で初期化する必要がある.
    • BSS クリアの方法
    • リンカスクリプトで付けたシンボル名を用いて,
    __bss_start から __bss_end までを 0 で初期化する
    51
    2016/12/04

    View Slide

  52. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    BSS 領域をクリアするアセンブリコード
    • アセンブリコード
    mov r0, #0 // r0 <- 0
    ldr r1, =__bss_start // r1 <- __bss_start
    ldr r2, =__bss_end // r2 <- __bss_end
    loop:
    cmp r1, r2 // r1 - r2 を行い,フラグをセットする
    beq loop_end // r1 == r2 なら loop_end に飛ぶ
    str r0, [r1] // r1 の指すアドレスのメモリに r0 の値をストア
    add r1, r1, #4 // アドレスを増加
    b loop // loop へ無条件ジャンプ
    loop_end:
    // その後の処理を書く
    52
    ※ 「 // 」以降はコメント
    2016/12/04

    View Slide

  53. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    start.S(BSS 初期化後 )
    .align 4
    .global _start
    _start:
    // ここに初期化のコードを書く
    ldr sp, =0x1c000000
    mov r0, #0
    ldr r1, =__bss_start
    ldr r2, =__bss_end
    loop:
    cmp r1, r2
    beq loop_end
    str r0, [r1]
    add r1, r1, #4
    b loop
    loop_end:
    // mainを呼ぶ
    b . // 無限ループ
    53
    2016/12/04

    View Slide

  54. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    main 関数に飛ぶ
    • 初期設定完了後は main 関数に飛ぶ
    • BL(Branch with Link) 命令を使う
    • 例 : bl main
    • 補足 : BL 命令について
    • BL 命令は分岐後に戻ってきたい場合に用いる ( 関数呼び出しなど)
    • BL 命令は次の命令のアドレス (pc+4) を lr に保存した後,ジャンプする
    • ジャンプ後, BX 命令を用いて bx lr のようにすると,
    分岐した場所の次の命令に戻れる
    54
    _start
    main
    bl main bx lr
    2016/12/04

    View Slide

  55. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    start.S(BSS 初期化後 )
    .align 4
    .global _start
    _start:
    // ここに初期化のコードを書く
    ldr sp, =0x1c000000
    mov r0, #0
    ldr r1, =__bss_start
    ldr r2, =__bss_end
    loop:
    cmp r1, r2
    beq loop_end
    str r0, [r1]
    add r1, r1, #4
    b loop
    loop_end:
    bl main // mainを呼ぶ
    b . // 無限ループ
    55
    2016/12/04

    View Slide

  56. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Tips: 引数の渡し方と戻り値の返し方 (ARM
    編 )
    • 関数呼び出しの引数の渡し方
    • 引数が4つ以下なら,
    第1引数から順に R0 から R3 レジスタに入れて渡す.
    • 引数が5つ以上の場合は,
    第5引数からはスタックに積んで送る.
    • 戻り値の返し方
    • 返り値が 32-bit 以下で表せるなら, R0 レジスタに入れて返す.
    56
    参考 (5.4, 5.5 節 ): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
    2016/12/04

    View Slide

  57. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Tips: Caller/Callee saved registers
    • Caller saved registers
    • 引数渡しに使われるレジスタ (R0-R3) など,
    関数を呼び出す側が内容を保存するレジスタのこと.
    • つまり,関数呼び出し後は値の同一性が保証されないレジスタ
    • Callee saved registers
    • 呼び出された関数側で値を保証しなければならないレジスタの事.
    • Caller saved registers 以外のレジスタ (R4-R12) のうち,関数内で上書き使用す
    るレジスタを必要に応じて保存する.
    • Caller saved registers は関数の初めにスタックに保存してから使い,
    最後にスタックから復元する.
    57
    2016/12/04

    View Slide

  58. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Tips: Caller/Callee saved registers
    • 関数呼び出し及び戻り時のレジスタ保護イメージ
    58
    関数 A
    関数 B
    R0-R3 をスタックに退避
    処理の流れ
    スタックから R0-R3 を復

    関数 B 呼び出し
    R4-R12 の中で使用する
    レジスタをスタックに退避
    退避したレジスタを復元
    処理
    2016/12/04

    View Slide

  59. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Makefile を書く
    • Makefile とは?
    • プログラムをビルドするためのルール等を記すファイル
    • このファイルを make コマンドに読み込ませると,
    書かれたルールに従ってビルドを行ってくれる.
    • Makefile のいいところ
    • 依存関係を調べ,更新のあるファイルだけをビルドしてくれる
    • 複数に別れたコードも一括でビルドできる
    • 長く使われているので資料が多い(←大切)
    59
    2016/12/04

    View Slide

  60. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : Makefile を書く
    • ミニキャンプではこの節の残りの説明・演習を省略します.
    • 興味のある方は,後日試してみてください.
    2016/12/04 60

    View Slide

  61. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Makefile の基本的な書き方
    • ビルドルールの基本形
    • ターゲット : 依存関係 ( 複数可 )
    コマンド
    コマンド
    ...
    61
    参考 URL: https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html#Pattern-Intro
    2016/12/04

    View Slide

  62. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    • ビルドルールの例
    • ldscript.lds, source.c から target を作る
    2016/12/04 62
    target を作る
    ビルドルール
    sourc
    e.c
    ldscti
    pt.ld
    s
    010101000010
    111010111010
    101010100101
    010101011010
    101010101010
    101010101010
    101000101110
    101011010110
    10
    target
    target: ldscript.lds source.c
    arm-unknown-eabi-gcc -c -o source.o source.c
    arm-unknown-eabi-ld -T ldscript.lds source.o -o target

    View Slide

  63. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Makefile の基本的な書き方
    • ルールを分けることも可能
    2016/12/04 63
    target: ldscript.lds source.c
    arm-unknown-eabi-gcc -c -o source.o source.c
    arm-unknown-eabi-ld -T ldscript.lds source.o -o target
    target: ldscript.lds source.o
    arm-unknown-eabi-ld -T ldscript.lds source.o -o target
    source.o: source.c
    arm-unknown-eabi-gcc -c -o source.o source.c
    分離

    View Slide

  64. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    自動変数
    • 自動変数とは
    • ターゲットや依存ファイルの名前を省略して書くためのもの
    • 以下の3つはよく使うので覚えておくと便利
    • $@ : ターゲットファイル名
    • $< : 依存ファイル名 ( 一番最初のみ )
    • $^ : 依存ファイル名 ( 全部 )
    64
    2016/12/04

    View Slide

  65. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    source.o: source.c
    arm-unknown-eabi-gcc -c -o source.o source.c
    Makefile の基本的な書き方
    • 自動変数使用例
    2016/12/04 65
    source.o: source.c
    arm-unknown-eabi-gcc –c -o $@ $^
    自動変数を使って書き直し
    • source.c は $^ に置

    • source.o は $@ に
    置換

    View Slide

  66. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    変数
    • 変数
    • コンパイラ名やコンパイルオプション等を入れた変数を定義できる
    • メリット
    • ルールを短く書ける
    • 共通の設定を一度に変更できる ( 最適化レベル変更などの際便利 )
    • 文法
    • CFLAGS= -Os # 変数を定義
    • CFLAGS+= -g # 変数に追加
    • CPPFLAGS= $(CFLAGS) # 変数を呼び出して変数を定義
    66
    2016/12/04

    View Slide

  67. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    source.o: source.c
    arm-unknown-eabi-gcc –c -o $@ $^
    Makefile の基本的な書き方
    • 変数使用例
    2016/12/04 67
    CC=arm-unknown-eabi-gcc
    source.o: source.c
    $(CC) –c -o $@ $^
    変数 CC でコンパイラを指定

    View Slide

  68. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    暗黙のルール (implicit rule)
    • 暗黙のルール
    • よく使うルールを暗黙のルールとして定義しておくと,
    詳細を指定しなくても暗黙のルールで処理できる.
    68
    参考 URL: https://www.gnu.org/software/make/manual/make.html#Implicit-Rules
    2016/12/04

    View Slide

  69. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    target: ldscript.lds source.o
    $(LD) -T $^ -o $@
    source.o: source.c
    $(CC) –c -o $@ $^
    Makefile の基本的な書き方
    • 暗黙のルール使用例
    2016/12/04 69
    .c.o:
    $(CC) –c $< –o $@
    target: ldscript.lds source.o
    $(LD) -T $^ -o $@
    .c から .o の変換は
    暗黙のルールで処理

    View Slide

  70. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    サフィックスルール
    • サフィックスルール (.SUFFIXES)
    • 「 .o は .c から作られる」など,
    あるターゲットを得るためには何をビルドすべきかの関係を示すため
    のルール
    • 例 : .bin が .elf からビルドされることを示す
    • .SUFFIXES: .elf .bin
    70
    2016/12/04

    View Slide

  71. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    その他
    • all ルール
    • make コマンドを引数無しで実行したときに,処理したいルールを列挙す
    るために用いられることの多いルール名
    • Makefile に書かれたルールの先頭に定義する必要がある
    • 引数無しで make コマンドを実行すると,先頭にあるルールが実行される
    • 例 : (make を叩くと target を作って欲しい場合 )
    • all: target
    • clean ルール
    • ビルドしたファイル等を削除するためによく用いられるルール名
    • 例 :
    • clean:
    rm target source.o
    71
    2016/12/04

    View Slide

  72. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Makefile を書くときの注意
    • 改行コードに CR+LF を使うとエラーになる
    • Linux では改行コードが LF なので多分注意する必要はない
    • Windows の場合は CR+LF の場合が多いので,注意すること
    • コマンドの前のインデントはスペースでなくタブを使う
    • タブの中にスペースがあったりすると,エラーとなる.
    72
    2016/12/04

    View Slide

  73. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : Makefile を読む
    • 次スライドの Makefile を読み,以下の質問に答えてください
    1. 変数 $(CC) にはどんな値が入っていますか?
    2. .c.o のルールは何をコンパイルして,何を作りますか?
    3. myprog.bin を作るにはどのソースコードが必要ですか?
    2016/12/04 73

    View Slide

  74. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : Makefile を読む
    CROSS= arm-unknown-eabi-
    CC= $(CROSS)gcc
    LD= $(CROSS)ld
    OBJCOPY= $(CROSS)objcopy
    OBJS=start.o main.o
    CFLAGS = -mfloat-abi=soft -mlittle-endian -fno-builtin –nostartfiles -std=c11
    LDFLAGS = -static –nostdlib
    .SUFFIXES: .elf .bin
    all: myprog.bin
    myprog.elf: $(OBJS)
    $(LD) $(LDFLAGS) -T ldscript.lds $^ `$(CC) -print-libgcc-file-name` -o $@
    .elf.bin:
    $(OBJCOPY) -O binary $< $@
    .c.o:
    $(CC) $(CFLAGS) -c $< -o $@
    .S.o:
    $(CC) $(CFLAGS) -c $< -o $@
    clean:
    $(RM) *.o *.bin *.elf
    74
    2016/12/04

    View Slide

  75. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Tips: libgcc をリンクする理由
    • libgcc とは
    • C 言語を動かすために必要な基本関数群をもつライブラリ
    • gcc でコンパイルしたプログラムには必ずリンクする必要がある
    • なぜリンクする必要があるの?
    • ソースコードのコンパイル時に演算をそのまま命令に変換することが
    出来ない場合がある
    • ARM は最近まで除算命令 (div) などを持っていなかった
    • libgcc にはこのような演算をソフトウェアでシミュレーションするプ
    ログラムなどが含まれており,必ずリンクする必要がある.
    75
    2016/12/04

    View Slide

  76. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : main.c を作る
    • 以下の様な何もしないコードを main.c として保存してくださ
    い.
    #include
    int main(void) {
    return 0;
    }
    76
    2016/12/04

    View Slide

  77. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : ビルドしてみる
    • ビルド
    • make コマンドを実行して myprog.bin ができていることを確認してく
    ださい
    • 逆アセンブリ結果を見る
    • 以下のコマンドで .elf を逆アセンブルしてコードを読んでみてくださ

    • arm-unknown-eabi-objdump -D myprog.elf
    77
    2016/12/04

    View Slide

  78. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    逆アセンブル結果
    78
    2016/12/04

    View Slide

  79. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    逆アセンブル結果
    79
    .text が 0x8000 か

    開始している
    0x1c000000 が
    sp に設定されている
    BSS 初期化が完了したら
    main に飛ぶ
    2016/12/04

    View Slide

  80. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : ビルドしたコードを動かしてみる
    1. ( 済 )FAT でフォーマットした SD カードにブートのためのファイルを入れ

    • 取得元 : https://github.com/raspberrypi/firmware/tree/master/boot
    • 必要なファイル ( 予め $HOME/sdcard 以下にダウンロード済み ):
    • start*.elf
    • fixup*.dat
    • bootcode.bin
    • LICENCE.broadcom
    • config.txt: 以下を記述 *
    • kernel=myprog.bin
    2. myprog.bin を SD カードに入れる
    3. SD カードを Raspberry Pi に刺して,電源を入れる
    • ただし,無限ループするだけなので,現在はまだ何も起こらない
    80
    * 参考 : https://www.raspberrypi.org/documentation/confguration/confg-txt.md
    2016/12/04

    View Slide

  81. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    LED Blink(L チカ )
    2016/12/04 81

    View Slide

  82. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    LED Blink
    • L チカ( LED Blink )とは ( 再掲 )
    • LED を点滅させるだけの”簡単“なプログラム
    • 低レイヤー版 Hello World
    • BareMetal 環境では GPIO のペリフェラルを直接制御して行う
    • そのために ...
    • メモリマップド I/O について知る
    • GPIO レジスタの使い方を知る
    82
    2016/12/04

    View Slide

  83. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Raspberry Pi の LED
    • Raspberry Pi Type B+ は
    ACT LED が GPIO47 に繋がれて
    いるので, L チカに使える
    • Tips: Type-B では GPIO16 に ACT L
    ED が繋がれていた
    • GPIO47 を Low にすると点灯,
    High にすると消灯する
    83
    2016/12/04

    View Slide

  84. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    Memory Mapped I/O(MMIO)
    • Memory Mapped I/O(MMIO)
    • ペリフェラルの制御レジスタが主記憶と同じメモリアドレス上に割り当てられてい
    る方式.
    • 制御レジスタが割り当てられたメモリアドレスに値を書き込むと,
    値が制御レジスタにセットされる
    • Raspberry Pi はアドレス 0x20000000※ からペリフェラルがマップされている
    • BCM2835-ARM-Peripherals.pdf, pp.5 の図 , ARM Physical Address を参照
    • ※ 注意
    • マニュアルに書かれている各ペリフェラルのアドレスは
    ARM Bus Address のアドレス (0x7E000000 開始 ) となっている
    • Raspberry Pi 起動時のアドレスは ARM Physical Address に変換されているので, 0
    x7E...... は 0x20...... に読み替えて使用する.
    84
    Tips: MMIO の他に I/O マップド I/O という方式もある
    2016/12/04

    View Slide

  85. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    GPIO
    • General Purpose I/O(GPIO)
    • 汎用的に使える信号の入出力を行うための I/O ペリフェラル
    • LED を接続して出力にしたり,スイッチを接続して入力にしたり
    • High(RasPi では 3.3V) や Low(0V) の信号を出力できる
    • Alternative mode で SPI や I2C ペリフェラルの入出力にも使用できる
    • 資料の場所
    • Raspberry Pi のペリフェラルドキュメント (pp.89-105)
    • BCM2835-ARM-Peripherals.pdf
    • https://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Periph
    erals.pdf
    85
    2016/12/04

    View Slide

  86. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    ペリフェラルマニュアルの読み方
    1. Index (目次)から,希望のペリフェラルのページを見つける
    • GPIO については pp.89-105
    2. 最初の 1 ページ目 (pp.89) に概要が書かれているので,
    そこから大まかな内容を把握する.
    3. 節の最初か最後に簡単な使い方 (How to use 的なもの ) が書かれてい
    ることがあるので,それを探す
    • 残念ながら GPIO については無い……
    4. 各レジスタの説明を読む
    5. それでもわからないことは, Web で調べる
    • 公式 Forum や StackOverflow 等に書いてあることがある
    • Linux や U-Boot 等の既存コードを読むとわかることもある
    86
    2016/12/04

    View Slide

  87. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    調べること
    • GPIO ペリフェラルのベースアドレス
    • よくある書き方
    • オフセットのみ書かれているもの.ベースアドレス + オフセット で計算する.
    • 一覧表に書かれている
    • 各種 GPIO 制御レジスタのメモリアドレス
    • よくある書き方
    • ベースアドレスと同じ
    • 各種 GPIO 制御レジスタの役割と使い方
    • よくある書き方
    • 各種レジスタ説明の一番最初に書かれていることが多い
    87
    2016/12/04

    View Slide

  88. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    BCM2835 の GPIO 概要
    • 標準的な I/O は以下のレジスタを用いて行う
    • GPFSEL
    • GPIO の入出力モードを設定するレジスタ
    • GPSET
    • GPIO の出力を High に設定するレジスタ
    • GPCLR
    • GPIO の出力を Low に設定するレジスタ
    • GPLEV
    • GPIO の入力レベルを取得するレジスタ
    ( 詳細説明は省略 )
    88
    2016/12/04

    View Slide

  89. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    GPFSEL[0-5]
    • GPFSEL(GPio Function SELect)
    • GPIO の入出力モードを設定する 32-bit レジスタたち
    • アドレスは 0x20200000 から 24-byte(32-bit(4-byte) x 6)
    • 1 つのレジスタあたり 10 ポートの設定を担当する
    • 1 つの GPIO のモードを 3-bit で設定する
    • 000: Input
    • 001: Output
    • 以下省略( BCM2835-ARM-Peripherals.pdf , pp.92, Table 6-3 等を参照)
    • 例: GPIO47(GPFSEL4) を Output にする
    • *((uint32_t *)(0x20200010) &= ~(uint32_t)(0x07 << (7 * 3)); // GPIO47 に対応する 3bit をクリア
    • *((uint32_t *)(0x20200010) |= (uint32_t)(0x01 << (7 * 3)); // GPIO47 に対応する 3bit を 001 にセット
    89
    2016/12/04

    View Slide

  90. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    GPSET[0-1]
    • GPSET[0-1]
    • GPIO を High にするレジスタ
    • アドレスは 0x2020001C から 8-byte
    • GPSET1 は GPIO53-32, GPSET0 は GPIO31-0 を担当
    • GPSET0 から右詰めで 1-bit ずつが各 GPIO に対応する
    • 例 : GPIO47 を High にする
    • *(uint32_t *)0x20200020 = 1 << (47 - 32);
    90
    2016/12/04

    View Slide

  91. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    GPCLR[0-1]
    • GPCLR[0-1]
    • GPIO を Low にするレジスタ
    • アドレスは 0x20200028 から 8-byte
    • GPCLR1 は GPIO53-32, GPCLR0 は GPIO31-0 を担当
    • GPCLR0 から右詰めで 1-bit ずつが各 GPIO に対応する
    • 例 : GPIO47 を Low にする
    • *(uint32_t *)0x2020002C = 1 << (47 - 32);
    91
    2016/12/04

    View Slide

  92. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    LED Blink の手順
    1. GPIO47 のモードを,
    GPFSEL レジスタで Output(0x01) にセットする
    2. GPSET レジスタの GPIO47 に対応するビットに 1 をセットして,
    GPIO47 の出力を High にする
    3. for 文を空回しして 500ms 程度待つ
    4. GPCLR レジスタの GPIO47 に対応するビットに 1 をセットして,
    GPIO47 の出力を Low にする
    5. for 文を空回しして 500ms 程度待つ
    6. 手順 2. に戻る
    92
    2016/12/04

    View Slide

  93. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : LED Blink してみる
    • main.c に LED Blink を行うコードを書いてみましょう
    • 書けたら以下の手順で動かしてみましょう
    1. make する
    2. ( エラーが出た場合 ) プログラムを直して手順 1. に戻る
    3. myprog.bin を Raspberry Pi の SD カードに入れる
    4. Raspberry Pi の電源を抜き差しして再起動する
    5. LED 点滅してなかったらプログラムを直して手順 1. に戻る
    93
    2016/12/04

    View Slide

  94. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : LED Blink してみる
    • GPIO47 のモードを Output にする
    2016/12/04 94
    #include
    int main(void) {
    *((uint32_t *)(0x20200010)) &= ~(uint32_t)(0x07 << (7 * 3));
    *((uint32_t *)(0x20200010)) |= (uint32_t)(0x01 << (7 * 3));
    return 0;
    }

    View Slide

  95. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : LED Blink してみる
    • 無限ループを作る
    2016/12/04 95
    #include
    int main(void) {
    *((uint32_t *)(0x20200010)) &= ~(uint32_t)(0x07 << (7 * 3));
    *((uint32_t *)(0x20200010)) |= (uint32_t)(0x01 << (7 * 3));
    while (1) {
    }
    return 0;
    }

    View Slide

  96. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : LED Blink してみる
    • GPIO47 を High にする
    2016/12/04 96
    #include
    int main(void) {
    *((uint32_t *)(0x20200010)) &= ~(uint32_t)(0x07 << (7 * 3));
    *((uint32_t *)(0x20200010)) |= (uint32_t)(0x01 << (7 * 3));
    while (1) {
    *(uint32_t *)0x20200020 = 1 << (47 - 32);
    }
    return 0;
    }

    View Slide

  97. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : LED Blink してみる
    • 適当に待つ
    2016/12/04 97
    #include
    int main(void) {
    *((uint32_t *)(0x20200010)) &= ~(uint32_t)(0x07 << (7 * 3));
    *((uint32_t *)(0x20200010)) |= (uint32_t)(0x01 << (7 * 3));
    while (1) {
    *(uint32_t *)0x20200020 = 1 << (47 - 32);
    for (int i = 0; i < 1000000; i++);
    }
    return 0;
    }
    配布資料では 100000000
    となっていますが,
    0 を 2 つ減らして
    1000000 にしてください

    View Slide

  98. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : LED Blink してみる
    • GPIO47 を Low にする
    2016/12/04 98
    #include
    int main(void) {
    *((uint32_t *)(0x20200010)) &= ~(uint32_t)(0x07 << (7 * 3));
    *((uint32_t *)(0x20200010)) |= (uint32_t)(0x01 << (7 * 3));
    while (1) {
    *(uint32_t *)0x20200020 = 1 << (47 - 32);
    for (int i = 0; i < 1000000; i++);
    *(uint32_t *)0x2020002C = 1 << (47 - 32);
    }
    return 0;
    }

    View Slide

  99. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    演習 : LED Blink してみる
    • 適当に待つ
    2016/12/04 99
    #include
    int main(void) {
    *((uint32_t *)(0x20200010)) &= ~(uint32_t)(0x07 << (7 * 3));
    *((uint32_t *)(0x20200010)) |= (uint32_t)(0x01 << (7 * 3));
    while (1) {
    *(uint32_t *)0x20200020 = 1 << (47 - 32);
    for (int i = 0; i < 1000000; i++);
    *(uint32_t *)0x2020002C = 1 << (47 - 32);
    for (int i = 0; i < 1000000; i++);
    }
    return 0;
    }

    View Slide

  100. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    発展課題
    • Systick Timer 等を用いて正確に 500ms 待ってみる
    • スイッチを繋げて,
    スイッチを押した時だけ LED が点灯するようにしてみる
    • GPIO をもっと簡単に制御するための関数を作ってみる
    • USART を使ってパソコンに文字を出力してみる
    • 必要なケーブル等は講師またはチューターにもらってください
    100
    2016/12/04

    View Slide

  101. (C) Toshifumi NISHINAGA CC-BY-SA-NC 4.0
    おわりに
    • 低レイヤーは楽しいです!
    • つらいこともたくさんあるけど,動いた時の感動は最高!
    • 学べばどこかで役に立ちます!
    • マイコンを始めとした組込み機器をより自由に使うことが出来ます
    よ!
    • プログラムの最適化やマルウェアの解析等はコンピュータアーキテク
    チャの知識があるとより深く考えられるようになりますよ!
    • 皆さん一緒に低レイヤーを学んで,一緒に遊びましょう!
    101
    2016/12/04

    View Slide