Apex Bootloader
From Buici
Contents |
Overview
APEX is a boot loader for embedded systems. It was written to support the Sharp LH series of SystemOnChip processors though it has been ported to a few other ARM targets.
- Features
- Easy to build. It depends only on shell utilities and GCC.
- Easy to configure. There is a single configuration file and it uses the linux-2.6 Kconfig infrastructure.
- Excellent dependency management. Uses Linux kernel Kbuild to optimally manage dependencies.
- Modular. Commands and drivers may be included or excluded by configuration.
- Supported targets: LH79520, LH79524, LH7A400, LH7A404, IXP42x (e.g. Linksys NSLU2), S3C2410, and iMX31.
- Support for RARP IP configuration and TFTP transfers to the target.
- Filesystem drivers for FAT, EXT2, and JFFS2.
- Partition driver for FIS as used by Redboot.
- Small footprint. A limited feature version can be as small as 16KiB.
- Support for booting APEX from non-memory-mapped storage, e.g. NAND flash, OneNAND, I2C EEPROM, SD/MMC.
Downloading APEX
The most recently released source code and prebuilt binaries are [available for download].
Recent Changes
- 2008.05.27 (apex-1.5.14)
- Debian release 1.4.15.2 changes merged in, though no unstable Debian release made.
- Revisions to the LCD panel setups to include a new panel.
- Integration of archive of NSLU2 and other IXP patches, e.g. SlugOS.
- Added post-inst script to flash apex-nslu2 on install of package.
- 2007.10.16 (apex-1.5.13)
- Added AEABI suport
- IXP42x using inline initialization
- Unified detection of runtime address to simplify initialization/relocation routines
- Enhanced APEX context record so we can detect the version of APEX and the environment region.
- Updated command-line tool for probing APEX environment.
- Fixed clock-speed setup on the LH7A404 to make sure CPU is running 200MHz.
- Removed a lot of cruft from the NAND drivers and relocators.
- Added Karma target.
- 2007.06.02 (apex-1.5.6)
- Fixed section ordering in reset code. GCC 4.1.1 now builds Apex correctly again.
- Added an ENV_SAVEATONCE configuration option. Some non-volatile storage for the environment doesn't take to incremental updates or multiple writes. This option makes a copy of the environment in RAM and gives the user a new command, saveenv, to save it to non-volatile storage.
- 2007.05.30 (apex-1.5.4)
- Incorporated latest nslu2 patches.
- Fixed sdram-initialize command detection of 256Mib SDRAM chips.
- iMX31 reset command added.
- iMX31 sleep test command added.
- Upgrades to the IPU test code. It is now capable of capturing still images.
- Unparseable regions now generate an error message instead of silently failing.
- Added a message about the current variation to the version command output. I appears if variation are enabled and the user has activated a variation.
- 2007.05.18 (apex-1.5.2)
- Eliminated CORE tag body as it is optional.
- Completely restructured reset and initialization to allow for stackless execution until SDRAM is setup.
- New section structure allows for easy integration of both custom relocations and early relocations.
- NAND driver support for ST command structure.
- 2007.05.10 (apex-1.5.0)
- Added bootable iMX31 platform. Presently, only a custom board is supported as there is lack of configuration for the iMX31ADS development platform.
- Added OneNAND flash driver with relocation support to allow booting from OneNAND.
- Fixed startup command definition to allow for an empty startup command.
- There is debug support for the iMX31 IPU in pursuit of a working sensor interface. This code includes I2C IO routines that could be generalized.
- CPSR is now set to supervisor on startup as this is a more correct operating mode for the boot loader.
- Added target board description string that is shown with the program copyright and help.
- Begun reorganization of the bootstrap so that APEX can boot without depending on the ARM specific procedure call mechanism.
- Fixed a typo in the environment setup that was inserting a copy for the ramdisk even though there was none requested.
- Enhanced the dm9000 command to properly choose the default interface in the event that more than one could be present on the system, but only one is.
- Reorganized the command invocation routine so that APEX squaks when the user enters an unrecognized command.
- Rolled minor revision for new architecture, ARMV6.
- 2007.04.09 (apex-1.4.18)
- Fixed drv-mem to properly handle word width IO. On some architectures, SoC registers won't read/write correctly unless using the expected width.
- Fixed the mx31 usleep function which was preventing the dm9000 code from being able to access the EEPROM. mx31 doesn't yet boot, but it's really close.
- 2007.02.25 (apex-1.4.17)
- Added sdram-init function for ixp4xx to support memory expansion. Command detects the SDRAM organization. May even work with 4-chip configurations, though not tested. sdram-init function uses the cache to store part of APEX while the SDRAM controller is being reprogrammed.
- Added cache support to the nor-flash driver which significantly the read-time.
- Improved the nor-flash device timing on the NSLU2. This, with the cache feature cuts the load time from flash in half. The timing improvement should also improve the speed of IO to flash from within the Linux kernel.
- 2007.02.15 (apex-1.4.16)
- Fixed a couple of Debian bugs including support for EABI. Added alternatives to Debian specific configs.
- Revised wait command to accept a zero wait time. This gives no delay, but does allow the boot process to be interrupted with a ^C.
- ST NAND flash protocol support started. It can read from ST NAND flash, but there is no flash writing or erasing support.
- Spansion NOR flash protcol support added, though not tested by me since I don't have any hardware to test against.
- Revised fill command to support width parameters and to be nicer about the width of the output region. Essentially, it is now a useful command.
- memory scan function allows the RAM memory map to be updated after APEX has booted. This, with the revised fill command, allows support for fat-SLUGs without requiring replacement of the primary boot loader.
- 2007.01.29 (apex-1.4.13)
- Fixed ext2 driver block caching so that multiple partitions are properly accessed.
- Revisions to the FIS driver in light of updates to the kernel. We now can detect the end of the partition table without scanning to the end of the block.
- Revised the memory test based on recommendations received by email. Still investigating.
- Added support for variations, a method for changing the boot mode based on runtime input from the user. The Companion and the NSLU2 both have routines to accept user input. The Debian packages allow customization of the boot process via the environment.
- New user-mode program to browse and modify the APEX flash environment.
- 2007.01.08 (apex-1.4.11)
- Fixed check in FIS driver for swapped-ness of the FIS partition table. This check is more robust that the originals ones that compared the erase block size with the length of the partition table as described by the partition entry for it. Now, it checks that the address of the partition table matches the address where the entry is being read.
- 2007.01.08 (apex-1.4.10)
- Support for more than one dm9000, though this is only for the sake of setting and programming mac addresses.
- Preinitialization support for the benefit of difficult NAND boot schemes. Preinitialization allows APEX to boot in situations where the CPU copies a very small portion of the loader, e,g, 512 bytes, from flash to SRAM and starts execution there. Preinitialization allows for an APEX customization to continue to bootstrap before jumping to the SDRAM initialization. When the CPU can copy for than 512 bytes, it is usually possible to execute the SDRAM initialization before copying the rest of APEX from NAND.
- Generic NAND driver implemented.
- Added several new LCD panels. Normalized the initialization data.
- Enhanced the FIS driver to cope with swapped partition tables. This is explicitly to support little-endian execution (e.g. ixp4xx) while maintaining RedBoot as a big-endian primary loader.
- Support for an early memory test. Still needs indicator feedback to the user when something goes wrong.
- Added '-' prefix support for commands in the startup variable. Adding the '-' tells APEX to ignore the return value from the command.
- Variation support added for boot-time/run-time selection of the boot variables. See README_variations. Variation service defined for nslu2.
- Fixed byte-swapping in the nor-cfi driver so that APEX can write a big-endian environment while running in little-endian mode.
- Applied rwhitby's patches include several configurations and a fix to the FIS driver for deleted partition entries.
Apex Bootloader Change History continues with older change notes.
Bootstrapping APEX from LogicLoader (BOLO/LOLO)
LOLO may be used to load APEX from a tftp server, from a CompactFlash card, or over the serial console. By doing do, may leave LOLO is NOR flash as the primary boot loader and chain to APEX as needed. Bear in mind that it is generally unwise to replace the boot loader without access to a working JTAG emulator that can reprogram flash memory. If you ever find yourself with a board that has no functioning boot loader, JTAG is your best bet for recovering.
Loading APEX via CompactFlash
In this first procedure, we're going to use a CompactFlash card to convey APEX. Format a CF card with at least one FAT partition. This partition must be 32MiB--this is a limitation of LOLO reported by some users that I just happened to get right when I first wrote this portion of the APEX documentation. The partition doesn't have to be the first one.
# fdisk -l /dev/hde Disk /dev/hde: 128 MB, 128188416 bytes 8 heads, 32 sectors/track, 978 cylinders Units = cylinders of 256 * 512 = 131072 bytes Device Boot Start End Blocks Id System /dev/hde1 1 733 93808 83 Linux /dev/hde2 734 978 31360 6 FAT16
Copy the apex program to the FAT partition of the CF card. You can verify that you have the right file with the GNU/Linux file command. You are looking for the fact that this is an ELF file. Don't worry that the program isn't stripped.
# file apex apex: ELF 32-bit LSB executable, ARM, version 1 (ARM), statically linked, not stripped
Flush the data to the CF card and then eject it. Insert it into the SDK board CompactFlash slot. Reset the SDK board and you should see the LogicLoader startup message followed by the losh> prompt. Loading APEX requires a few steps.
The address that you want to use for the exec command is the address that LOLO reports as the load address. It will be 0x20200000 on the LH7952X processors and 0xc0200000 on the LH7A40X processors.
losh> mount fatfs /cf
act c h s type c h s lba sects
part 0: 00 001 01 00 83 007 a0 dc 00000020 0002dce0 UNKNOWN FS
part 1: 00 000 81 dd 06 007 e0 d1 0002dd00 0000f500 FAT16 >32MB
part 2: 00 000 00 00 00 000 00 00 00000000 00000000 UNKNOWN FS
part 3: 00 000 00 00 00 000 00 00 00000000 00000000 UNKNOWN FS
losh> cd cf
losh> ls
r: apex 166154
losh> load elf apex
loading from apex:
R.....
elf file type : 0x0002
machine type: 0028 version: 1
prog start addr : 0x20200000
num prog headers: 1
num sect headers: 25
prog header size: 32 - 52/52 - delta:32684
offset : 0x00008000 disk length: 0x00008998 mem len: 0x0000d3e4
phyaddr: 0x20200000 vaddr : 0x20200000 dl addr: 0x20200000
losh> exec 0x20200000
APEX Boot Loader 1.2.11 -- Copyright (c) 2004,2005 Marc Singer
APEX comes with ABSOLUTELY NO WARRANTY. It is free software and you
are welcome to redistribute it under certain circumstances.
For details, refer to the file COPYING in the program source.
apex => mem:0x20200000+0x8998 (35224 bytes)
env => nor:128k+64k
Use the 'help .' command to get a list of help topics.
# copy nor:256k+1536k 0x20008000
1572864 bytes transferred
apex>
Once you are satisfied, you can use APEX to erase flash and write itself as the boot loader. Use the $apex alias variable to refer to the location of apex in memory.
apex> erase nor:0 apex> copy $apex nor:0 # copy mem:0x20200000+0x8998 nor:0 35224 bytes transferred
When you reset the SDK board, APEX will run.
Loading APEX over the Serial Console
If you don't have a CompactFlash card handy, you may want to load APEX using the serial console. It looks very similar to the procedure for CompactFlash except that you'll use the load elf command in LOLO to initiate the transfer and then send apex using your terminal program. LOLO doesn't use a transfer protocol such as Xmodem or Zmodem in this case. You need to send the raw data over the serial line. For example, in Microsoft Windows' Hyperterminal program you send the file apex with the "Send As Text" transfer command.
Specifying Regions
One of the key features of APEX is the use of regions to describe IO.
apex> dump mem:0+32 00000000: 06 00 00 ea 47 00 00 ea 46 00 00 ea 45 00 00 ea ...êG..ê F..êE..ê 00000010: 44 00 00 ea 43 00 00 ea 42 00 00 ea 41 00 00 ea D..êC..ê B..êA..ê
The mem:0+32 is a region specification for RAM. It describes 32 bytes of data at the start of addressable memory and is handled by the mem: driver. The dump command displays the contents of that region.
Regions give a simple set of commands much versatility.
apex> dump 0
The default driver is mem: and the default length for the dump command is 64 bytes. This command dumps the first 64 bytes of addressable memory.
apex> dump nor:0
Dumps the first 64 bytes of NOR flash.
apex> erase nor:0
Erases the first NOR flash block.
apex> copy 0xc0200000+0x4c50 nor:
Copies from memory to NOR flash. This will program flash.
apex> xdownload nor:0
Download data over the serial line using the xmodem protocol and write it directly to flash.
IXP42x and the Linksys NSLU2 (aka SLUG)
APEX supports the Intel IXP42x processor which is the CPU in the SLUG. As of version 1.2.11, APEX boots the SLUG offering an alternative to the default RedBoot loader.
In contrast to RedBoot, APEX spends 10 fewer seconds in startup and is only about 40KiB long. I suspect that RedBoot is doing a memory test and other diagnostics which contribute to the longer load time. RedBoot requires two flash blocks. APEX can share a single flash block with it's user editable environment.
Running APEX in SDRAM
- Attach a serial cable to your slug. If you are lost already, start with [adding a serial port to your slug].
- Power-on the slug. When you see the +, press ^C one time.
- After about 10 seconds, RedBoot will signon and show a prompt.
- Upload apex.bin to your slug. After starting the RedBoot load command, use the upload feature of your terminal program to send apex.bin via xmodem.
RedBoot> load -b 0x01000000 -r -m xmodem
- It shouldn't take long once the sender and receiver synchronize. When it is done, jump to the first instruction. APEX will start immediately and then boot into Linux.
RedBoot> g 0x01000000 APEX Boot Loader 1.2.11 -- Copyright (c) 2004,2005 Marc Singer APEX comes with ABSOLUTELY NO WARRANTY. It is free software and you are welcome to redistribute it under certain circumstances. For details, refer to the file COPYING in the program source. apex => mem:0x00200000+0x6e4c (28236 bytes) env => nor:128k+64k Use the 'help .' command to get a list of help topics. # copy nor:0x60010+0xffff0 0x00008000 1048560 bytes transferred # copy nor:0x160010+0x69fff0 0x01000000 6946800 bytes transferred # wait 10 Press a key to cancel autoboot. Press a key to cancel autoboot. # boot Booting kernel at 0x00008000... Uncompressing Linux........................................................... done, booting the kernel.
Writing APEX to NOR Flash
Before committing APEX to flash, make sure you have a way to restore the original boot loader. If this procedure doesn't work for you, I'm not going to be able to drop by to fix it.
The memory copy of APEX can be written directly to flash. Aside from using the Linux kernel's mtdblock driver, APEX is the easiest way to write the boot loader to flash. If the default APEX startup script automatically boots, you'll have to make sure to press a ^C to interrupt the boot process.
APEX provides a handy alias variable for the region of memory where it resides, $apex. So, writing it to flash always looks the same. It will reprint the copy command (not shown here) with the substitution for $apex.
apex> erase nor:0 apex> copy $apex nor:0
Next time the SLUG is booted, it will run APEX and boot into Linux.
Fat Slugs (More than 32MiB of SDRAM)
SDRAM memory configuration is setup using the standard config targets. You'll need to know the organization of the memory chips. The standard layout has one bank of memory that with 32MiB of SDRAM. Four chip 64MiB Fat Slugs have two banks with 32MiB of SDRAM in each bank. Two chip 64MiB Fat Slugs have one bank with 64MiB of SDRAM in each bank. 32MiB is 0x02000000. 64MiB is 0x04000000.
Using the FIS Partition Driver
When using APEX as a second stage loader, you may want to maintain NOR flash partitions using the FIS directory which is used by Redboot. APEX includes an FIS driver that can parse the FIS directory and use FIS partitions as the sources for copying data from flash to SDRAM.
The source region of the FIS driver must be set to point to the FIS directory. On the NSLU2, this region is nor:0x7e0000+4k. When the driver is built into APEX and this region is set, the version command will list the partitions.
apex> version
APEX Boot Loader 1.3.30 -- Copyright (c) 2004,2005,2006 Marc Singer
APEX comes with ABSOLUTELY NO WARRANTY. It is free software and you
are welcome to redistribute it under certain circumstances.
For details, refer to the file COPYING in the program source.
apex => mem:0x00200000+0x9240 (37440 bytes)
env => nor:0x7fc000+15k (empty)
*** No SDRAM init when APEX executed from SDRAM.
stack: 2544 used (4096)
memory: 0x0 0x02000000 (32 MiB)
nor: 8MiB total 32B write buffer
region 0: 64 blocks of 131072 (0x20000) bytes
fis:
0x50000000+0x00040000 RedBoot
0x50040000+0x00020000 SysConf
0x50060000+0x00100000 Kernel
0x50160000+0x00020000 Ramdisk
0x50180000+0x00660000 Flashdisk
0x507e0000+0x00020000 FIS directory
cpu: id 0x690541f1 ctrl 0x1aff cpsr 0x200000d3
Use the command 'help help' to get started.
The FIS driver looks for the FIS partition name as the partition of the path. It is case insensitive.
apex> dump fis://sysconf 50040000: 00 00 04 59 5b 6e 65 74 77 6f 72 6b 5d 0a 76 65 ...Y[net work].ve 50040010: 72 73 69 6f 6e 3d 32 2e 33 2e 32 34 0a 74 65 6c rsion=2. 3.24.tel 50040020: 6e 65 74 5f 65 6e 61 62 6c 65 3d 6e 6f 0a 68 77 net_enab le=no.hw 50040030: 5f 69 64 3d 34 66 30 30 63 30 30 30 30 30 30 30 _id=4f00 c0000000 50040040: 2d 32 30 30 33 0a 64 6f 6d 61 69 6e 5f 6e 61 6d -2003.do main_nam 50040050: 65 3d 0a 77 5f 64 5f 6e 61 6d 65 3d 77 6f 72 6b e=.w_d_n ame=work 50040060: 67 72 6f 75 70 0a 7a 6f 6e 65 5f 6e 61 6d 65 3d group.zo ne_name= 50040070: 2a 0a 6d 73 6e 5f 65 6e 61 62 6c 65 3d 79 65 73 *.msn_en able=yes
The region can also include an offset and a length.
apex> dump fis://sysconf@16+16 50040010: 72 73 69 6f 6e 3d 32 2e 33 2e 32 34 0a 74 65 6c rsion=2. 3.24.tel
You'll need to use quoting to examine the directory because of the space in the name.
apex> dump "fis://fis directory+16" 507e0000: 52 65 64 42 6f 6f 74 00 00 00 00 00 00 00 00 00 RedBoot. ........
Copying the kernel to SDRAM in preparation for booting is best done without a length qualifier. When no length is specified, the region defaults to the size of the partition. This will guarantee that changing the partition sizes will not affect proper boot-up. In this example, we also skip the first 16 bytes of the SERCOMM header.
apex> copy fis://kernel@16 $bootaddr # copy fis://kernel 0x00008000 1048576 bytes transferred
Kernel Command Lines
Much of the kernel setup can be controlled with the command line. Here are some examples
Serial Console
console=ttyAM0,115200
This is the basic console mode. It uses the device /dev/ttyAM0 at 115.2k baud as /dev/console.
Serial and FrameBuffer Console
console=tty0 console=ttyAM0,115200
This form will show the console on both the framebuffer device and the serial device. The last device is used as /dev/console.
The Environment and Aliases
APEX has two kinds of runtime variables. Environment variables are saved to non-volatile storage, when available, and are restored when APEX executes. Aliases are non-persistent and are used by APEX to store information that is either easy for APEX to discover, is inherently transient, or just offered as a convenience to the user.
The current environment is listed with the printenv command.
apex> printenv cmdline *= console=ttyAM0 root=/dev/hda2 3 startup *= copy nor:256k+1536k 0x20008000; bootaddr *= 0x20008000
The *= indicates environment variables that are set to the default values.
The current aliases are listed with the alias command.
apex> alias apex mem:0x20200000+0xdb10 env nor:128k+64k hostip 192.168.8.203 serverip 192.168.8.1 gatewayip 192.168.8.1
There are some important differences between the environment and aliases. Environment variables are restricted to a list that is defined when APEX is built. New environment variables may not be declared. New aliases, on the other hand, are unrestricted. There is no such thing as a default alias value. When an aliases undefined, it is removed. When an environment variable is undefined, it reverts to the default value.
Variables may be inserted into a command line when prefixed with a dollar-sign '$'. If a variable name exists both among the aliases and in the environment, the alias will take priority.
apex> checksum $apex # checksum mem:0x20200000+0xdb10 crc32 0x35c88aa9 (902335145) over 56080 (0xdb10) bytes
APEX will redisplay commands that use variable expansion so that the user knows what is being executed.
Ethernet Support
As of version 1.3, APEX has a small IP stack capable of a few basic protocols. There are MAC drivers for the LH79524 and the SMC91x which covers all of the Logic PD boards for the Sharp LH processors. The stack is incomplete in that it doesn't implemented TCP. It does support, ARP, RARP, ICMP echo and response, and TFTP read.
Reading a Linux kernel from a tftp server might look like this.
apex> ipconfig rarp hostip 192.168.8.203 serverip 192.168.8.1 gatewayip 192.168.8.1 apex> copy tftp://$serverip/zImage $bootaddr # copy tftp://192.168.8.1/zImage 0x20008000 1255360 bytes transferred
These commands can be interrupted by typing ^C on the console.
--Elf 14:38, 6 April 2006 (PDT)


