SD card boot for AT91SAM SoC

Introduction

This page describes how to create from scratch a bootable SD card for Microchip MPU SoCs. It also includes some FAQs about SD card boot.

HELP Note that there are several ways to generate an SD Card image. Build systems like buildroot, OpenWrt or Yocto Project can easily generate SD Card images out of the box by using the proper build directives. Try to use these easy ways before trying to manipulate disk images as it's described in hereunder in this page.

Here is a summary of SD Card image names generated by these build systems:

Build system location SD Card image name
buildroot output/images sdcard.img
OpenWrt bin/target/at91/<target-name>-<libc> openwrt-<revision-board-name>-sdcard.img.gz
Yocto Project tmp/deploy/images/<machine-name> <image-name-machine-name>.rootfs.wic

SD card boot prerequisites

  • All AT91SAM SoCs support SD card boot except SAM9260, SAM9261 rev A, SAM9263 rev A and SAMA5D2 rev B.

  • Only MCI0 supports SD card boot.
    • sam9x5-ek uses MicroSD card in MCI0. Other boards use SD card in MCI0.

  • The first partition of SD card should be FAT16 or FAT32.

  • A BOOT.BIN, the at91bootstrap binary, must exist in the first FAT partition. Board's ROM code will load BOOT.BIN to SRAM and run it.
    • To compile at91bootstrap, you need to choose the configuration file for your bootstrap:
      1. Board type
        • Every support board has a directory under at91bootstrap/board/. In the support board directory, you can find the config files.
      2. Which binary bootstrap will be loaded to DDR?
        • Using at91sam9xxekxx_linux_defconfig, at91bootstrap will load IMAGE.BIN, the Linux kernel, in the same partition of SD card.
          • In this case, the bootargs passed to kernel are specified in the configuration file: at91sam9xxekxx_linux_defconfig.
        • Using at91sam9xxekxx_uboot_defconfig, at91bootstrap will load U-BOOT.BIN in the same partition of SD card.
      3. Where bootstrap will load the binary from?
        • SD card: at91sam9xxeksd_xxxxx_defconfig
        • NAND flash: at91sam9xxeknf_xxxxx_defconfig
        • Serial/data flash: at91sam9xxekdf_xxxxx_defconfig
    • For example, if we want to compile a bootstrap for at91sam9x5, which will load U-Boot in SD card, so the configuration file is:
      at91sam9x5eksd_uboot_defconfig

How to make a bootable SD card

Environment:

  • One SD or MicroSD card.

  • Linux PC used to create one or multiple partitions in SD card.
    • If your PC has no SD/MicroSD card slot, then use a USB SD/MicroSD card reader.

Step1: Insert your SD card to the Linux PC

  • If use SD card reader, the SD card will show as /dev/sdx, 'x' can be a, b, c...
    • If the SD card has several partitions, then sdx1, sdx2... indicate the 1st, 2nd and other partitions.
  • If use SD card slot in PC, the SD card will show as /dev/mmcblkx, 'x' can be 0, 1, 2...
    • If the SD card has several partitions, then mmcblkxp1, mmcblkxp2... indicate the 1st, 2nd and other partitions.

Step2: Erase the MBR of the SD card using Linux dd command

  • Umount the partitions if the SD card is auto mounted.
    mount | grep /media    # list all the partitions are mounted in /media
    sudo umount /dev/sdxx  # umount all listed by above command 

ALERT! Warning: Be very careful with this operation: if you don't choose the proper disk name, you could completely crash your host system!

ALERT! Warning: The data in your SD card will be totally destroyed!

  • Use dd command to clean the MBR and the partition information.
    sudo dd if=/dev/zero of=/dev/sdx bs=10M count=1   # if you use SD card slot, you need change the parameter to: dev/mmcblkx 

Step3: Create one or multiple partitions in SD card with Linux PC

First a FAT partition must be created. Then, if want to put a Linux root file system in SD card, you need to create one more non-FAT partition (EXT2, EXT4, etc.) to store it.

As follows, create one FAT partition and one non-FAT partition in the SD card:

  • Use Linux fdisk command to modify the partition table.
    • Start fdisk to open the SD card.
      sudo fdisk /dev/mmcblkx # if using SD card reader you need change the device name to "/dev/sdx" 
    • Press 'p' to display the partitions information. We can see that we have no partition in the 2G SD card because we have already erased the MBR part.
      Command (m for help): p
      Disk /dev/mmcblk0: 2002 MB, 2002780160 bytes
      11 heads, 10 sectors/track, 35560 cylinders
      Units = cylinders of 110 * 512 = 56320 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
      
            
    • Press 'n' to create a new primary partition and specify the partition size. For our FAT partition, 64M is enough to store BOOT.BIN and IMAGE.BIN.
      Command (m for help): n
      Command action
         e   extended
         p   primary partition (1-4)
      p
      Partition number (1-4): 1
      First cylinder (1-35560, default 1):
      Using default value 1
      Last cylinder, +cylinders or +size{K,M,G} (1-35560, default 35560): +64M 
    • Press 't' to specify the new partition type to FAT16, which is the same as the FAT partition we deleted.
      Command (m for help): t
      Selected partition 1
      Hex code (type L to list codes): 6
      Changed system type of partition 1 to 6 (FAT16)
            
    • Press 'n' to create an additional primary Linux partition. In this case we specify the size as 1500M.
      • If you want to use the whole available space for the 2nd partition, don't specify the size, just press enter key.
        Command (m for help): n
        Command action
           e   extended
           p   primary partition (1-4)
        p
        Partition number (1-4): 2
        First cylinder (1194-35560, default 1194):
        Using default value 1194
        Last cylinder, +cylinders or +size{K,M,G} (1194-35560, default 35560): +1500M 
      • By default the 2nd partition type is "Linux". So you don't need to press 't' to specify the type for it.
    • Press 'p' to display the partition information. We can see now we have two partitions.
      Command (m for help): p
      
              Device Boot      Start         End      Blocks   Id  System
      /dev/mmcblk0p1               1        1193       65610    6  FAT16
      /dev/mmcblk0p2            1194       29121     1536040   83  Linux
            
    • Press 'w' to write the changed partition information. If you want to abort the change, just press 'q'.
      Command (m for help): w
      The partition table has been altered!
      
      Calling ioctl() to re-read partition table. 

Step4: Format and mount the FAT and non-FAT partition

sudo mkfs.msdos /dev/mmcblk0p1   # format as FAT32 you need add parameters "-F 32".  if using SD card reader you need change the device name to "/dev/sdx1"
sudo mkfs.ext2 /dev/mmcblk0p2    # if using SD card reader you need change the device name to "/dev/sdx2"

sudo mount -t vfat /dev/mmcblk0p1 /mnt/fat
sudo mount -t ext2 /dev/mmcblk0p2 /mnt/ext
   

Step5: Compile the at91bootstrap binary and copy it to the FAT partition.

  • Download the latest at91bootstrap from Linux4SAM.
  • Find the correct configuration file in board/at91sam9xxxek/
    • at91sam9xxxsd_linux_defconfig: with this configuration file, at91bootstrap will load IMAGE.BIN (Linux Kernel) directly.
    • at91sam9xxxsd_uboot_defconfig: with this configuration file, at91bootstrap will load U-BOOT.BIN.
  • Compile at91bootstrap with the correct config file.

In the top directory of at91bootstrap, run the following commands (take 9x5-ek loading u-boot as an example).

make mrproper
make at91sam9x5eksd_uboot_defconfig
make
   

If no error happens, then you can find the at91bootstrap binary (at91sam9x5ek-sdcardboot-uboot-3.x.bin) in the binaries/ directory.

  • Copy at91bootstrap binary to the FAT partition, and change the name to BOOT.BIN.
     cp at91bootstrap/binaries/at91sam9x5ek-sdcardboot-uboot-3.x.bin /mnt/fat/BOOT.BIN 

    TIP Tip: If you want to copy file to the FAT partition in Windows XP/7 system, you must use a USB SD card reader.

Step6: Compile the U-Boot binary and copy it to the FAT partition

If at91bootstrap loads Linux kernel directly, then you can skip this step.

  • Compile U-Boot in Linux4sam and copy u-boot.bin to SD card's FAT partition.
  • Notice: In the current mainline U-Boot, sam9x5-ek board can save the environment in SD card. To support that, you need to:
    1. Download the latest mainline U-Boot.
    2. Run make mrproper && make at91sam9x5ek_mmc.

Step7: Copy the Kernel binary to SD card

  • For the at91bootstrap that loads kernel:
    • Compile and copy Linux kernel to the FAT partition, and change the name to IMAGE.BIN.

  • For the at91bootstrap that loads U-Boot:
    • If U-Boot doesn't support SD card read/write, then you need to flush the Kernel to NAND/serial flash, or get kernel from network.
    • If U-Boot supports SD card read/write, just copy kernel to SD card's FAT partition. Then use the following command to load its memory at 22000000:
      fatload mmc 0 22000000 kernel_file_name

TIP Tip: If you want to copy file to the FAT partition in Windows XP/7 system, then you must use a USB SD card reader.

Step8: Copy the root file system to SD card

You can build a buildroot or OE root file system, and then copy it to your EXT2/4 partition on Linux PC. Another way to get the root file system is to extract all files from Linux4sam's pre-built UBI/JFFS2 demo. Please refer to the Q&A section.

FAQ

Q: How to use EXT4 rootfile system in SD card?

Two things are needed to support EXT4 rootfile system:

  1. When create the bootable SD card, we need to format the second partition as EXT4, as follows:
    sudo mkfs.ext4 /dev/mmcblkxp2 # if using SD card reader you need change the device name to "/dev/sdx2" 
  2. Build Kernel with EXT4 support. Please add the following lines in the Linux kernel configuration file:
    CONFIG_EXT4_FS=y
    CONFIG_EXT4_FS_XATTR=y
    CONFIG_LBDAF=y 

Q: What is the bootargs used to mount the EXT parition as root file system?

setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p2 rootdelay=2'

Q: Does U-Boot support SD card read/write?

The newer version of U-Boot used by Linux4SAM supports SD card read/write.

Q: I copy the boot.bin (it is a correct bootstrap binary) to my SD card's FAT partition, but the ROM code cannot load boot.bin. What should I do?

First, check if the boot.bin is the correct one for the current EK board.

Second, rename the file with all capital letters: BOOT.BIN.

If it still doesn't work, it might be the FAT partition offset, which causes that ROM code cannot find the BOOT.BIN.

The solution is to move the FAT partition's first start sector to the next sector.

The following shows using fdisk command to open SD card. Press x to enter expert mode, and then press b to move the partition's beginning sector offset to the next sector.

  • Using fdisk command to open the SD card. Press 'p' to display the partition information.
    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: 1977 MB, 1977614336 bytes
    255 heads, 63 sectors/track, 240 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x6abc6fb3
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1               1         240     1927768+   b  W95 FAT32 
  • Press 'x' to enter expert mode.
     Command (m for help): x 
  • Press 'p' to display the partition information. As we can see, the start sector is 63, and we need to move it to 64.
    Expert command (m for help): p
    
    Disk /dev/sdb: 255 heads, 63 sectors, 240 cylinders
    
    Nr AF  Hd Sec  Cyl  Hd Sec  Cyl     Start      Size ID
     1 00   1   1    0 254  63  239         63    3855537 0b
     2 00   0   0    0   0   0    0          0          0 00
     3 00   0   0    0   0   0    0          0          0 00
     4 00   0   0    0   0   0    0          0          0 00
    
    Expert command (m for help): m
    Command action
       b   move beginning of data in a partition
       c   change number of cylinders
       d   print the raw data in the partition table
       e   list extended partitions
       f   fix partition order
       g   create an IRIX (SGI) partition table
       h   change number of heads
       i   change the disk identifier
       m   print this menu
       p   print the partition table
       q   quit without saving changes
       r   return to main menu
       s   change number of sectors/track
       v   verify the partition table
       w   write table to disk and exit 
  • Press 'b' to change the start sector to 64.
    Expert command (m for help): b
    Partition number (1-4): 1
    New beginning of data (63-3855599, default 63): 64
    
    Expert command (m for help): p
    
    Disk /dev/sdb: 255 heads, 63 sectors, 240 cylinders
    
    Nr AF  Hd Sec  Cyl  Hd Sec  Cyl     Start      Size ID
     1 00   1   1    0 254  63  239         64    3855536 0b
    Partition 1 has different physical/logical beginnings (non-Linux?):
         phys=(0, 1, 1) logical=(0, 1, 2)
     2 00   0   0    0   0   0    0          0          0 00
     3 00   0   0    0   0   0    0          0          0 00
     4 00   0   0    0   0   0    0          0          0 00
    
  • Press 'w' to apply the change. If you want to abort the change, just press 'q'.
    Expert command (m for help): w
    The partition table has been altered!
    
    Calling ioctl() to re-read partition table. 

Q: How to extract the files of pre-compiled demo (UBI, JFFS2), and copy them to SD card's ext2/4 partition?

To do this, mount the ubi/jffs2 pre-compiled demo image as a loopback device in your PC, and then copy all files to your SD card's partition.

Here are the steps: (tested in Ubuntu 11.04.)

  • Install "mtd-utils" package in PC.
    sudo apt-get install mtd-utils

  • Mount UBIFS images as a loopback:
    modprobe nandsim first_id_byte=0x2c second_id_byte=0xda third_id_byte=0x00 fourth_id_byte=0x15
    modprobe ubi mtd=0
    ubidetach /dev/ubi_ctrl -m 0
    ubiformat /dev/mtd0 -s 2048 -f Angstrom-x11-at91sam9-image-eglibc-ipk-v20110624-at91sam9x5ek.rootfs.ubi
    ubiattach /dev/ubi_ctrl -m 0 -O 2048
    mkdir /mnt/loop
    mount -t ubifs ubi0 /mnt/loop
    cp -R /mnt/loop/* /new/directory 

  • Mount JFFS2 images as a loopback:
    modprobe nandsim first_id_byte=0x2c second_id_byte=0xda third_id_byte=0x00 fourth_id_byte=0x15
    modprobe mtdblock
    modprobe mtdchar
    modprobe mtd mtd=0
    dd if=Angstrom-x11-at91sam9m10-image-glibc-ipk-2009.X-stable-at91sam9m10g45ek.rootfs.jffs2 of=/dev/mtd0
    mkdir /mnt/loop
    mount -t jffs2 /dev/mtdblock0 /mnt/loop
    cp -R /mnt/loop/* /new/directory/ 

TIP Tip: if you are using sama5d4ek or sama5d4_xplained board, the nand flash is different, so please use following line to do the nandsim, and change the page size to 4096.

sudo modprobe nandsim first_id_byte=0x2c second_id_byte=0xdc third_id_byte=0x90 fourth_id_byte=0xa6
   

Q: Why the SD card with two partitions cannot be recognized in Windows PC?

  • If using SD card slot in PC, the Windows XP/7 system cannot recognize the multi-partitioned SD/MicroSD card. It will prompt a message: "Disk is not formatted".
  • Use USB SD/MicroSD card reader so that Windows system can recognize the multi-partitioned SD card.

Q: Can I use Windows' default format tool instead of dd & mkfs.msdos to format the SD Card?

In general, Windows' default format tool can work well. But sometimes it may cause problems for SD boot.

Because in Windows OS, the format behavior is different when using the notepad's SD card slot and using USB SD card reader to read the SD card.

  • If using notepad's SD card slot, the SD card will be formatted as unpartitioned (No MBR, the first physical sector is FAT boot sector).
  • If using USB SD card reader, the SD card will be formatted as partitioned (with MBR in the first physical sector).

If the SD card is formatted as unpartitioned, then using Linux fdisk command to create partitions will cause problems. Since fdisk command only modifies MBR, it will think the first sector of the unpartitioned SD card as MBR. The solution for this case is to run dd to erase SD card's sectors. Please follow Step2.

Reference