Skip to content

Instantly share code, notes, and snippets.

@novi
Forked from poutyface/gist:1223553
Created November 8, 2012 16:57
Show Gist options
  • Select an option

  • Save novi/4040055 to your computer and use it in GitHub Desktop.

Select an option

Save novi/4040055 to your computer and use it in GitHub Desktop.

Revisions

  1. novi revised this gist Nov 8, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -183,7 +183,7 @@ $ cd ..
    -- _install/etc/init.d/rcS
    #!/bin/sh

    mount -t proc none /porc
    mount -t proc none /proc
    mount -t sysfs none /sys
    /sbin/mdev -s

  2. novi revised this gist Nov 8, 2012. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -143,6 +143,7 @@ $ make defconfig
    $ make menuconfig
    デフォルトのコンフィグレーションではかなりの数のツールが選択されているので、ほしいものだけ
    をチェックする。コンパイル途中でエラーがでたら素直に外すのが吉
    Staticビルドする設定をする(重要)

    $ make install

  3. @poutyface poutyface revised this gist Oct 30, 2011. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -233,3 +233,6 @@ $ arm-none-eabi-objcopy -O binary test.elf test.bin



    -----
    arch/arm/mach-<mach>/Makefile.boot
    zreladdr: head.SがRAMにzImageを展開したあとのKernelのスタートアドレス
  4. @poutyface poutyface revised this gist Oct 30, 2011. 1 changed file with 35 additions and 1 deletion.
    36 changes: 35 additions & 1 deletion gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -195,7 +195,41 @@ $ chmod +x _install/etc/init.d/rcS
    $ qemu-system-arm -M realview-pbx-a9 -m 128M -kernel kernel-v2.6.39/arch/arm/boot/zImage -nographic -initrd rootfs.img.gz -smp 2 -append "root=/dev/ram rdinit=/sbin/init Console=ttyAMA0 mem=128M"


    お疲れ様でした。
    appendix
    ---------
    QEMUでは-kernelオプションに渡されたバイナリファイルを0x00010000にロードする。
    エミュレータは0x00000000番地からスタートするが、ここには予めいくつかのインストラクションが
    含まれており、最終的に0x00010000にジャンプするようになっている。このことから
    あるプログラムをQEMU上で単に実行するには、0x00010000でリンクされたバイナリを作成することで
    実行できる

    startup.o
    ------------
    .global _Reset
    _Reset:
    LDR sp, =stack_top
    BR c_entry
    B .

    test.ld
    --------
    ENTRY(_Reset)
    SECTIONS
    {
    . = 0x10000;
    .startup . : { startup.o(.text) }
    .text : { *(.text) }
    .data : { *(.data) }
    .bss : { *(.bss) }
    . = . + 0x1000;
    stack_top = .;
    }

    -----
    $ arm-none-eabi-as -mcpu=arm926ej-s -g startup.s -o startup.o
    $ arm-none-eabi-gcc -c -mcpu=arm926ej-s -g test.c -o test.o
    $ arm-none-eabi-ld -T test.ld test.o startup.o -o test.elf
    $ arm-none-eabi-objcopy -O binary test.elf test.bin



  5. @poutyface poutyface created this gist Sep 17, 2011.
    201 changes: 201 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,201 @@

    モチベーション
    ---------------
    Androidのエミュレータは中でQEMUを使ってる
    中で使われているので、Android開発とは直接関係がないけど、
    素のQEMUの使い方を知る。

    * QEMUの使い方を覚える
    * Linuxをエミュレータ環境で動かしてみる
    * ARM のクロス環境に慣れてみる
    * ARM はマルチコア


    環境
    -----
    Linux 2.6.38-11-generic Ubuntu SMP
    kernel-v2.6.39
    QEMU emulator version 0.14.0 (qemu-kvm-0.14.0)


    linux kernelをコンパイル
    -------------------------
    $ cd kernel-v2.6.39

    $ export ARCH=arm

    $ export CROSS_COMPILE=arm-none-linux-gnueabi-
    クロス環境のツールチェインはCodeSourceryのツールチェインを使用する
    https://sourcery.mentor.com/sgpp/lite/arm/portal/subscription?@template=lite
    target OS GNU/LinuxをダウンロードしてbinにPATHを通す.

    $ make realview_smp-defconfig
    ターゲット向けのコンフィグレーションファイルを作る。
    あらかじめ用意されているコンフィグレーションがあるので(XXX-defconfig)を
    それを指定する. 今回はSMPなので realview_smp-defconfigを指定.
    ターゲットのコンフィグレーションファイルの種類はARMの場合,arch/arm/configsで確認できる。

    $ make menuconfig
     ARMv7アーキテクチャに設定する、またCortex-A9を使用する.

    * loadable module support [disabled]
    * Platform Baseboard for ARM11 [disabled]
    * Support ARM ARMv6 [disabled]
    * PBX A9 and ARMv7 [enabled]
    -> Support RealView(R) Emulation Baseboard
    -> Support Multicore Cortex-A9 Tile
    * Support RealView(R) Platform Baseboard Explore [enabled]
    * CONFIG_REALVIEW_HIGHT_PHYS_OFFSET [disabled]
    RealView platform type
    -> Hight physical base address for the RealView platform

    * EABI(allowing also old ABI) SupportがEnabledになっているかを確認すること
    これはCodeSourcery toolchainでコンパイルするので必要

    ** Network device support
    -> Network Ethernet (10 or 100Mbit)
    ->SMSC LAN911X [disabled]
      qemu-0.14.0でハードフェアエラーがでるためdisabledにする


    ビルドが成功するとarch/arm/boot/zImageにカーネルイメージが出来上がる
    このカーネルイメージはQemuで実行することができる


    Kernel の起動を確認する
    ------------------------

    シングルコアでの起動を確認
    qemu-system-arm -M realview-pbx-a9 -m 128M -kernel kernel-v2.6.39/arch/arm/boot/zImage -nographic -append "console=ttyAMA0 mem=128M"

    マルチコアでの起動を確認
    qemu-system-arm -M realview-pbx-a9 -m 128M -kernel kernel-v2.6.39/arch/arm/boot/zImage -nographic -smp 2 -append "console=ttyAMA0 mem=128M"

    initrd(ルートファイルシステム)を指定していないので、途中でエラーになるのが正しい

    -M : 仮想ボードのモデル名
    -m : メモリ容量
    -kernel : linux kernelのイメージ
    -nographic : windowでなくconsoleで
    -append : カーネル起動パラメータを指定する
    -smp : CPUコアの数

    Note:
    モデル名は qemu-system-arm -M ? でリストが表示される

    QEMUを抜けるには Ctrl-A, x を順番にタイプする。


    確認用のinitrdの作成
    ---------------------
    確認のためにinitrdを作成し、正しく起動するかを確認してみる
    普通のlinuxであると、ルートファイルシステムはさまざまなディレクトリ(/bin, /etc, /usr等) がある
    が、これは後回しで、簡単なプログラムを1つ作成して、1ファイルを含むだけのinitrdを作ってみる.

    -- test.c

    #include <stdio.h>

    void main()
    {
    printf("Welcome world\n");
    while(1);
    }

    ----

     Note:
      while(1) でループしているのは、linuxがこのプログラムを初めに動かすので、プログラムを
      終了させないため


    $ arm-none-linux-gnueabi-gcc -static test.c -o test
    $ echo test | cpio -o --format=newc > rootfs
    $ qemu-system-arm -M realview-pbx-a9 -m 128M -kernel kernel-v2.6.39/arch/arm/boot/zImage -nographic -initrd rootfs -smp 2 -append "root=/dev/ram rdinit=/test console=ttyAMA0 mem=128M"

    Note:
    cpioはfilesystemを作るのに使われる。cpioはファイルのリストを入力しアーカイブを出力する。
    formatにnewcを指定するとinitramfs形式のフォーマット。
    いま作成したrootfsはtestバイナリファイルを1つ含んだファイルシステムイメージで、これを
    QEMUのinitrdパラメータに渡すことができる。

    -initrd でinitrd を指定する
    -append でrdinit=に初めに実行するプログラムを指定できる

    上手く動いていれば "Welcom world" が最後に出力される。


    BusyBoxを使用してツールを作成する, initrdも作成
    ------------------------------------------------
    上記でlinuxは起動できたが、いろいろツールが足りないので、BusyBoxでターゲット用の
    各種ツール群を作成する。
    BusyBoxはコンパクトなファイルシステムを必要とする組み込みlinuxでよくつかわれる、
    さまざまなシステムユーティリティを提供する。

    busybox-1.19.2
    http://www.busybox.net/

    $ export ARCH=arm
    $ export CROSS_COMPILE=arm-none-linux-gnueabi-

    $ make defconfig

    $ make menuconfig
    デフォルトのコンフィグレーションではかなりの数のツールが選択されているので、ほしいものだけ
    をチェックする。コンパイル途中でエラーがでたら素直に外すのが吉

    $ make install

    ビルドが成功すると _install/ にルートファイルシステムのツリーが生成される。
    これらを前回の"Welcome world"と同じように、cpioツールを使用してlinuxのルートファイル
    システムイメージを作ると出来上がり。

    $ cd _install
    $ find . | cpio -o --format=newc > ../rootfs.img
    $ cd ..
    $ gzip -c rootfs.img > rootfs.img.gz

    $ qemu-system-arm -M realview-pbx-a9 -m 128M -kernel kernel-v2.6.39/arch/arm/boot/zImage -nographic -initrd rootfs.img.gz -smp 2 -append "root=/dev/ram rdinit=/bin/sh console=ttyAMA0 mem=128M"

    rdinit=で/bin/shを指定しているのでシェルが立ち上がる。ls, pwd等のコマンドが使えるようになっている。
    一方今のままでは、psコマンドが使えない。これは特殊なファイルシステムが/procが必要なので作成する必要がある。

    $ mkdir /proc
    $ mount -t proc none /proc

    また、/devがconsoleデバイスを除いて、空っぽである。こちらも特殊なファイルシステム/sysを作成する

    $ mkdir /sys
    $ mount -t sysfs none /sys
    $ mdev -s

    これらのマウント処理は通常、起動時に/sbin/initにさせることができる。
    /sbin/initは通常linux kernelによって最初に起動されるプログラムである。
    initに何かをさせるには/etc/init.d/rcSに記述する。
    なのでBusyBoxで_installを作成したあとに各種設定ファイルを追加して、cpio -> gzip でinitrdを作れば
    いいだろう

    $ cd _install
    $ mkdir proc sys dev etc etc/init.d
    $ cd ..

    -- _install/etc/init.d/rcS
    #!/bin/sh

    mount -t proc none /porc
    mount -t sysfs none /sys
    /sbin/mdev -s

    ---

    $ chmod +x _install/etc/init.d/rcS

    この内容で、またrootfs.img.gzを作成
    今回は、rdinit=/sbin/initを指定する
    $ qemu-system-arm -M realview-pbx-a9 -m 128M -kernel kernel-v2.6.39/arch/arm/boot/zImage -nographic -initrd rootfs.img.gz -smp 2 -append "root=/dev/ram rdinit=/sbin/init Console=ttyAMA0 mem=128M"


    お疲れ様でした。