APEXをコンパイルしてみる

APEXブートローダーを使ってみるか。
まずは、redbootから実行できるよう、ビッグエンディアンでのバイナリを作成する必要がある。

# wget ftp://ftp.buici.com/pub/apex/apex-1.4.5.tar.gz
# tar zxvf apex-1.4.5.tar.gz
# cd apex-1.4.5

READMEをつらつらと眺める。
IXP42xでの機種依存部分はこのへんにあるようだ。

# ls -al src/mach-ixp42x/
total 144
drwxrwxr-x   2 1000 1000  4096 Aug 18 16:58 .
drwxrwxr-x  12 1000 1000  4096 Aug 18 16:58 ..
-rw-rw-r--   1 1000 1000  4588 Jul 25 06:04 Kconfig
-rw-rw-r--   1 1000 1000  2378 May 15  2005 Makefile
-rw-rw-r--   1 1000 1000  1012 Mar 21  2005 Makefile.libs
-rw-rw-r--   1 1000 1000 13509 May 15  2005 NOTES.nslu2
-rw-rw-r--   1 1000 1000  1691 Jul 26 06:41 cmd-reset.c
-rw-rw-r--   1 1000 1000   410 Feb 27  2006 coprocessor.h
-rw-rw-r--   1 1000 1000  1820 Jul 26 06:34 cpuinfo.c
-rw-rw-r--   1 1000 1000  2904 Aug 18 16:50 debian-nslu2-arm_config
-rw-rw-r--   1 1000 1000  2923 Aug 18 16:55 debian-nslu2-armeb_config
-rw-rw-r--   1 1000 1000  2512 Jun  2 23:51 debug_ll.h
-rw-rw-r--   1 1000 1000  1553 Jul 26 06:41 env.c
-rw-rw-r--   1 1000 1000  1257 Feb 27  2006 hardware.h
-rw-rw-r--   1 1000 1000 12187 Jul 22 23:59 initialize.c
-rw-rw-r--   1 1000 1000  8887 Jul 21 22:31 ixp42x.h
-rw-rw-r--   1 1000 1000  1597 Feb 27  2006 memory.h
-rw-rw-r--   1 1000 1000  1258 Jul 23 23:56 nor-cfi.h
-rw-rw-r--   1 1000 1000  3560 Jul 26 06:41 npe-interface.c
-rw-rw-r--   1 1000 1000  2453 Jul 26 06:41 npe.c
-rw-rw-r--   1 1000 1000  2521 Feb 27  2006 nslu2.h
-rw-rw-r--   1 1000 1000  2821 Aug 12 19:03 nslu2_config
-rw-rw-r--   1 1000 1000  2789 Aug 12 19:03 openslug_config
-rw-rw-r--   1 1000 1000  3277 Jul 26 06:41 pci.c
-rw-rw-r--   1 1000 1000  4328 Jul 26 06:41 serial.c
-rw-rw-r--   1 1000 1000  1787 Jul 26 06:41 spinner-nslu2.c
-rw-rw-r--   1 1000 1000  1376 Jul 26 06:41 timer.c

Kconfigのコメントを読むと、IAL1.5では、リトルエンディアンには対応できないようだ。
以前の予想は当たっていたが、素直に行かなくて残念だ。
これまでにいくつかあったパッチが必要ということか。OpenEnbededや、NLSU2のパッチを持って来る必要があるのかも。


メモリマップをあわせて、CONFIG_USER_BIGENDIAN=yで、あとはよしなになりそうかな。
kernelに渡すパラメータも、この中で埋めるようだ。


機種依存部分の切り分けを見る。
nslu2.hは、LEDのGPIOを定義している。
src/mach-ixp42x/hardware.hの中で、CONFIG_MACH_NSLU2があったら、nslu2.hを読んでいる。
でも、他のコードの中では、決め打ちでこれがあることを前提にしているみたいだな... その部分は修正が必要だろう。NSLU2以外のことは、あまり考えられていないようだ。


Gentoo3の環境を使ってビルドしてみる。ビルドできないとしょうがないので、メモリマップなどはまだ合わせない。

# make menuconfig

Kconfigにハードウエアアーキテクチャを書いておく必要があるようだ。NSLU2ではこんな感じ。

Linksys NSLU2
  | There is no help available for this kernel option.                      |
  | Symbol: MACH_NSLU2 [=y]                                                 |
  | Prompt: Linksys NSLU2                                                   |
  |   Defined at src/mach-ixp42x/Kconfig:7                                  |
  |   Depends on: <choice>                                                  |
  |   Location:                                                             |
  |     -> IXP42X Implementations (<choice> [=y])                           |
  |   Selects: ARCH_IXP420 && USES_NOR_CFI && USES_NOR_BOOTFLASH

エンディアン切り替えについては、こいつを有効にしておけばよさそう。任意にスイッチできるというわけではないようだ。

Environment  --->
    [ ]   Endian swap when copying kernel (NEW)

一旦終わって、NV550用の設定をKconfigに追記する。とりあえず、コピペして名前を変更するだけ。

config MACH_NV550
        bool "MRL NV550"
        select ARCH_IXP420
        select USES_NOR_CFI
        select USES_NOR_BOOTFLASH


再度 make menuconfig。
menuconfigでコンパイラの指定も必要なようだ。というか、セルフでビルドすることは想定外のよう。
/usr/bin/armeb-softfloat-linux-uclibc-gcc-3.4.4ではgccが末尾に付くのでダメだった。
/usr/bin/に設定して通る。


serial.c がエラーでダウン。

  CC      src/mach-ixp42x/serial.o
src/mach-ixp42x/serial.c: In function `ixp42x_serial_init':
src/mach-ixp42x/serial.c:80: warning: implicit declaration of function `_L'
src/mach-ixp42x/serial.c:80: error: `LED5' undeclared (first use in this function)
src/mach-ixp42x/serial.c:80: error: (Each undeclared identifier is reported only once
src/mach-ixp42x/serial.c:80: error: for each function it appears in.)
src/mach-ixp42x/serial.c:90: error: `LED6' undeclared (first use in this function)
src/mach-ixp42x/serial.c:101: error: `LED7' undeclared (first use in this function)
src/mach-ixp42x/serial.c:107: error: `LED8' undeclared (first use in this function)
make[1]: *** [src/mach-ixp42x/serial.o] Error 1
make: *** [src/mach-ixp42x] Error 2

NLSU2では、なんかシリアル初期化時のステイトをLED表示しているのかな? それが決め打ちで埋まっている。

# grep LED5 src/mach-ixp42x/*
src/mach-ixp42x/nslu2.h:#define LED5    ((1<<1)|(0<<0)|(0<<2)|(1<<3))
src/mach-ixp42x/serial.c:  _L(LED5);
src/mach-ixp42x/spinner-nslu2.c:    _L(LED5); break;

関連部分は、今回はバッサリ削除しよう。なんかGPIO設定していて気持ち悪いけど、そのままにする。

# cp src/mach-ixp42x/serial.c src/mach-ixp42x/serial.c.old
# diff -Naur src/mach-ixp42x/serial.c.old src/mach-ixp4
2x/serial.c
--- src/mach-ixp42x/serial.c.old        2006-09-04 18:54:35 +0000
+++ src/mach-ixp42x/serial.c    2006-09-04 18:58:32 +0000
@@ -77,7 +77,7 @@
   u32 divisor_l = 0;
   u32 divisor_h = 0;

-  _L(LED5);
+//  _L(LED5);

   switch (baudrate) {
   case 115200:
@@ -87,7 +87,7 @@
     return;
   }

-  _L(LED6);
+//  _L(LED6);

   UART_LCR  = UART_LCR_WLS_8 | UART_LCR_STB_1 | UART_LCR_DLAB;
   UART_DLL  = divisor_l;
@@ -98,13 +98,13 @@
   UART_IER  = UART_IER_UUE;    /* Enable UART, mask all interrupts */
                                /* Clear interrupts? */

-  _L(LED7);
+//  _L(LED7);

   if (console_driver == 0)
     console_driver = &ixp42x_serial_driver;

 //  console_driver->write (0, "Console initialized\r\n", 21);
-  _L(LED8);
+//  _L(LED8);

 #if !defined (DISABLE_SECOND_UART_INIT)
   UART_SEC_IER  = UART_IER_UUE;        /* Enable second UART as well */

次にイニシャライズで同じような部分に当たる。これも多分ステイト表示をしているだけだと思う。いずれ、LED制御は同じようなものを入れる必要があるかも。

  CC      src/mach-ixp42x/initialize.o
src/mach-ixp42x/initialize.c: In function `initialize_bootstrap':
src/mach-ixp42x/initialize.c:151: warning: implicit declaration of function `_L'
src/mach-ixp42x/initialize.c:151: error: `LEDf' undeclared (first use in this function)
src/mach-ixp42x/initialize.c:151: error: (Each undeclared identifier is reported only once
src/mach-ixp42x/initialize.c:151: error: for each function it appears in.)
src/mach-ixp42x/initialize.c:228: error: `LED1' undeclared (first use in this function)
src/mach-ixp42x/initialize.c:260: error: `LED2' undeclared (first use in this function)
src/mach-ixp42x/initialize.c:304: error: `LED3' undeclared (first use in this function)
src/mach-ixp42x/initialize.c: In function `target_init':
src/mach-ixp42x/initialize.c:325: error: `LED6' undeclared (first use in this function)
src/mach-ixp42x/initialize.c:394: error: `LED7' undeclared (first use in this function)
make[1]: *** [src/mach-ixp42x/initialize.o] Error 1
make: *** [src/mach-ixp42x] Error 2
# cp src/mach-ixp42x/initialize.c src/mach-ixp42x/initialize.c.old
# diff -Naur src/mach-ixp42x/initialize.c.old src/mach-
ixp42x/initialize.c
--- src/mach-ixp42x/initialize.c.old    2006-09-04 19:01:41 +0000
+++ src/mach-ixp42x/initialize.c        2006-09-04 19:05:22 +0000
@@ -148,7 +148,7 @@
   PUTC_LL('A');
 #endif

-  _L(LEDf);                    /* Start with all on */
+  //_L(LEDf);                  /* Start with all on */
   GPIO_ER &= ~0xf;             /* Enable LEDs as outputs */

   /* *** FIXME: this CPSR and CP15 manipulation should not be
@@ -225,7 +225,7 @@
          /* Exit now if executing in SDRAM */
   if (EXP_CNFG0 & (1<<31)) {
     PUTC_LL ('b');
-    _L(LED1);
+    //_L(LED1);

     /* Boot mode */
     __asm volatile ("cmp %0, %2\n\t"
@@ -257,7 +257,7 @@
   }
   else {
     PUTC_LL ('n');
-    _L(LED2);
+    //_L(LED2);

 #if defined (CONFIG_SDRAMBOOT_REPORT)
     fSDRAMBoot = 1;
@@ -301,7 +301,7 @@
   usleep (1);                  /* Must wait for 3 CPU cycles before
                                   SDRAM access */

-  _L(LED3);
+  //_L(LED3);

 #if defined (CONFIG_SDRAMBOOT_REPORT)
   barrier ();
@@ -322,7 +322,7 @@

 static void target_init (void)
 {
-  _L(LED6);
+  //_L(LED6);

   //  EXP_CNFG0 &= ~EXP_CNFG0_MEM_MAP; /* Disable boot-mode for EXP_CS0  */
   //  __REG(EXP_PHYS + 0x28) |= (1<<15); /* Undocumented, but set in redboot */
@@ -391,7 +391,7 @@
   //    *IXP425_EXP_CS7 = (EXP_ADDR_T(3) | EXP_SETUP_T(3) | EXP_STROBE_T(15) |
EXP_HOLD_T(3) | EXP_RECOVERY_T(15) | EXP_SZ_512 | EXP_MUX_EN | EXP_WR_EN | EXP_C
S_EN);

 #endif
-  _L(LED7);
+  //_L(LED7);
 }

 static void target_release (void)

この2つの修正でビルドは通るようになった。

# make
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/basic/split-include
  HOSTCC  scripts/basic/docproc
  CC      src/arch-arm/entry/reset.o
  CC      src/arch-arm/entry/mmu-alloc.o
  CC      src/arch-arm/entry/sdramboot.o
  LD      src/arch-arm/entry/built-in.o
  LDS     src/arch-arm/entry/apex.lds
  CC      src/mach-ixp42x/serial.o
  CC      src/mach-ixp42x/env.o
  CC      src/mach-ixp42x/cpuinfo.o
  CC      src/mach-ixp42x/initialize.o
  CC      src/mach-ixp42x/timer.o
  CC      src/mach-ixp42x/pci.o
  CC      src/mach-ixp42x/cmd-reset.o
  LD      src/mach-ixp42x/built-in.o
  CC      src/drivers/driver.o
  CC      src/drivers/drv-mem.o
  CC      src/drivers/drv-nor-cfi.o
  LD      src/drivers/built-in.o
  LD      src/net/built-in.o
  CC      src/arch-arm/linux/atag.o
  LD      src/arch-arm/linux/built-in.o
  CC      src/apex/init.o
  CC      src/apex/console.o
  CC      src/apex/console-printf.o
  CC      src/apex/command.o
  CC      src/apex/cmd-version.o
  CC      src/apex/cmd-help.o
  CC      src/apex/cmd-boot.o
  CC      src/apex/command-history.o
  CC      src/apex/env.o
  CC      src/apex/cmd-checksum.o
  CC      src/apex/cmd-compare.o
  CC      src/apex/cmd-copy.o
  CC      src/apex/cmd-drvinfo.o
  CC      src/apex/cmd-dump.o
  CC      src/apex/cmd-env.o
  CC      src/apex/cmd-erase.o
  CC      src/apex/cmd-fill.o
  CC      src/apex/cmd-go.o
  CC      src/apex/cmd-info.o
  CC      src/apex/cmd-wait.o
  CC      src/apex/cmd-xreceive.o
  CC      src/apex/cmd-alias.o
  LD      src/apex/built-in.o
  LD      src/lib/built-in.o
  CC      src/lib/alias.o
  CC      src/lib/crc32.o
  CC      src/lib/ctype.o
  CC      src/lib/dump.o
  CC      src/lib/env.o
  CC      src/lib/lookup.o
  CC      src/lib/memcmp.o
  CC      src/lib/memset.o
  CC      src/lib/pngr.o
  CC      src/lib/sort.o
  CC      src/lib/spinner.o
  CC      src/lib/strcat.o
  CC      src/lib/strchr.o
  CC      src/lib/strcmp.o
  CC      src/lib/strcpy.o
  CC      src/lib/strcspn.o
  CC      src/lib/strlcpy.o
  CC      src/lib/strlen.o
  CC      src/lib/strnicmp.o
  CC      src/lib/strnlen.o
  CC      src/lib/vsprintf.o
  CC      src/lib/xmodem.o
  CC      src/lib/zlib-heap.o
  CC      src/lib/zlib.o
  AR      src/lib/lib.a
  LD      src/arch-arm/lib/built-in.o
  CC      src/arch-arm/lib/cp15.o
  AS      src/arch-arm/lib/div64.o
  CC      src/arch-arm/lib/entry.o
  AS      src/arch-arm/lib/lib1funcs.o
  AS      src/arch-arm/lib/memchr.o
  AS      src/arch-arm/lib/memcpy.o
  AS      src/arch-arm/lib/memzero.o
  CC      src/arch-arm/lib/relocate.o
  AR      src/arch-arm/lib/lib.a
  LD      apex
  OBJCOPY src/arch-arm/rom/apex.bin
# ls -al src/arch-arm/rom/apex.bin
-rwxr-xr-x  1 root root 36664 Sep  4 19:09 src/arch-arm/rom/apex.bin