第3章 ソフトウェアの移行に関して

3.1. 対応ソフトウェア

新フラッシュメモリ適用品(型番: AG43*-****)を動作させるには、以下のソフトウェアを使用してください。

  • hermit-at-3.10.0-source.tar.gz以降 (イメージファイル名: loader-armadillo-iotg-std-v3.10.0.bin以降)

  • linux-3.14-at10.tar.gz以降 (イメージファイル名: linux-aiotg-std-v2.09.bin.gz以降)

[ティップ]

従来品、Armadillo-IoTゲートウェイ G2(型番: AG42*-****)で新フラッシュメモリ適用品対応ソフトウェアを使用しても、フラッシュメモリメモリマップはこれまで通り 表2.1「従来品 フラッシュメモリ メモリマップ」に記載した仕様で動作します。

3.2. お客様が開発したソフトウェアの移行方法について

ここでは、従来品をベースに開発したソフトウェア(Hermit-At, Linux カーネル)を、どのように新フラッシュメモリ適用品に移行すべきか考えられるパターンを記載します。

ここで記載するのはあくまで移行方法の例であり、2章変更による影響: フラッシュメモリのメモリマップ「新フラッシュメモリ適用に伴うソフトウェア変更箇所」「ソフトウェアから新フラッシュメモリ適用品か判別する方法」を十分に確認し、お客様の開発状況に合わせ適切な方法を検討・適宜選択してください。

新フラッシュメモリ適用品対応ソフトウェアにアップデートする

ユーザーランド(Atmark-Dist)のみ変更しており、Hermit-At, Linux カーネルに変更を加えていない場合や、カーネルコンフィギュレーションのみ変更した場合は、基本的に、新フラッシュメモリ適用品対応ソフトウェアにそのままアップデートすることで移行が可能です。

お客様が行った修正を、新フラッシュメモリ適用品対応ソフトウェアに入れる

お客様でHermit-At, Linux カーネルのソースコードの変更をしているが、簡単な変更のみである、または変更量が小さい場合、この方法がスムーズである場合が多いです。

お客様のソフトウェアに、新フラッシュメモリ適用に伴うソフトウェア変更箇所 を入れる

お客様でソースコードの変更をしており、変更量が多い、最新のソフトウェアにすると動かなくなる機能がある場合、この方法がスムーズである場合が多いです。

[ティップ]

Hermit-At, Linux カーネルの変更をしていなくても、ユーザーランドからmtdデバイスファイル(/dev/mtd*)をopenし、アクセスを行うようなアプリケーションを作成している場合、フラッシュメモリメモリマップが変更になっているため、影響がある可能性があります。

3.3. 新フラッシュメモリ適用に伴うソフトウェア変更箇所

新フラッシュメモリへの対応に伴い、Hermit-At、Linux カーネルの変更を行った箇所を記載します。

主に以下の変更を行なっています。

  • 新フラッシュメモリのドライバーの有効化と変更

  • 新フラッシュメモリ適用品か、従来品かの判別とそれに合わせたフラッシュメモリ メモリマップの設定

3.3.1. Hermit-Atの変更点

3.3.1.1. src/target/driver/flash_core.c

CFIの情報を元に、搭載フラッシュメモリの判別を行う処理を追加しました。

--- a/src/target/driver/flash_core.c
+++ b/src/target/driver/flash_core.c
@@ -23,6 +23,50 @@ flash_eb eb;
 
 static flash_protect *protect_table = 0;
 
+#define flash_read(addr)         cpu_to_le16(read16((addr)))
+#define flash_write(addr, b)     write16((addr), cpu_to_le16((b)))
+
+static int qry_present(const u32 base)
+{
+       u8 offs, v;
+       u8 qry[] = "QRY";
+
+       for (offs = 0; offs < 3; offs++) {
+               v = flash_read(base + ((0x10 + offs)<<1));
+               if ( v != *(qry + offs))
+                       return 0;
+       }
+       return 1; // "QRY" found
+}
+
+int flash_get_cfi_vendor_spec(const u32 base_addr)
+{
+       int type;
+       u32 base;
+       u16 primary_spec = 0;
+
+       base = (base_addr & FLASH_BASE_MASK);
+       flash_write(base, 0xF0);
+       flash_write(base, 0xFF);
+       flash_write(base, 0x98);
+
+       if (!qry_present(base))
+               flash_write(base + (0x555 << 1), 0x98);
+       primary_spec = flash_read(base + (0x13 << 1));
+       switch (primary_spec){
+       case 0x0001:
+               type = FLASH_TYPE_INTEL;
+               break;
+       case 0x0002:
+               type = FLASH_TYPE_AMD;
+               break;
+       default:
+               type = -1;
+               break;
+       }
+       return type;
+}
+
 int flash_initialize(const int type, const u32 base_addr)
 {
        memzero(&fops, sizeof(flash_ops));
@@ -77,6 +121,16 @@ int flash_initialize(const int type, const u32 base_addr)
        return 0;
 }
 
+int flash_initialize_cfi(const u32 base_addr)
+{
+       int type;
+
+       type = flash_get_cfi_vendor_spec(base_addr);
+       if (type < 0)
+               return -1;
+       return flash_initialize(type, base_addr);
+}
+
 int flash_register_protect_table(flash_protect *table)
 {
        protect_table = table;

3.3.1.2. src/target/driver/flash_amd.c

新フラッシュメモリのbuffer programに対応しました。

--- a/src/target/driver/flash_amd.c
+++ b/src/target/driver/flash_amd.c
@@ -21,8 +21,21 @@
 
 static flash_cfi cfi_info;
 
+#define AMD_CMD_UNLOCK_START           0xAA
+#define AMD_CMD_UNLOCK_ACK             0x55
+#define AMD_CMD_WRITE_TO_BUFFER                0x25
+#define AMD_CMD_WRITE_BUFFER_CONFIRM   0x29
+#define AMD_BUFFER_PROGRAM_ALIGNED_MASK (0xf)
+
+#define FORCE_WORD_PROGRAM (0)
 #define FLASH_TIMEOUT 400000000
 
+#define min(x, y) ({                 \
+       typeof(x) _min1 = (x);        \
+       typeof(y) _min2 = (y);        \
+       (void) (&_min1 == &_min2);    \
+       _min1 < _min2 ? _min1 : _min2;})
+
 #define flash_read(addr)         read16(addr)
 #define flash_write(addr, b)     write16((addr), (b))
 
@@ -73,6 +86,12 @@ static int flash_status_full_check(addr_t addr, unsigned short value1, unsigned
        return (status1 != value1 || status2 != value2) ? -1 : 0;
 }
 
+static void flash_amd_unlock_seq(addr_t base)
+{
+       flash_write_cmd(base + (0x555 << 1), AMD_CMD_UNLOCK_START);
+       flash_write_cmd(base + (0x2AA << 1), AMD_CMD_UNLOCK_ACK);
+}
+
 /*
  * Program the contents of the download buffer to flash at the given
  * address.  Size is also specified; we shouldn't have to track usage
@@ -86,7 +105,7 @@ static int flash_status_full_check(addr_t addr, unsigned short value1, unsigned
  * them because in the context of this command they signify bugs, and
  * we want to be extra careful when writing flash.
  */
-int flash_amd_program(const u32 from, const u32 to, const u32 size)
+static int flash_amd_word_program(const u32 from, const u32 to, const u32 size)
 {
        int status;
        unsigned int loop;
@@ -121,6 +140,53 @@ int flash_amd_program(const u32 from, const u32 to, const u32 size)
        return status;
 }
 
+static int flash_amd_buffer_program(const u32 from, const u32 to, const u32 size)
+{
+       u32 base;
+       u32 addr;
+       u32 end;
+       u32 data;
+       size_t max_program_size;
+
+       if (from & UNALIGNED_MASK) return -H_EALIGN;
+       if (to & UNALIGNED_MASK) return -H_EALIGN;
+       if (cfi_info.max_buf_write_size < 2) return -H_ENOCMD;
+
+       base = (to & FLASH_BASE_MASK);
+       addr = to;
+       end  = to + size;
+       data = from;
+       max_program_size = 1 << cfi_info.max_buf_write_size;
+
+       while (addr < end) {
+               u32 block_start = addr & ~(max_program_size - 1);
+               /* We must not cross write block boundaries */
+               u32 next_boundary = (addr + max_program_size) & ~(max_program_size - 1);
+               u32 program_end = min(end, next_boundary);
+
+               flash_amd_unlock_seq(base);
+               flash_write_cmd(block_start, AMD_CMD_WRITE_TO_BUFFER);
+               flash_write_cmd(block_start, ((program_end - addr) >> 1) - 1);
+
+               /* program flash memory par 16 bits word */
+               for (; addr < program_end; addr+=2, data+=2) {
+                       flash_write(addr, *((u16 *)data));
+               }
+
+               flash_write_cmd(block_start, AMD_CMD_WRITE_BUFFER_CONFIRM);
+               flash_status_wait(addr - 2, *((u16 *)(data - 2)));
+       }
+       return 0;
+}
+
+int flash_amd_program(const u32 from, const u32 to, const u32 size)
+{
+       if (FORCE_WORD_PROGRAM)
+               return flash_amd_word_program(from, to, size);
+       else
+               return flash_amd_buffer_program(from, to, size);
+}
+

3.3.1.3. target/armadillo-iotg-std/Kconfig

新フラッシュメモリ適用品で、強制的に従来品のフラッシュメモリで動作するコンフィギュレーション "FORCE_MTDPARTS4x0" を追加しました。

"FORCE_MTDPARTS4x0"はデフォルト無効です。

[警告]

Linux カーネルが"FORCE_MTDPARTS4x0"に対応していないため、このコンフィギュレーションは現時点で使用することができません。

--- a/src/target/armadillo-iotg-std/Kconfig
+++ b/src/target/armadillo-iotg-std/Kconfig
@@ -3,5 +3,46 @@
 #
 
 if PLATFORM_ARMADILLO_IOTG_STD
+config FORCE_MTDPARTS4x0
+       bool "force use old(4x0) mtd parts for Armadillo-411 and Armadillo-441"
+       default n
+       help
 ※ 省略
+                            +------------+   +------------+
 endif # PLATFORM_ARMADILLO_IOTG_STD

3.3.1.4. configs/armadillo_iotg_std_defconfig

新フラッシュメモリを動作させるために、"CONFIG_FLASH_AMD"を有効化しています。

--- a/configs/armadillo_iotg_std_defconfig
+++ b/configs/armadillo_iotg_std_defconfig
@@ -74,7 +74,7 @@ CONFIG_CONSOLE_TTYMXC1=y
 CONFIG_DEFAULT_CONSOLE="ttymxc1"
 CONFIG_STANDARD_CONSOLE="ttymxc1"
 CONFIG_FLASH=y
-# CONFIG_FLASH_AMD is not set
+CONFIG_FLASH_AMD=y
 CONFIG_FLASH_INTEL=y
 # CONFIG_FLASH_SPI is not set
 CONFIG_ETHERNET=y

3.3.1.5. configs/armadillo_iotg_std_boot_defconfig

新フラッシュメモリを動作させるために、"CONFIG_FLASH_AMD"を有効化しています。

--- a/configs/armadillo_iotg_std_boot_defconfig
+++ b/configs/armadillo_iotg_std_boot_defconfig
@@ -72,7 +72,7 @@ CONFIG_CONSOLE_TTYMXC1=y
 CONFIG_DEFAULT_CONSOLE="ttymxc1"
 CONFIG_STANDARD_CONSOLE="ttymxc1"
 CONFIG_FLASH=y
-# CONFIG_FLASH_AMD is not set
+CONFIG_FLASH_AMD=y
 CONFIG_FLASH_INTEL=y
 # CONFIG_FLASH_SPI is not set
 CONFIG_ETHERNET=y

3.3.1.6. target/armadillo-iotg-std/board.h

新フラッシュメモリ適用品を表すBoard type ”BOARD_TYPE_ARMADILLO411" を追加しました。なお、従来品のBoard typeは"BOARD_TYPE_ARMADILLO410"となります。

Board typeはArmadillo-IoT G2の搭載EEPROM内に書き込まれており、Hermit-At内でEEPROMをReadしBoard typeの判別を行います。

--- a/src/target/armadillo-iotg-std/board.h
+++ b/src/target/armadillo-iotg-std/board.h
@@ -36,6 +36,7 @@ struct board_private {
        u8 reserved;
        u16 type;       /* Board type */
 #define BOARD_TYPE_ARMADILLO410                0x0410
+#define BOARD_TYPE_ARMADILLO411                0x0411
        u16 hardware;   /* Hardware ID */
        u8 base_board_gen;      /* Base Board Generation */

3.3.1.7. include/target/machine.h

新フラッシュメモリ適用品を表すmachine_nr ”MACH_ARMADILLO411" を追加しました。なお、従来品のmachine_nrは"MACH_ARMADILLO410"となります。

Hermit-At内でEEPROMに書き込まれているBoard typeを判別し、それに対応したmachine_nrの設定を行います。machine_nrはARM LinuxのATAGという仕組みを利用し、Linux カーネル側に伝えられます。Linux カーネルはこのmachine_nrを元に、製品の種類を判別します。

--- a/include/target/machine.h
+++ b/include/target/machine.h
@@ -12,6 +12,8 @@
 #define MACH_ARMADILLO440      (2374)
 #define MACH_ARMADILLO460      (3270)
 #define MACH_ARMADILLO410      (4636)
+#define MACH_ARMADILLO411      (5136)
 #define MACH_ARMADILLO800EVA   (3863)
 #define MACH_ARMADILLO810      (4115)
 #define MACH_ARMADILLO840      (4264)

3.3.1.8. src/target/armadillo-iotg-std/board.c

EEPROM内に記載されているボード情報から、machine_nrを登録します。

machine_nrの値に応じて、新フラッシュメモリ適用品のフラッシュメモリメモリマップを使用するか、従来品のフラッシュメモリメモリマップを使用するかを判別します。

コンフィギュレーション"CONFIG_FORCE_MTDPARTS4x0"を設定した場合は、machine_nrの値に関係なく、従来品のフラッシュメモリメモリマップで動作します。

--- a/src/target/armadillo-iotg-std/board.c
+++ b/src/target/armadillo-iotg-std/board.c
@@ -28,11 +28,18 @@
 #include <gpio_pca9538.h>
 #include "board.h"
 
+#if defined(CONFIG_FORCE_MTDPARTS4x0)
+int force_mtdparts4x0 = 1;
+#else
+int force_mtdparts4x0 = 0;
+#endif
+
 char target_name[256];
 char *target_profile = target_name;
 
 static struct board_private board_priv;
 static struct memory_device mdev_param;
+static struct memory_map armadillo_iotg_std_4x1_memory_map;
 
 #define FLASH_ADDR(offset) (FLASH_START + (offset))
 #define RAM_ADDR(offset) (DRAM_START + (offset))
@@ -420,7 +427,16 @@ static void armadillo_iotg_std_setup_private_data(struct platform_info *pinfo)
        pinfo->system_rev = ((u32)priv->hardware & ~0xffu) |
                            ((u32)priv->base_board_gen << 16);
 
-       pinfo->machine_nr = MACH_ARMADILLO410;
+       switch (priv->type) {
+       case BOARD_TYPE_ARMADILLO411:
+               pinfo->machine_nr = MACH_ARMADILLO411;
+               break;
+       case BOARD_TYPE_ARMADILLO410:
+               /* FALL THROUGH */
+       default:
+               pinfo->machine_nr = MACH_ARMADILLO410;
+               break;
+       }
 }
 
 static void armadillo_iotg_std_setup_watchdog(struct platform_info *pinfo)
@@ -604,14 +620,25 @@ static void armadillo_iotg_std_setup_flash(struct platform_info *pinfo)
 {
        int val;
 
+       if (pinfo->machine_nr == MACH_ARMADILLO411 &&
+           !force_mtdparts4x0)
+               pinfo->map = &armadillo_iotg_std_4x1_memory_map;
+
        flash_initialize_cfi(FLASH_START);
 
        val = flash_get_size(FLASH_START);
        pinfo->map->flash.size = 1 << val;
-       hsprintf(pinfo->default_mtdparts,
-                "armadillo_iotg_std-nor:%p(all)ro,0x20000@0(bootloader)ro,"
-                "0x400000(kernel),%p(userland),-(config)",
-                pinfo->map->flash.size, pinfo->map->flash.size - 0x520000);
+       if (pinfo->machine_nr == MACH_ARMADILLO411 &&
+           !force_mtdparts4x0)
+               hsprintf(pinfo->default_mtdparts,
+                        "armadillo_iotg_std-nor:%p(all)ro,0x40000@0(bootloader)ro,"
+                        "0x400000(kernel),%p(userland),-(config)",
+                        pinfo->map->flash.size, pinfo->map->flash.size - 0x540000);
+       else
+               hsprintf(pinfo->default_mtdparts,
+                        "armadillo_iotg_std-nor:%p(all)ro,0x20000@0(bootloader)ro,"
+                        "0x400000(kernel),%p(userland),-(config)",
+                        pinfo->map->flash.size, pinfo->map->flash.size - 0x520000);
 }
 
 static void armadillo_iotg_std_setup_map(struct platform_info *pinfo)
@@ -693,10 +720,10 @@ static void armadillo_iotg_std_rev_fixup(struct platform_info *pinfo)
         *   Rev.B 0x02xx
         *   Rev.C 0x03xx
         */
-       if ((pinfo->system_rev & CPU_BOARD_REV_MASK) < 0x0300) {
-               memcpy(&mmcsd1_pwren_pin[0], &mmcsd1_pwren_pin_revb[0],
-                      sizeof(struct iomux_info));
-       }
+       if (pinfo->machine_nr != MACH_ARMADILLO411)
+               if ((pinfo->system_rev & CPU_BOARD_REV_MASK) < 0x0300)
+                       memcpy(&mmcsd1_pwren_pin[0], &mmcsd1_pwren_pin_revb[0],
+                              sizeof(struct iomux_info));
 }
 
 static void armadillo_iotg_std_prepare_normal_boot(struct platform_info *pinfo)
@@ -722,6 +749,25 @@ static struct memory_map armadillo_iotg_std_memory_map = {
        .free           = { RAM_ADDR(0x06000000), 0x02000000 },
 };
 
+static struct memory_map armadillo_iotg_std_4x1_memory_map = {
+       .flash          = { FLASH_ADDR(0x00000000), 0},
+       .param          = { FLASH_ADDR(0x00020000), 0x00008000 },
+
+       /* default memory map: RAM = 128MB, (FLA = 32MB) */
+       .ram            = { RAM_ADDR(0x00000000), 0 },
+       .boot_param     = { RAM_ADDR(0x00000100), 0x00000f00 },
+       .mmu_table      = { RAM_ADDR(0x00004000), 0x00004000 },
+       .kernel         = { RAM_ADDR(0x00008000), 0x007f8000 },
+/*     .hermit         = { RAM_ADDR(0x00800000), 0x00300000 }, */
+/*     .fec_desc       = { RAM_ADDR(0x00b00000), 0x00100000 }, */
+       .gunzip         = { RAM_ADDR(0x00c00000), 0x00100000 },
+/*     .stack(irq)     = { RAM_ADDR(0x00d00000), 0x00100000 }, */
+/*     .stack(svc)     = { RAM_ADDR(0x00e00000), 0x00100000 }, */
+/*     .vector         = { RAM_ADDR(0x00f00000), 0x00100000 }, */
+       .initrd         = { RAM_ADDR(0x01000000), 0x05000000 },
+       .free           = { RAM_ADDR(0x06000000), 0x02000000 },
+};
+
 static void armadillo_iotg_std_init(void)
 {
        struct platform_info *pinfo = &platform_info;
@@ -742,8 +788,13 @@ static void armadillo_iotg_std_init(void)
 
        update_target_profile();
 
-       memdev_add(flash, &mdev_param,
-                  "hermit/param", FLASH_ADDR(0x00018000), 0x00008000);
+       if (pinfo->machine_nr == MACH_ARMADILLO411 &&
+           !force_mtdparts4x0)
+               memdev_add(flash, &mdev_param,
+                          "hermit/param", FLASH_ADDR(0x00020000), 0x00008000);
+       else
+               memdev_add(flash, &mdev_param,
+                          "hermit/param", FLASH_ADDR(0x00018000), 0x00008000);
 }
 arch_initcall(armadillo_iotg_std_init);

3.3.2. Linux カーネルの変更点

3.3.2.1. arch/arm/configs/armadillo_iotg_std_defconfig

新フラッシュメモリを動作させるために、コンフィギュレーション"CONFIG_MTD_CFI_AMDSTD"を有効化しました。

--- a/arch/arm/configs/armadillo_iotg_std_defconfig
+++ b/arch/arm/configs/armadillo_iotg_std_defconfig
@@ -122,6 +122,7 @@ CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y

3.3.2.2. arch/arm/tools/mach-types

新フラッシュメモリ適用品を表すmach-types ”ARMADILLO411" を追加しました。なお、従来品のmach-typesは従来品は"ARMADILLO410"となります。

この情報は、bootloaderからARM LinuxのATAGという仕組みを利用し、Linux カーネルに伝えられます。

--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1010,3 +1010,5 @@ eukrea_cpuimx28sd MACH_EUKREA_CPUIMX28SD  EUKREA_CPUIMX28SD       4573
 domotab                        MACH_DOMOTAB            DOMOTAB                 4574
 pfla03                 MACH_PFLA03             PFLA03                  4575
 armadillo410           MACH_ARMADILLO410       ARMADILLO410            4636
+armadillo411           MACH_ARMADILLO411       ARMADILLO411            5136

3.3.2.3. arm/mach-imx/mach-armadillo_iotg_std.c

__machine_arch_type(mach-types)の値に応じて、新フラッシュメモリ適用品のフラッシュメモリメモリマップを使用するか、従来品のフラッシュメモリメモリマップを使用するかを判別します。

--- a/arch/arm/mach-imx/mach-armadillo_iotg_std.c
+++ b/arch/arm/mach-imx/mach-armadillo_iotg_std.c
@@ -434,6 +434,30 @@ static struct mtd_partition armadillo_iotg_std_nor_flash_partitions[] = {
        },
 };
 
+static struct mtd_partition armadillo_iotg_std_4x1_nor_flash_partitions[] = {
+       {
+               .name           = "nor.bootloader",
+               .offset         = 0x00000000,
+               .size           = 2 * SZ_128K,
+               .mask_flags     = MTD_WRITEABLE,
+       }, {
+               .name           = "nor.kernel",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 32 * SZ_128K,
+               .mask_flags     = 0,
+       }, {
+               .name           = "nor.userland",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 214 * SZ_128K,
+               .mask_flags     = 0,
+       }, {
+               .name           = "nor.config",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 8 * SZ_128K,
+               .mask_flags     = 0,
+       },
+};
+
 static const struct physmap_flash_data
                armadillo_iotg_std_nor_flash_pdata __initconst = {
        .width          = 2,
@@ -441,6 +465,13 @@ static const struct physmap_flash_data
        .nr_parts       = ARRAY_SIZE(armadillo_iotg_std_nor_flash_partitions),
 };
 
+static const struct physmap_flash_data
+               armadillo_iotg_std_4x1_nor_flash_pdata __initconst = {
+       .width          = 2,
+       .parts          = armadillo_iotg_std_4x1_nor_flash_partitions,
+       .nr_parts       = ARRAY_SIZE(armadillo_iotg_std_4x1_nor_flash_partitions),
+};
+
 static const struct resource
 armadillo_iotg_std_nor_flash_resource __initconst = {
        .flags          = IORESOURCE_MEM,
@@ -663,10 +694,16 @@ static void __init armadillo_iotg_std_init(void)
        imx25_add_imx_usb_hs(&usbh2_pdata);
        imx25_add_imx2_wdt();
 
-       platform_device_register_resndata(NULL, "physmap-flash", -1,
-                       &armadillo_iotg_std_nor_flash_resource, 1,
-                       &armadillo_iotg_std_nor_flash_pdata,
-                       sizeof(armadillo_iotg_std_nor_flash_pdata));
+       if (__machine_arch_type == MACH_TYPE_ARMADILLO411)
+               platform_device_register_resndata(NULL, "physmap-flash", -1,
+                                                 &armadillo_iotg_std_nor_flash_resource, 1,
+                                                 &armadillo_iotg_std_4x1_nor_flash_pdata,
+                                                 sizeof(armadillo_iotg_std_4x1_nor_flash_pdata));
+       else
+               platform_device_register_resndata(NULL, "physmap-flash", -1,
+                                                 &armadillo_iotg_std_nor_flash_resource, 1,
+                                                 &armadillo_iotg_std_nor_flash_pdata,
+                                                 sizeof(armadillo_iotg_std_nor_flash_pdata));
 
        imx25_named_gpio_init();
 
@@ -734,3 +771,16 @@ MACHINE_START(ARMADILLO410, "Armadillo-410")
        .init_late      = armadillo_iotg_std_init_late,
        .restart        = mxc_restart,
 MACHINE_END
+
+MACHINE_START(ARMADILLO411, "Armadillo-410")
+       /* Maintainer: Atmark Techno, Inc.  */
+       .atag_offset    = 0x100,
+       .map_io         = mx25_map_io,
+       .init_early     = imx25_init_early,
+       .init_irq       = mx25_init_irq,
+       .handle_irq     = imx25_handle_irq,
+       .init_time      = armadillo_iotg_std_timer_init,
+       .init_machine   = armadillo_iotg_std_init,
+       .init_late      = armadillo_iotg_std_init_late,
+       .restart        = mxc_restart,
+MACHINE_END

3.4. ソフトウェアから新フラッシュメモリ適用品か判別する方法

3.4.1. Hermit-Atのソースコード内で判別する方法

src/target/armadillo-iotg-std/board.c の以下の処理を参考にしてください。"pinfo->machine_nr == MACH_ARMADILLO411"が真であれば新フラッシュメモリ適用品となります。

static void armadillo_iotg_std_init(void)
{
	struct platform_info *pinfo = &platform_info;

※ 省略

	if (pinfo->machine_nr == MACH_ARMADILLO411 &&
	    !force_mtdparts4x0)
		memdev_add(flash, &mdev_param,
			   "hermit/param", FLASH_ADDR(0x00020000), 0x00008000);
	else
		memdev_add(flash, &mdev_param,
			   "hermit/param", FLASH_ADDR(0x00018000), 0x00008000);
}

3.4.2. 保守モードのHermit-At コマンドで判別する方法

Hermit-Atのinfoコマンド、またはmemmapコマンドから判別が可能です。

新フラッシュメモリ適用品でinfoコマンドを実行すると、次のように"Board Type"が 0x00000411 となります。

hermit> info
 Board Type: 0x00000411
Hardware ID: 0x00000100
    DRAM ID: 0x00000002
     Jumper: 0x00000000
    Tact-SW: 0x00000001
 ORIG MAC-1: 00:11:0c:27:00:03
Base Board Gen: 0x00000001

新フラッシュメモリ適用品でmemmapコマンドを実行すると、次のように"bootloader"領域が"0xa0000000:0xa003ffff"となります。

hermit> memmap
0xa0000000:0xa1ffffff FLA all bf:8K bl:256x128K/l
0xa0000000:0xa003ffff FLA bootloader bf:8K bl:2x128K/l
0xa0040000:0xa043ffff FLA kernel bf:8K bl:32x128K
0xa0440000:0xa1efffff FLA userland bf:8K bl:214x128K
0xa1f00000:0xa1ffffff FLA config bf:8K bl:8x128K
0x80000000:0x87ffffff RAM dram-1

従来品でinfoコマンドを実行すると、次のように"Board Type"が 0x00000410 となります。

hermit> info
 Board Type: 0x00000410
Hardware ID: 0x000003ff
    DRAM ID: 0x00000002
     Jumper: 0x00000000
    Tact-SW: 0x00000001
 ORIG MAC-1: 00:11:0c:18:0b:ff
Base Board Gen: 0x00000001

従来品でmemmapコマンドを実行すると、次のように"bootloader"領域が"0xa0000000:0xa001ffff"となります。

hermit> memmap
0xa0000000:0xa1ffffff FLA all bf:8K bl:4x32K/l,255x128K/l
0xa0000000:0xa001ffff FLA bootloader bf:8K bl:4x32K/l
0xa0020000:0xa041ffff FLA kernel bf:8K bl:32x128K
0xa0420000:0xa1efffff FLA userland bf:8K bl:215x128K
0xa1f00000:0xa1ffffff FLA config bf:8K bl:8x128K
0x80000000:0x87ffffff RAM dram-1

3.4.3. Linux カーネルのソースコード内で判別する方法

arch/arm/mach-imx/mach-armadillo_iotg_std.c の以下処理を参考にしてください。"if (__machine_arch_type == MACH_TYPE_ARMADILLO411)" が真であれば新フラッシュメモリ適用品となります。

※ 省略 ※
#include <asm/mach-types.h>
※ 省略 ※

static void __init armadillo_iotg_std_init(void)
{
※ 省略 ※
	if (__machine_arch_type == MACH_TYPE_ARMADILLO411)

3.4.4. アプリケーションから判別する方法

/proc/mtd の内容を確認し、bootloader領域のsizeから判別が可能です。

新フラッシュメモリ適用品では次に示すように、"nor.bootloader"の"size"が00040000となります。

[root@armadillo-iotg (ttymxc1) ~]# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00040000 00020000 "nor.bootloader"
mtd1: 00400000 00020000 "nor.kernel"
mtd2: 01ac0000 00020000 "nor.userland"
mtd3: 00100000 00020000 "nor.config"

従来品では次に示すように、"nor.bootloader"の"size"が00020000となります。

[root@armadillo-iotg (ttymxc1) ~]# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00020000 00008000 "nor.bootloader"
mtd1: 00400000 00020000 "nor.kernel"
mtd2: 01ae0000 00020000 "nor.userland"
mtd3: 00100000 00020000 "nor.config"