/var/log/messages

May 6, 2014 - 4 minute read - Comments - programming

U-Boot を RPi で動かす

入手方法は以下で

$ git clone git://github.com/swarren/u-boot.git
$ cd u-boot
$ git checkout -b rpi_dev origin/rpi_dev

以下で make とのこと。

export CROSS_COMPILE=arm-unknown-eabi-
make rpi_b_config
make

若干のソース修正も入っていますがここでは略。

fatls について色々確認してみます。

とりあえず grep してみるなど。

$ find . |xargs grep fatls 2>/dev/null
./board/mcc200/auto_update.c:           debug ("Unable to use USB %d:%d for fatls\n",
./board/freescale/m54455evb/README:fatls   - list files in a directory (default /)
./README:               becomes available to the fat commands, i.e. fatls.
./System.map:0013c994 D _u_boot_list_2_cmd_2_fatls
Binary file ./u-boot.bin matches
Binary file ./common/built-in.o matches
./common/cmd_fat.c:     fatls,  4,      1,      do_fat_ls,
Binary file ./common/cmd_fat.o matches
Binary file ./u-boot matches
./include/configs/bcm28155_ap.h: * This is necessary for the fatls command to work on an SD card
./include/configs/zmx25.h:              "fatls usb 0; fatload usb 0 0x81000000 zmx25-init.bin;" \
./include/configs/jadecpu.h:            "fatls usb 0; fatload usb 0 0x40000000 jadecpu-init.bin;" \
./u-boot.map: .u_boot_list_2_cmd_2_fatls
./u-boot.map:                0x0013c994                _u_boot_list_2_cmd_2_fatls
./u-boot.map: .rel.u_boot_list_2_cmd_2_fatls
./drivers/block/systemace.c: * "ace" that allows the user to execute "fatls ace 0" and the

./common/cmd_fat.c かな。gtags -v して emacs 起動。定義は以下なカンジらしい。

static int do_fat_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc,
                         char * const argv[])
{
        int dev, part;
        block_dev_desc_t *dev_desc;
        disk_partition_t info;

        if (argc < 2) {
                printf("usage: fatinfo <interface> [<dev[:part]>]\n");
                return 0;
        }

        part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1);
        if (part < 0)
                return 1;

        dev = dev_desc->dev;
        if (fat_set_blk_dev(dev_desc, &info) != 0) {
                printf("\n** Unable to use %s %d:%d for fatinfo **\n",
                        argv[1], dev, part);
                return 1;
        }
        return file_fat_detectfs();
}

Unrecognized filesystem type はどこで出力しているのか、というと

./fs/fs.c:      printf("** Unrecognized filesystem type **\n");

らしい。fs_probe_unsupported という関数。fs/fs.c で以下な定義がありますね。

    {
            .fstype = FS_TYPE_ANY,
            .null_dev_desc_ok = true,
            .probe = fs_probe_unsupported,
            .close = fs_close_unsupported,
            .ls = fs_ls_unsupported,
            .exists = fs_exists_unsupported,
            .read = fs_read_unsupported,
            .write = fs_write_unsupported,
    },

これってそもそも fat な区画と思っていないのかな。って fatls の実態こちらだった模様。

static int do_fat_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
        return do_ls(cmdtp, flag, argc, argv, FS_TYPE_FAT);
}

do_ls は fs/fs.c で定義されてて核心は以下なのかどうか。

    if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype))
            return 1;

    if (fs_ls(argc >= 4 ? argv[3] : "/"))
            return 1;

    return 0;

で、fs_ls も fs/fs.c で以下な定義ですが、ここで unsupported が戻っているのか。

static struct fstype_info *fs_get_info(int fstype)
{
struct fstype_info *info;
int i;

for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes) - 1; i++, info++) {
    if (fstype == info->fstype)
        return info;
}

/* Return the 'unsupported' sentinel */
return info;
}

動かしてみます

て、U-Boot 側で JTAG が使える形になってないと、なのか。とりあえず u-boot.lds を見てみるに

ENTRY(_start)

らしいのでそこを探すか。と思ったら board/raspberrypi/rpi_b/ なるディレクトリを発見。

$ ls board/raspberrypi/rpi_b/
built-in.o  Makefile  rpi_b.c  rpi_b.o  rpi_b.su

rpi_b.c には board_mmc_init とかって手続きの定義があったり。あと arch/arm というディレクトリがあります。おそらく cpu/arm1176/start.S がエントリポイントになるのかどうか。

ここに JTAG な GPIO 有効にするコードをベタで書けば良いのかどうか。

とりあえずやってみた

baremetal 本の gpio.c をコピィして Makefile に追加

obj-y	:= lowlevel_init.o
obj-y	+= init.o reset.o timer.o mbox.o gpio.o

あー、コピィしたヤツって色々 include しとるな。無理矢理気味ですが、以下に。

typedef volatile unsigned int vu32_t;

#define PHY_PERI_ADDR(x) (0x20000000 + (x))
#define GPIO_BASE       (0x00200000)
#define GPPUD           ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x94))
#define GPPUDCLK0       ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x98))
#define GPPUDCLK1       ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x9c))
#define GPFSEL0         ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x00))
#define GPFSEL1         ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x04))
#define GPFSEL2         ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x08))
#define GPFSEL3         ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x0c))
#define GPFSEL4         ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x10))
#define GPFSEL5         ((vu32_t *)PHY_PERI_ADDR(GPIO_BASE + 0x14))

void init_gpio(void){
    int i;
    // pullup all
    *GPPUD 	= 0x02;
    // wait 150 cycle
    for(i=0;i<150;i++){
            // nop
            asm("mov r0,r0");
    }
    *GPPUDCLK0 = 0xffffffff;
    *GPPUDCLK1 = 0xffffffff;
    // wait 150 cycle
    for(i=0;i<150;i++){
            // nop
            asm("mov r0,r0");
    }
    *GPPUDCLK0 = 0;
    *GPPUDCLK1 = 0;

    *GPFSEL0 = 0;
    *GPFSEL1 = 0;
    *GPFSEL2 = 0;
    *GPFSEL3 = 0;
    *GPFSEL4 = 0;
    *GPFSEL5 = 0;
}

あとは arch/arm/cpu/arm1176/start.S を以下に修正。

    /*
     * Go setup Memory and board specific bits prior to relocation.
     */
    bl	lowlevel_init		/* go setup pll,mux,memory */

            // initialize gpio
    bl      init_gpio

    // pinMode(22 ,ALT4)
    ldr     r3, .L2
    ldr     r2, .L2
    ldr     r2, [r2]
    orr     r2, r2, #192
    str     r2, [r3]

    // pinMode(4, ALT5)
    ldr     r3, .L2+4
    ldr     r2, .L2+4
    ldr     r2, [r2]
    orr     r2, r2, #8192
    str     r2, [r3]

    // pinMode(27, ALT4)
    ldr     r3, .L2
    ldr     r2, .L2
    ldr     r2, [r2]
    orr     r2, r2, #6291456
    str     r2, [r3]

    // pinMode(25, ALT4)
    ldr     r3, .L2
    ldr     r2, .L2
    ldr     r2, [r2]
    orr     r2, r2, #98304
    str     r2, [r3]

    // pinMode(24, ALT4)
    ldr     r3, .L2
    ldr     r2, .L2
    ldr     r2, [r2]
    orr     r2, r2, #12288
    str     r2, [r3]

    bl	_main

どうなるか。

$ make clean
$ export CROSS_COMPILE=arm-unknown-eabi-
$ make rpi_b_config
$ make

を、u-boot.bin ができてますね。ファイルをコピーしてデバッガの用意して電源投入してみましたが駄目。追加した部分をコメントアウトしてコンパイルし直してみます。

  AS      arch/arm/cpu/arm1176/start.o

一応コンパイルし直されているみたい。SD にコピィしてみると起動なメセジが出ましたね。むむむ。

無理矢理 gdb したら以下なメセジが出た。

Dwarf Error: wrong version in compilation unit header (is 4, should be 2)

Makefile がアレなのかどうか。KBUILD_CFLAGS には -g 付いてるのですが、HOSTCFLAGS には付いてません。この違いが何なのかがアレです。とりあえず以下にしてみました。

# HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTCFLAGS   = -Wall -Wstrict-prototypes -g -fomit-frame-pointer

どうなるか。ってコンパイルできないぞ。なので以下に修正。

HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -g -fomit-frame-pointer

最適化オプション有効にしてデバッグとか微妙なんだけど仕方ない。でもコンパイル通ったけど現象変わらず。crosstools なソレを使ってるのが微妙なのかなぁ。

現時点で何をどうすりゃ良いかも分からないので v6pi が gdb で云々できるかを確認してみたいと思います。たぶんこの件、明日以降は当分対応無理じゃないかと思いますorz

U-Boot で fatls v6pi の中身確認とか

comments powered by Disqus