mini2440にDebian環境をインストール

最終更新: 2011/02/10 20:08:14 [| ]  最終更新: 2011/02/10 20:08:14

はじめに

このページではmini2440ボードに最低限のLinux環境をインストールします。

mini2440ボードはオンボードに64M(最近のモデルではより大量)のFlashメモリを積んでいて、ここをファイルシステムとして使えます。それと同時にオンボードでSDカードのスロットがあり、こちらもLinuxから利用可能です。
コンパクトな固定のシステムを作る場合には、当然オンボードで動作させた方が部品も少なくいいのですが、デバッグしたり、更新したりすることを考えると、最初からSDカードに詰めてしまった方がいろいろと便利です。
というわけで、SDカード上にカーネルをインストールし、ファイルシステムを構築します。

主に、

を行います。

なお、以下の記述はほぼ、project4funmini2440 Bootstrap Lenny for your ARM boardの解説をもとに、実際に確認した手順をまとめています。
また、ツール類は開発環境の準備でインストールしたものを使用しています。

また、インストールするのはDebian/Ubuntu系のarmelアーキテクチャのセットですが、Ubuntuはバージョンが進むにつれ、最適化されているARMの種類が上がるようです。 mini2440のARM9(ARM920T)はARMv4アーキテクチャで、それに対応するのがDebian 5(lenny)の模様です。Ubuntuになると、後続のARMv5,6,7になるため、mini2440の関連情報を探すとlennyになっているようです。


ブートローダ U-Bootの構築

基本的に、FriendryARM提供のU-Bootで動作するので、ボードにインストールするためのU-Bootは不要ですが、カーネルイメージをU-Boot用に変換するために、ビルドします。

まず、mini2440用に調整されているらしい、u-bootのソースを取得します。

$ mkdir uboot ; cd uboot 
$ git clone git://repo.or.cz/u-boot-openmoko/mini2440.git
$ ls
mini2440
$ tar cvzof uboot-mini2440_git_orig.tar.gz mini2440
$ cd mini2440
$ export CROSS_COMPILE=arm-linux-
$ make mini2440_config    一瞬
$ make all    今時のPCでざーっと流れて2,3分
2010/07/19現在でgitで持ってきたもの.tar.gz↑

念のための確認として、コンパイル時には arm-linux-gccが呼ばれているはずです。 生成されるファイルはu-boot.bin(バイナリ) u-boot(ELF binary) u-boot.srec(モトローラS形式)です。
※最終的にどれを書き込むのかは不明。


カーネルの取得と構築

まず、mini2440用に調整されているらしい、カーネルソースを取得します。

$ mkdir kernel ; cd kernel
$ git clone git://repo.or.cz/linux-2.6/mini2440.git 取得にそこそこ時間がかかります
$ ls
mini2440
$ tar cvzof kernel-2.6.32_mini2440_git_orig.tar.gz mini2440

2010/07/19現在でgitで持ってきたもの.tar.gz↑

つぎにビルドの準備をします。
その際、カーネルソースの一部を書き換えます。

$ cd 2440
$ EDIT drivers/video/fbmem.c
書き換えポイント(fbmem.c, 1050行付近、FBIOPUTでサーチ)
    case FBIOPUT_VSCREENINFO:
        return 0;  【この行挿入】
        if(copy_from_user(&var...))
            return -EFAULT;
もと情報によれば、どうも X をfbdevで動かすために必要な改造の模様です。
(改造の必要性については未検証)

また、7inchの液晶を使う場合(後述)、そのままでは画面が点滅する問題が起きました。
データシートと照合すると誤植のようです。以下の修正で点滅が見られなくなりました。
arch/arm/mach-s3c2440/mach-mini2440.cの250行目付近、mini2440+7"TFTに関する構造体の設定:

         480, 29, 3, 3,          /* y timing */
         50),                    /* refresh rate */
を
         480, 29, 13, 3,         /* y timing */
         60),                    /* refresh rate */
に (※refresh rateはタイミング的に可能に思われる)
N35の場合は不要です。A70でもロットによって違ったりするかもしれませんので、いきなり書き換えない方がいいかもしれません。
(一度以下の手順を済ませて点滅した場合、ソース修正、uImage作成までやって、SDのvfatパーティションに書けばOK)

続いて、カーネルのクロス構築を行います。

$ mkdir -p ../kernel-bin
$ CROSS_COMPILE=arm-linux- ARCH=arm make O=../kernel-bin/ mini2440_defconfig
     すぐに終わります
$ CROSS_COMPILE=arm-linux- ARCH=arm make O=../kernel-bin/
     カーネルビルドなのでかなりかかります
$ ../../uboot/mini2440/tools/mkimage -A arm -O linux -T kernel -C none \
   -a 0x30008000 -e 0x30008000 -d ../kernel-bin/arch/arm/boot/zImage uImage
     これでu-boot対応カーネルイメージが出来る
$ ls -l uImage
... 2040148 uImage
$ CROSS_COMPILE=arm-linux- ARCH=arm make O=../kernel-bin/ \
  INSTALL_MOD_PATH=../kernel-modules modules_install
これで mini2440ディレクトリ内にuImageと、../kernel-modules内に附属するモジュールが生成されます。

注意点はubootのビルドパスです。

  開発用ディレクトリ
     uboot
        mini2440
     kernel
        mini2440
とubootとkernelは並列に並んでいるような相対パス表記になっています。

なお、もしカーネルの設定を変えたい場合は、

$ mkdir -p ../kernel-bin
$ CROSS_COMPILE=arm-linux- ARCH=arm make O=../kernel-bin/ mini2440_defconfig
$ CROSS_COMPILE=arm-linux- ARCH=arm make O=../kernel-bin/ menuconfig
$ CROSS_COMPILE=arm-linux- ARCH=arm make O=../kernel-bin/
$ ../../uboot/mini2440/tools/mkimage -A arm -O linux -T kernel -C none \
   -a 0x30008000 -e 0x30008000 -d ../kernel-bin/arch/arm/boot/zImage uImage_A70
$ ls -l uImage
... 2040148 uImage
$ CROSS_COMPILE=arm-linux- ARCH=arm make O=../kernel-bin/ \
  INSTALL_MOD_PATH=../kernel-modules_A70 modules_install
とmake menuconfigを追加します。
make menuconfig には ncursesが必要です。そのためには
$ sudo apt-get install libncurse5-dev
が必要です(ぐぐって調べるのに若干面倒だった)。

mini2440へのU-Bootのインストール

作業の概要

mini2440ボードには2系統のフラッシュROMが乗っています。 両者は基板上の音声出力コネクタ横のスライドスイッチで切り替えられ、一方は最低限のBIOS的内容、もう一方はOSなどを入れたりする主たるストレージです。
本来は、このストレージの方にブートローダ、カーネル、ファイルシステムなど一式を全部詰め込むのですが、初期型が64Mしかないのですぐに一杯になります。 最新版は1Gあるようで十分な容量で、今後はそこに入れることも検討しますが、ハード的に壊すとおしまいなのと、入れ換えたりするのが面倒なので、ここではSDカードをメインのストレージにします。
そのSDカードから起動できるようなブートローダとして、U-Bootをインストールします。

手順は:

  1. 接続などのチェック
  2. 今はいっている内容のバックアップ(USB接続の確認兼用、無しでも良いかもしれない)
  3. U-Bootの書き込み
を行います。

必要なもの

Friendry ARM:Downloads:


インストール前のチェック

  1. まず動作確認をする。
    ボードに手を加える前に電源をいれて、Qtopiaが起動することを確認する。
    ROM切り替えスイッチ(音声出力コネクタ横のスライドスイッチ)が奥(というか基板角の反対)側であることを確認して、電源(ACアダプタ側のスイッチ)を入れる。

    手っ取り早い例としては、「ビデオ」のところに「なにか」入っているかもしれない(笑)。イヤホンを挿すと音も出るけど音量の大きさに注意。なお、このビデオアプリ、何故か応答無しになることがある。

    ちなみに、正しい電源の切り方は知らないから、Qtopiaのときはぶちっと切っている。

  2. つぎにシリアルポートの実験をする。
    ボードの電源を落とし、PCの(USB経由の)シリアルポートとボードのDsub9pinを接続する(クロスケーブル)。
    PC側で適切なポートを開き、通信条件を 115200bps (標準:8bit 1スタート1ストップ)に設定する。
    この状態で電源をいれる。
    VIVI version 0.1.4 (root@russell-work-pc) (gcc version 2.95.3 
         20010315 (release)) #0.1.4 Tue Jun 16 15:20:37 CST 2009
    MMU table base address = 0x33DFC000
    Succeed memory mapping.
    DIVN_UPLL0
    MPLLVal [M:7fh,P:2h,S:1h]
    CLKDIVN:5h
    
    +---------------------------------------------+
    | S3C2440A USB Downloader ver R0.03 2004 Jan  |
    +---------------------------------------------+
    USB: IN_ENDPOINT:1 OUT_ENDPOINT:3
    FORMAT: +++
    NOTE: Power off/on or press the reset button for 1 sec
          in order to get a valid USB device address.
    
    NAND device: Manufacture ID: 0xec, Chip ID: 0x76 (Samsung K9D1208V0M)
    Could not found stored vivi parameters. Use default vivi parameters.
    Press Return to start the LINUX/Wince now, any other key for vivi
    Copy linux kernel from 0x00050000 to 0x30008000, size = 0x00200000 ... done
    zImage magic = 0x016f2818
    Setup linux parameters at 0x30000100
    linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc 
     console=ttySAC0"
    MACH_TYPE = 782
    NOW, Booting Linux......
    Uncompressing Linux............................................................
    Linux version 2.6.29.4-FriendlyARM (root@russell-work-pc) 
    (gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) ) #4 Tue Jun 9 16:32:08 CST 2009
    CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
    CPU: VIVT data cache, VIVT instruction cache
    Machine: FriendlyARM Mini2440 development board
    ATAG_INITRD is deprecated; please update your bootloader.
    Memory policy: ECC disabled, Data cache writeback
      :
    hwclock: settimeofday() failed: Invalid argument
    [19/Dec/2003:06:17:30 +0000] boa: server version Boa/0.94.13
    [19/Dec/2003:06:17:30 +0000] boa: server built Mar 26 2009 at 15:28:42.
    [19/Dec/2003:06:17:30 +0000] boa: starting server pid=498, port 80
    
    Try to bring eth0 interface up......eth0: link down
    Done
    
    Please press Enter to activate this console.
    
    というような感じで、ブートシーケンスが流れる。 ここで、Enterすると、rootのシェルがひらかれる。手元のものでディスク容量は64M中50Mほど使っていて余裕の少ない状態。

既存イメージの吸い出し

元に戻せるように、いまのイメージをPCに吸い出しておきます。 そのためには、USB接続をします。

  1. usb-downloaddr-setup-.zipを展開して、インストーラを実行。読めない文字が出てくるけど、適当にボタンを押せば入る。
  2. 電源を切ったボードのUSB-BコネクタとPCを接続する。
  3. ROM切り替えスイッチ(音声ジャック横)を角側にスライドさせる。
  4. シリアルポート、USBの接続を確認して電源をいれる。
    USB接続が認識されて、ドライバの組み込みが行われる。
    ターミナルには、
    ##### FriendlyARM BIOS for 2440 #####
    [x] bon part 0 320k 2368k
    [v] Download vivi
    [k] Download linux kernel
    [y] Download root_yaffs image
      :
    [s] Set the boot parameters
    [t] Print the TOC struct of wince
    [u] Backup NAND Flash to HOST through USB(upload)
    [r] Restore NAND Flash from HOST through USB
    [q] Goto shell of vivi
    Enter your selection:
    
    な感じで表示される。
  5. そのままdnw.zipを展開して出てくる、dnw.exeを実行する。
  6. バックアップを行う。
    先ほどのターミナルで、「u」を入力。
    Enter your selection: u
    Backup Information:
               Start Addr       : 0x0
               End Addr         : 0x4000000
               bBackupOOB       : 1
               bCheckBad        : 1
               dwBackupTotalLen : 0x4200000
               dwReservedBlks   : 20
               dwEPInPktSize    : 32
    Use dnw.exe to receive backup.
    
    という表示が出るので、dnw.exeのメニュー[USB Port]→[Backup Nand Flash to File]を実行すると、保存ファイルを聞かれるので、適当な名前で保存する。
    なお、書き戻しは、[r]を選択の上、[USB Port]→[Transmit/Restore]

U-Bootのインストール

あとは、U-Bootを書き込みます。 ただし、参考文献にしたがって、少し念入りな手順にします(本来は書き込むだけでOKと思われる)

  1. ROMスイッチ角側で起動。BIOSメニューを出す。
  2. ターミナルで[q]を選択した後、以下のloadコマンドを実行
  3. DNWで[USB Port]→[Transmit/Restore]して
    ダウンロード済みのu-boot---.zipのなかの、u-boot-v132.bin を選択する。
    ##### FriendlyARM BIOS for 2440 #####
    [x] bon part 0 320k 2368k
    [v] Download vivi
      :
    [r] Restore NAND Flash from HOST through USB
    [q] Goto shell of vivi
    Enter your selection: q             ※ [q]
    Supervivi> load flash 0 246164 u ※ コマンド入力
    USB host is connected. Waiting a download.
    
    Now, Downloading [ADDRESS:30000000h,TOTAL:246174]
    RECEIVED FILE SIZE:  246174 (240KB/S, 1S)
    Downloaded file at 0x30000000, size = 246164 bytes
    Found block size = 0x00040000
    Erasing...    ... done
    Writing...    ... done
    Written 246164 bytes
    Supervivi>
    
    なお、load の引数は、開始番地と転送するバイト数(u-boot.binの大きさ)と推定される。

  4. 一度電源を切り、ROMスイッチを奥側に切り替え、起動し直す。
    (USBの認識がされないと警告が出た)
    U-Boot 1.3.2-mini2440 (May 25 2010 - 19:15:21)
    
    I2C:   ready
    DRAM:  64 MB
    Flash:  2 MB
    NAND:  Bad block table not found for chip 0
    Bad block table not found for chip 0
    64 MiB
    *** Warning - bad CRC or NAND, using default environment
    
    USB:   S3C2410 USB Deviced
    In:    serial
    Out:   serial
    Err:   serial
    MAC: 08:08:11:18:12:27
    Hit any key to stop autoboot:  0
    MINI2440 #
    
  5. 続けて、メモリのチェックを行う。
    nand scrub, nand createbbt を実行し、yで答える(エコーバック無しでEnter必要)
    MINI2440 # nand scrub        ※入力
    
    NAND scrub: device 0 whole chip
    Warning: scrub option will erase all factory set bad blocks!
             There is no reliable way to recover them.
             Use this command only for testing purposes if you
             are sure of what you are doing!
    
    Really scrub this NAND flash?  ※ [y]、[Enter]を押す。
    Erasing at 0x2850000 --  63% complete.
    NAND 64MiB 3,3V 8-bit: MTD Erase failure: -5
    Erasing at 0x3ffc000 -- 100% complete.
    Bad block table not found for chip 0
    Bad block table not found for chip 0
    OK
    MINI2440 # nand createbbt      ※入力
    Create BBT and erase everything ?  ※ [y]、[Enter]を押す。
    Skipping bad block at  0x0287c000
    Skipping bad block at  0x03ff0000
    Skipping bad block at  0x03ff4000
    Skipping bad block at  0x03ff8000
    Skipping bad block at  0x03ffc000
    
    Creating BBT. Please wait ...Bad block table not found for chip 0
    Bad block table not found for chip 0
    (2,30秒はかかるのでしばらく待つ)
    Bad block table written to 0x03ffc000, version 0x01
    Bad block table written to 0x03ff8000, version 0x01
    
    MINI2440 #
    

  6. このコマンドを実行すると、u-bootもろとも消してしまうので、先ほどのu-bootのインストール手順をもう一度行う。
    すなわち、1:スイッチを角側に切り替えて電源投入、2:[q]→"Supervivi> load flash 0 246164 u"、DNWでu-boot--.binをダウンロード をする。
  7. スイッチを奥側に切り替えて電源投入。
    依然として、"*** Warning - bad CRC or NAND, using default environment"がでる。
    以下の2コマンドを実行する(dynenv set 40000, saveenv)。
    MINI2440 # dynenv set 40000
    device 0 offset 0x40000, size 0x3fc0000
    45 4e 56 30 - 00 00 04 00
    MINI2440 # saveenv
    Saving Environment to NAND...
    Erasing Nand...Writing to Nand... done
    
  8. 電源を入れ直すと、今度はWarningがでない。
    U-Boot 1.3.2-mini2440 (May 25 2010 - 19:15:21)
    
    I2C:   ready
    DRAM:  64 MB
    Flash:  2 MB
    NAND:  64 MiB
    Found Environment offset in OOB..
    USB:   S3C2410 USB Deviced
    In:    serial
    Out:   serial
    Err:   serial
    MAC: 08:08:11:18:12:27
    Hit any key to stop autoboot:  0
    MINI2440 #
    
以上で、U-Bootのインストールは終了です。 SDカードへのカーネルなどのインストール後、追加の設定をします。
なお、USBケーブルは使いませんが、シリアルはまだつかいます。


SDカードへのインストール

Ubuntu環境を使って、SDカード上にファイルシステムを作ります。

手順:

  1. 初期のインストールファイルを取得
  2. SDカードのパーティションわけ、フォーマット、コピー
  3. mini2440で起動確認

ファイル類の準備

debootstrapコマンド(apt-get必要)で初期のインストールに必要なファイルを取得します。

$ (sudo apt-get install debootstrap)
$ mkdir armel-rootfs
$ sudo debootstrap --arch=armel \   ※sudo必須
   --include=ifupdown,udev,procps,netbase,vim-tiny,module-init-tools,\
     (切らずに続く)wget,openssh-server,screen,apmd \
   --foreign lenny ./armel-rootfs http://ftp.de.debian.org/debian
[sudo] password for
I: Retrieving Release
I: Retrieving Packages
I: Validating Packages
    :
I: Extracting mount...
I: Extracting util-linux...
I: Extracting zlib1g...

$ cd armel-rootfs
$ sudo tar cfjv ../armel-rootfs.tar.bz2 *   ※sudoしておいたほうがいいでしょう。
$ cd ..
$ ls -l
drwxr-xr-x 18 root    root        4096 2008-04-06 15:51 armel-rootfs
-rw-r--r--  1 root    root    71904114 2010-07-20 22:23 armel-rootfs.tar.bz2
これで、ファイル類の取得と、一式固めができます。 2010/7/20時点のarmel-rootfs.tar.bz2

SDカードのパーティションとフォーマット

次に、SDカードをフォーマットします。 UbuntuインストールのSDカードリーダライタのところで確認したSDカードリーダライタをつかいます。
また、中を壊しても良い2GのSDカード(フォーマットからするので)を用意します。
※1Gでも2G以上でも可のはず

  1. SDカードを挿す。買ってきたばかりならデスクトップに何らかのアイコンが出るとともに、ファイルブラウザが開く。
  2. dmesgコマンドで念のため、どのデバイスで認識されたか確認する。
    $ dmesg | tail
    sd 7:0:0:0: [sdb] 3842048 512-byte logical blocks: (1.96 GB/1.83 GiB)
    sd 7:0:0:0: [sdb] Assuming drive cache: write through
    sd 7:0:0:0: [sdb] Assuming drive cache: write through
      sdb: sdb1
    
    ここから、SDカードは /dev/sdb でアクセスすることがわかる。「sdb」の部分は環境に依存する。 間違うと、いろいろ吹き飛ばすので注意。

  3. デスクトップ上のブラウザは閉じ、自動マウントされたのを解除する。
    $ df -k
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /dev/sda1             19737268   6335036  12399636  34% /
    none                    509008       336    508672   1% /dev
    none                    513232       208    513024   1% /dev/shm
    none                    513232       100    513132   1% /var/run
    none                    513232         0    513232   0% /var/lock
    none                    513232         0    513232   0% /lib/init/rw
    /dev/sdb1              1920704         0   1920704   0% /media/41A3-D996
    $ sudo umount /media/41A3-D996  ※ それらしいのをumount
    $ 問題なければ、df -k してでてこない
    

  4. パーティションを切る。
    パーティションは
    /dev/sdb1 type 0C 100M (Kernel Image 等)
    /dev/sdb2 type 83 700M (main rootfs)
    /dev/sdb3 type 82 128M (swap)
    
    程度とする。2GのSDを使うと1G程度あまりがでるが、放置しておく。 あとで容量的に不足してから、/optなり/homeなりとしてパーティションを追加して使う。
    最初から大きく確保しないのは、この後行う、インストール確認後の丸ごとバックアップをする際に無駄に大きくなりすぎないため。

    以下、操作の例:

    $ sudo fdisk /dev/sdb
    
    WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
             switch off the mode (command 'c') and change display units to
             sectors (command 'u').
    
    Command (m for help): 【p】
    
    Disk /dev/sdb: 1967 MB, 1967128576 bytes
    57 heads, 56 sectors/track, 1203 cylinders
    Units = cylinders of 3192 * 512 = 1634304 bytes
    sSector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x00000000
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1               1        1204     1920955+   6  FAT16
    
    Command (m for help): 【d】
    Selected partition 1
    
    Command (m for help): 【n】
    Command action
       e   extended
       p   primary partition (1-4)
    【p】
    Partition number (1-4): 【1】
    First cylinder (1-1203, default 1):【Enter】
    Using default value 1
    Last cylinder, +cylinders or +size{K,M,G} (1-1203, default 1203): 【+100M】
    
    Command (m for help): 【t】
    Selected partition 1
    Hex code (type L to list codes): 【0c】
    Changed system type of partition 1 to c (W95 FAT32 (LBA))
    
    Command (m for help): 【n】
    Command action
       e   extended
       p   primary partition (1-4)
    【p】
    Partition number (1-4): 【2】
    First cylinder (66-1203, default 66):【Enter】
    Using default value 66
    Last cylinder, +cylinders or +size{K,M,G} (66-1203, default 1203): 【+700M】
    
    Command (m for help): 【n】
    Command action
       e   extended
       p   primary partition (1-4)
    【p】
    Partition number (1-4): 【3】
    First cylinder (516-1203, default 516):【Enter】
    Using default value 516
    Last cylinder, +cylinders or +size{K,M,G} (516-1203, default 1203): 【+128M】
    
    Command (m for help): 【t】
    Partition number (1-4): 【3】
    Hex code (type L to list codes): 【82】
    Changed system type of partition 3 to 82 (Linux swap / Solaris)
    
    Command (m for help): 【p】
    
    Disk /dev/sdb: 1967 MB, 1967128576 bytes
    57 heads, 56 sectors/track, 1203 cylinders
    Units = cylinders of 3192 * 512 = 1634304 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x00000000
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1               1          65      103712    c  W95 FAT32 (LBA)
    /dev/sdb2              66         515      718200   83  Linux
    /dev/sdb3             516         598      132468   82  Linux swap / Solaris
    
    Command (m for help): 【w】
    The partition table has been altered!
    
    Calling ioctl() to re-read partition table.
    
    WARNING: If you have created or modified any DOS 6.x
    partitions, please see the fdisk manual page for additional
    information.
    Syncing disks.
    $
    
    最後の【w】の入力でテーブルを書き出して終了。 もし、途中で削除を思いとどまったり、パーティションの切り分けに失敗しても w しなければ問題なし。
    なお、一覧の Start, End, 操作途中で聞かれる先頭シリンダ番号は、SDカードによって(少なくともKingstonとSunDiskで)異なる。これは1シリンダ当たりの容量が異なるため (57 heads, 56 sectors/track, 1203 cylinders // Units = cylinders of 3192 * 512 = 1634304 bytes の部分で heads,sectors/trackの違い)。


  5. 確認のため、SDカードを抜いて、挿し直して、dmesgをする。
    $ dmesg | tail
    [59182.583513]  sdb: sdb1 sdb2 sdb3
    [59473.953582] sd 8:0:0:0: [sdb] 3842048 512-byte logical blocks: (1.96 GB/1.83 GiB)
    [59473.958898] sd 8:0:0:0: [sdb] Assuming drive cache: write through
    [59473.968929] sd 8:0:0:0: [sdb] Assuming drive cache: write through
    
    sdbがsdb1〜sdb3になっている。なお、ファイルシステムが無いため、たぶんファイルブラウザは出てこないし、df -kで確認しても自動マウントされていない。

  6. ファイルシステムを作る。 以下の手順で、FAT32(vfat), ext3 をつくる。
    $ sudo mkfs.vfat /dev/sdb1
    mkfs.vfat 3.0.7 (24 Dec 2009)
    $ sudo mkfs.ext3 /dev/sdb2
    mke2fs 1.41.11 (14-Mar-2010)
    Filesystem label=
    OS type: Linux
      :
    This filesystem will be automatically checked every 25 mounts or
    180 days, whichever comes first.  Use tune2fs -c or -i to override.
    $
    
以上で、SDカードにファイルシステムが出来ました。

SDカードのへのコピー

次に用意していたファイル類をSDカードにコピーします。

  1. まずカーネルをコピーする。
    SDカードを抜いて挿し直すと、自動マウントされるので、umountする。
    $ df -k
    Filesystem           1K-blocks      Used Available Use% Mounted on
      :
    /dev/sdb1               103492         0    103492   0% /media/2165-6558
    /dev/sdb2               706888     17116    653864   3% /media/9f1842b3-48ac-479d-8d5d-f5bd4e40c7ec
    $ umount /media/2165-6558/
    $ umount /media/9f1842b3-48ac-479d-8d5d-f5bd4e40c7ec
    
    次にマウントしてコピーする
    $ cd kernel/mini2440     ※カーネルを構築したディレクトリに移行
    $ sudo mkdir /mnt/tmp    ※ubuntuインストール後、最初の1回のみ
    $ sudo mount /dev/sdb1 /mnt/tmp   ※sdbかは環境依存
    $ df -k
    Filesystem           1K-blocks      Used Available Use% Mounted on
       :
    /dev/sdb1               103492         0    103492   0% /mnt/tmp
    $ sudo cp uImage /mnt/tmp/
    $ ls -l /mnt/tmp/
    total 1994
    -rwxr-xr-x 1 root root 2040148 2010-07-20 23:07 uImage
    $ sudo umount /mnt/tmp
    

  2. つぎに必要なファイルをルートファイルシステムにコピーする。 途中の/mnt/tmpへのcdを確実にする。 失敗すると開発環境のubuntuがほぼ確実に壊れる 。 他も、相対パスになっているところに注意すること。一度操作の意味を考えてから実行すべし。
    $ sudo mount /dev/sdb2 /mnt/tmp
    $ cd /mnt/tmp  ※超重要
    /mnt/tmp$ ls -al
    total 16
    drwx------ 2 root root 16384 2010-07-20 22:57 lost+found
    /mnt/tmp$ sudo tar xvjfp (フルパス/)armel-rootfs.tar.bz2
    だーーー
    var/log/fsck/
    var/local/
    
    /mnt/tmp$ sudo cp -Rp (フルパス)kernel-modules/lib/* lib/
    (多少時間がかかる)
    /mnt/tmp$ sudo /bin/bash
    ※現在のディレクトリが/mnt/tmpであることを再確認
    /mnt/tmp# echo "proc /proc proc none 0 0" >> etc/fstab
    /mnt/tmp# echo "mini2440" > etc/hostname
    /mnt/tmp# echo '127.0.0.1 localhost.localdomain localhost' > etc/hosts
    /mnt/tmp# mknod dev/console c 5 1
    mknod: `dev/console': File exists  ※参考文献にあったが不要らしい
    /mnt/tmp# echo 'deb http://ftp.de.debian.org/debian lenny main' > etc/apt/sources.list 
    /mnt/tmp# exit
    /mnt/tmp$ cd /
    $ sudo umount /mnt/tmp
    
    なお、途中で'sudo /bin/bash'するのはその後のファイルのへの記述追加をするのに'echo'にsudoが効かないため。 直接viなどで書き換えたいときは'sudo vi'でよい。
以上で、開発環境側での基本的なファイルのコピーは終了です。

ボードでの起動実験

まず、mini2440ボードとシリアルポートの接続を行います。
そのまま電源を入れてみれば、U-Bootが立ち上がるので、確認出来ます(ROMのスイッチは奥側)。

次に先ほどのSDカードを挿して、DHCPの可能なネットワークケーブルを繋いで、電源をいれます。

U-Boot 1.3.2-mini2440 (May 25 2010 - 19:15:21)

I2C:   ready
DRAM:  64 MB
Flash:  2 MB
NAND:  64 MiB
Found Environment offset in OOB..
USB:   S3C2410 USB Deviced
In:    serial
Out:   serial
Err:   serial
MAC: 08:08:11:18:12:27
Hit any key to stop autoboot:  0
MINI2440 #

次に、以下のコマンドをプロンプトに入力します。

MINI2440 # setenv bootcmd 'mmcinit ; fatload mmc 0:1 0x31000000 uimage ; bootm 0x31000000'
MINI2440 # setenv bootargs (空白おいて続けて一行で)
'console=ttySAC0,115200 noinitrd root=/dev/mmcblk0p2 rootwait=4 rw ip=dhcp init=/bin/sh'
MINI2440 # boot
うまくいけば、Linuxが起動します。
MINI2440 # boot
mmc: Probing for SDHC ...
mmc: SD 2.0 or later card found
trying to detect SD Card...
Manufacturer:       0x02, OEM "TM"
Product name:       "SD02G", revision 6.0
Serial number:      2716765588
Manufacturing date: 5/2010
CRC:                0x68, b0 = 1
READ_BL_LEN=15, C_SIZE_MULT=7, C_SIZE=365
size = 1642070016
SD Card detected RCA: 0xafd8 type: SD
reading uimage

2040148 bytes read
## Booting kernel from Legacy Image at 31000000 ...
   Image Name:
   Created:      2010-07-19   4:23:49 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2040084 Bytes =  1.9 MB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux.......................... done, booting the kernel.
Linux version 2.6.32-rc8 (kumagai@UbuntuCrossTest) 
(gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) ) #1 Mon Jul 19 00:15:15 EDT 2010
  :
s3c2410-rtc s3c2410-rtc: setting system clock to 2140-01-26 12:04:30 UTC (1071898574)
s3c-sdi s3c2440-sdi: running at 398kHz (requested: 400kHz).
s3c-sdi s3c2440-sdi: running at 16875kHz (requested: 25000kHz).
s3c-sdi s3c2440-sdi: running at 16875kHz (requested: 25000kHz).
mmc0: new SD card at address afd8
(DHCP でIPアドレス取得を試みる)
kjournald starting.  Commit interval 5 seconds
EXT3 FS on mmcblk0p2, internal journal
EXT3-fs: recovery complete.
EXT3-fs: mounted filesystem with writeback data mode.
VFS: Mounted root (ext3 filesystem) on device 179:2.
Freeing init memory: 132K
sh-3.2#
つぎに、ファイルのインストール作業の後半を行います。
sh-3.2# mount /proc /proc -t proc
sh-3.2# export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
sh-3.2# /debootstrap/debootstrap --second-stage
:
:
I: Configuring tasksel...
I: Base system installed successfully.
sh-3.2#
この、debootstrapのsecond stageはかなり時間がかかるので(手元で40分)、しばらく放置します。
なお、SDカード側にLEDが4個並んでいます。外から2番目がSDカードのアクセスランプになっていて、アクセス具合はわかります。

追加の作業をします。

sh-3.2# mknod dev/ttySAC0 c 204 64
sh-3.2# echo ttySAC0 >> /etc/securetty
sh-3.2# printf "T0:123:respawn:/sbin/getty 115200 ttySAC0\n" >> /etc/inittab
sh-3.2# printf "auto lo\niface lo inet loopback\n" >> /etc/network/interfaces
sh-3.2# printf "auto eth0\niface eth0 inet dhcp\n" >> /etc/network/interfaces
sh-3.2# printf "nameserver 192.168.1.1" >> /etc/resolv.conf
最後のnameserverは環境に応じて適宜設定して下さい(ここでは自環境のブロードバンドルータを指定)。

最後に再起動をして、自動的にU-BootからLinuxがあがるようにします。 ここではまだ 'shutdown -r now'は使えないようなので、syncしてexitあたりで。 なお、電源側にリセットスイッチがあります。
U-Bootのプロンプトで、

MINI2440 # setenv bootcmd 'mmcinit ; fatload mmc 0:1 0x31000000 uimage ; bootm 0x31000000'
MINI2440 # setenv bootargs (空白おいて続けて一行で)
'console=ttySAC0,115200n8 rootdelay=3 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait'
MINI2440 # saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
MINI2440 # boot
先ほどに比較し、'saveenv'が増えています。
Debian GNU/Linux 5.0 mini2440 ttySAC0

mini2440 login: root (パスワード無しroot)
Linux mini2440 2.6.32-rc8 #1 Mon Jul 19 00:15:15 EDT 2010 armv4tl

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
mini2440:~#
時間がひどいことになっている場合は、設定した方がいいかもしれません。
mini2440:~# date
Sat Dec 20 06:41:58 UTC 2003
mini2440:~# date 072100432010
Wed Jul 21 00:43:00 UTC 2010
また、swapを使う場合の準備として、swapをつくっておきます。
mini2440:~# mkswap /dev/mmcblk0p3
Setting up swapspace version 1, size = 135540 kB
no label, UUID=c9b6d9d6-fb6f-4400-b28d-93557695f288
mini2440:~# swapon /dev/mmcblk0p3
Adding 132360k swap on /dev/mmcblk0p3.  Priority:-1 extents:1 across:132360k SS
swapを使うのはあまり実用的ではありませんが、メモリがどうしても足りないとき(大きなコンパイルをしたい場合など)、swaponしておくと役に立つことがあります。

もう一度再起動して、今度は自動でカーネルが起動するかを確認します。 なお、まがりなりにもLinuxが動いているので、"shutdown -h now / shutdown -r now"などを使うべきでしょう。

この起動の設定で、カーネルのモードが変わります。bootargs で以下の変更が有効なことを確認しました。

以上で、SDカードで最低限のUbuntu Linux (armel lenny)が動くようになりました。

SDカードのバックアップ

ここまでで、一通り、「起動するLinux環境」ができたので、このあといじることを考えて、バックアップします。

バックアップにはいろいろな手がありますが、ここでは、一番力任せな「パーティションを丸ごとバックアップ」でいきます。 なお、バックアップとリストアを行うと、カードのコピーができます。いろいろ試すときにコピーをつくるといいでしょう。

SDカードのバックアップ

まず、SDカードをUbuntuに繋ぎます。
自動的にマウントされてファイルブラウザも開くと思うので、安全のため、umountします。

$ df -k
Filesystem   1K-blocks      Used Available Use% Mounted on
/dev/sda1     19737268   6344636  12390036  34% /
 :
/dev/sdb1       103492      3988     99504   4% /media/2165-6558
/dev/sdb2       706888    257384    413596  39% /media/9f1842b3-...
$ sudo umount /media/2165-6558/
[sudo] password for 
$ sudo umount /media/9f1842b3-48ac-479d-8d5d-f5bd4e40c7ec/
$ dk -k で確認
つぎに、ddコマンドを使ってバックアップを作ります。if=とof=を間違うと(ファイルがすでにあると)上書き破壊を起こすので、気をつけて下さい。
$ mkdir image; cd image
$ sudo dd bs=1M if=/dev/sdb1 of=FASD_orig_sdb1.vfat
101+1 records in
101+1 records out
106201088 bytes (106 MB) copied, 41.7631 s, 2.5 MB/s
$ sudo dd bs=1M if=/dev/sdb2 of=FASD_orig_sdb2.ext
3
701+1 records in
701+1 records out
735436800 bytes (735 MB) copied, 80.4732 s, 9.1 MB/s
of=でファイル名を指定できます。拡張子を含め自由なので、わからなくならないように好きにつければいいです。 それぞれ、fdiskで確保したのとだいたい同じような容量のファイルができます。 なお、101+1, 701+1は、指定した(bs=1M)入出力の単位で101,701回の読み書きと半端なの1回分という表記で、SDカードの1シリンダ当たりの容量によっては、ファイルのバイト数共々異なる数字になり得ます。

SDカードへのリストア(既存パーティション)

もし、すっかり同じパーティション構成のSDカードがあれば、書き戻しは簡単です。
同じようにumountした上で、

$ mkdir image; cd image
$ sudo dd bs=1M if=FASD_orig_sdb1.vfat of=/dev/sdb1 
$ sudo dd bs=1M if=FASD_orig_sdb2.ext of=/dev/sdb2
と、ifとofを逆にするだけです。(ファイルの側はchmod -wしておいたほうが無難か)。 書き込み後、起動確認をしてください。

SDカードへのリストア(新規SD)

コピーを作る場合などに新規のSDカードに書き込む場合は、パーティションの作成から必要です。
基本的には上のファイルシステム構築と一緒ですが、ブランドが異なるメディアを使う場合は容量の指定に注意が必要です。

$ $ ls -lk  (サイズはキロバイト単位)
total 1646436
-r--r--r-- 1 root root 103712 2010-07-22 22:53 FASD_orig_sdb1.vfat
-r--r--r-- 1 root root 718200 2010-07-22 22:55 FASD_orig_sdb2.ext3
$ sudo fdisk /dev/sdb
中身を消す。

Command (m for help): p
Disk /dev/sdb: 1977 MB, 1977614336 bytes
61 heads, 62 sectors/track, 1021 cylinders
Units = cylinders of 3782 * 512 = 1936384 bytes
メーカが異なるため、この数値が最初の例と異なる
※同じメーカーでも異なる場合あり

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1021, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-1021, default 1021): +103712K
※ここで、前例の+100Mではなく、イメージのサイズをキロバイト表示した値、
※+103712K を指定。

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (57-1021, default 57):
Using default value 57
Last cylinder, +cylinders or +size{K,M,G} (57-1021, default 1021): +718200K
※同じく、+700Mではなく、+718200Kを使用

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (438-1021, default 438):
Using default value 438
Last cylinder, +cylinders or +size{K,M,G} (438-1021, default 1021): +128M
※swapは適当でいいので、適当に128M

Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): c
Changed system type of partition 1 to c (W95 FAT32 (LBA))

Command (m for help): t
Partition number (1-4): 3
Hex code (type L to list codes): 82
Changed system type of partition 3 to 82 (Linux swap / Solaris)
※忘れずにパーティションタイプを設定

Command (m for help): p
Disk /dev/sdb: 1977 MB, 1977614336 bytes
61 heads, 62 sectors/track, 1021 cylinders
Units = cylinders of 3782 * 512 = 1936384 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1          56      105865    c  W95 FAT32 (LBA)
/dev/sdb2              57         437      720471   83  Linux
/dev/sdb3             438         507      132370   82  Linux swap / Solaris

Command (m for help): w
The partition table has been altered!
ここで、以下の最初の例と比べてみます。
Disk /dev/sdb: 1967 MB, 1967128576 bytes
57 heads, 56 sectors/track, 1203 cylinders
Units = cylinders of 3192 * 512 = 1634304 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1          65      103712    c  W95 FAT32 (LBA)
/dev/sdb2              66         515      718200   83  Linux
/dev/sdb3             516         598      132468   82  Linux swap / Solaris
1シリンダ当たり(Units)が前より大きくなり、結果、シリンダ数(start-end)が小さくなりました。
一方、Blocks(1Kバイト単位)は前より大きくなりました。
つまり、必要な容量を確保した上で、Units単位に切り上げた領域、が確保されます。
(このバックアップ・リストアを繰り返すと、いずれはだんだん領域だけが大きくなる危険性があるので注意。 mkfsでつくったファイルシステムそのものは大きくならず、後ろにゴミがついていくだけ。)

なお、この方法だと、head, sectorsが同じでも、余裕を見てEndを1個うしろにずらす場合があります(もしかすると必ず)。
もし、pでみて、headとsector(上では57-56)が一致するなら、そのままstart-endの値をつかってすっかり同じテーブルを作った方が、容量的にはぴったりになります。最終的にBlocksが「未満」にならなければOKです。
(たとえば、同じメーカの同じ銘柄のSDカードなら同じことが期待される)

最後に、イメージの書き戻しをします。

$ sudo dd bs=1M if=FASD_orig_sdb1.vfat of=/dev/sdb1
101+1 records in
101+1 records out
106201088 bytes (106 MB) copied, 26.0068 s, 4.1 MB/s
$ sudo dd bs=1M if=FASD_orig_sdb2.ext3 of=/dev/sdb2
701+1 records in
701+1 records out
735436800 bytes (735 MB) copied, 143.268 s, 5.1 MB/s
あとは、このSDをmini2440に差し込んで確認です。新しくパーティションから作った場合は、mkswapもしておきましょう。 (mkswap /dev/mmcblk0p3)


熊谷正朗 [→連絡]
東北学院大学 工学部 機械知能工学科 RDE
[| ]