U-Boot

From Openmoko

Revision as of 00:50, 10 February 2007 by HaraldWelte (Talk | contribs)

Jump to: navigation, search

Contents

General

The GTA01 uses the u-boot bootloader.

More information on u-boot can be found at [1], [2] and [3].

However, the vanilla u-boot doesn't support many of the features that GTA01 needs, such as

  • Support for boot from NAND flahs using S3C2410 Steppingstone
  • Support for reading kernel/initrd from SD/Transflash
  • Support for S3C2410 NAND flash
  • Support for downloading programs via S3C2410 USB Device Controller
  • Support to display bootup logo / status on S3C2410 Framebuffer

User:HaraldWelte is working on those issues, and in fact most of them have already been implemented.

Bootloader source code

The current bootloader patches can be found at https://svn.openmoko.org/trunk/src/target/u-boot/patches/.

Untar the sources, apply the patch. run "make gta01bv3_config" (or gta01bv2_config, or whatever hardware revision you have), run "make". You will get a resulting "u-boot.bin" image, which you can directly flash (either using existing bootloader or sjf2410-linux) into NAND.

Bootloader binary

The latest bootloader binary (for NAND) can be found at [4]. It should be written to the NAND flash address 0x00000000 (size 0x30000)

Bootloader development

QT2410

If you want to do bootloader development on the QT2410, it's easier to work with a bootloader image that can be downloaded via USB into RAM instead of flashing.

To do so, you need to edit the u-boot/include/configs/qt2410.h file, and change the "if 0" in Line 32 into a "if 1", then recompile with "make".

The resulting "u-boot.bin" is _NOT SUITABLE_ for NAND flash, but only for direct execution from within ram, e.g. by using the s3c2410_boot_usb program.

GTA01

Doing bootloader development on the GTA01 is a bit more tricky. first, we don't have any NOR flash. Second, there is no other way to boot _but_ from NAND. Therefore, we also don't have a USB downloader like the QT2410.

The main problem is: The S3C2410 Steppingstone unconditionally copies the first 4k of flash into its internal SRAM. That SRAM segment stays unconditionally mapped at physical address zero. How do we get around this

Using JTAG to boot from RAM

So how can we boot from RAM? We use JTAG / OpenOCD to

  • reset and halt the cpu at PC=0
> reset halt
target halted in ARM state due to debug request, current mode: Supervisor
cpsr: 0x400000d3 pc: 0x00000000
MMU: disabled, D-Cache: disabled, I-Cache: disabled
  • download a small piece of code for low-level SDRAM timing initialization (overwrite 4k SRAM of steppingstone)
> load_binary /space/misc/gta01/u-boot.git/foo.bin 0            
downloaded 332 byte in 0s 21899us
  • assert a break point at address 0x33f80000 (which indicates that the low-level code has finished)
> bp 0x33f80000 4 hw
breakpoint added at address 0x33f80000
  • run the code up to the break point
> resume
Target 0 resumed
> Target 0 halted
target halted in ARM state due to breakpoint, current mode: Supervisor
cpsr: 0x600000d3 pc: 0x33f80000
MMU: disabled, D-Cache: disabled, I-Cache: enabled
  • download the u-boot RAM image to 0x33f80000
> load_binary /space/misc/gta01/u-boot.git/u-boot.bin 0x33f80000
downloaded 135692 byte in 6s 567264us
  • resume processing
> resume
Target 0 resumed

At this point, the display backlight gets bright and we see the following familiar prompt on the serial console:

U-Boot 1.1.6 (Jan 13 2007 - 23:44:23)

DRAM:  128 MB
NAND:  64 MiB
*** Warning - bad CRC or NAND, using default environment

In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0 
GTA01Bv2 # 

Creating bootable images

u-boot needs bootable images (such as kernels, but also initrd and others) in form of a so-called uImage. In order to create a uImage from e.g. a vmlinux kernel image, you can proceed as follows:

objcopy -O binary -R .note -R .comment -S vmlinux linux.bin
gzip -9 linux.bin
u-boot/tools/mkimage -A arm -O linux -T kernel -C gzip -a 30008000 -e 30008000 -n "Kernel Image QT2410" -d linux.bin.gz uImage

Bootloader prompt

The bootloader prompt is available either on the serial console (via Debug Board), or as virtual USB Serial device (USB CDC_ACM). Whether the serial port or usb i used depends on the u-boot environment variables stdin, stdout and stderr.

Whether or not you use usbtty, the first couple of messages will always be displayed on the serial console.

The bootloader is currently configured to waid for three seconds. If a key press on the serial port is received within those three seconds, auto-boot is aborted.

U-Boot 1.1.4-ga2c95a72-dirty (Aug  6 2006 - 22:05:48)

DRAM:  64 MB
Flash: 512 kB
NAND:  64 MiB
In:    serial
Out:   serial
Err:   serial

cs8900a chipid 0x630e
Hit any key to stop autoboot:  0 
QT2410 #

Auto-boot

Auto-boot executes the command[s] specified in the bootcmd environment variable. The default configuration is:

GTA01Bv2 # printenv
bootcmd=nand read.e 0x32000000 kernel; bootm 0x32000000

This basically tells us that it will load the content of the NAND partition kernel to memory address 0x32000000 and then try to boot it.

Environment

u-boot is configured to manage a non-volatile environment that is stored in NAND flash. You can use the commands to read/alter/store the environment in the following example:

QT2410 # printenv
bootcmd=mmcinit; ext2load mmc 0 0x32000000 uImage; bootm 0x32000000
bootdelay=3
baudrate=115200
ipaddr=10.0.0.110
serverip=10.0.0.1
netmask=255.255.255.0
bootargs=root=/dev/mmcblk0p1 console=ttySAC0,115200 loglevel=8 rootdelay=10
stdin=serial
stdout=serial
stderr=serial

Environment size: 271/16380 bytes
QT2410 # setenv bootdelay 10
QT2410 # printenv bootdelay
bootdelay=10
QT2410 # saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
QT2410 # 

Note: When setting multiple commands, e.g. for bootcmd, you need to escape the ';', for instance

QT2410 # setenv bootcmd mmcinit\; ext2load mmc 0 0x32000000 uImage\; bootm 0x32000000

As of 2007-02-01, laforge says the correct bootargs are:

rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8

Note that this requires flashing the jffs2 root image into NAND.

MMC/SD

in order to initialize a MMC/SD card, you have to use the ``mmcinit command.

QT2410 # mmcinit
trying to detect SD Card...
MMC found. Card desciption is:
Manufacturer ID = 58d564
HW/FW Revision = 3 8
Product Name = 21DN!@X�
Serial Number = 445303
Month = 5
Year = 2000
READ_BL_LEN=15, C_SIZE_MULT=7, C_SIZE=3197
size = 4208984064

afterwards, you can read ext2 filesystems like:

QT2410 # ext2ls mmc 0
<DIR>       1024 .
<DIR>       1024 ..
<DIR>      12288 lost+found
         1544788 uImage

NAND

QT2410 # help nand
nand info                  - show available NAND devices
nand device [dev]     - show or set current device
nand read[.jffs2]     - addr off size
nand write[.jffs2]    - addr off size - read/write `size' bytes starting
    at offset `off' to/from memory address `addr'
nand erase [clean] [off size] - erase `size' bytes from
    offset `off' (entire device if not specified)
nand bad - show bad blocks
nand dump[.oob] off - dump page
nand scrub - really clean NAND erasing bad blocks (UNSAFE)
nand markbad off - mark bad block at offset (UNSAFE)
nand biterr off - make a bit error at offset (UNSAFE)

Loading Kernel from NAND

QT2410 # nand read 0x32000000 0x34000 0x200000

NAND read: device 0 offset 212992, size 2097152 ...  2097152 bytes read: OK
QT2410 # bootm 0x32000000
## Booting image at 32000000 ...
   Image Name:   Kernel Image QT2410
   Created:      2006-08-06  20:23:01 UTC
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    1546258 Bytes =  1.5 MB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
Starting kernel ...

Writing new bootloader to NAND

The following set of commands loads the file u-boot.bin from ext2/mmc and flashes it into the bootloader flash partition:

QT2410 # ext2load mmc 0 0x32000000 u-boot.bin
QT2410 # nand erase u-boot
QT2410 # nand write 0x32000000 u-boot

Writing kernel to NAND

The following set of commands loads the file uImage from ext2/mmc and flashes it into the kernel flash partition:

QT2410 # ext2load mmc 0 0x32000000 uImage
QT2410 # nand erase kernel
QT2410 # nand write.e 0x32000000 kernel

Writing rootfs to NAND

The following set of commands loads the file rootfs.jffs2 from ext2/mmc and flashes it into the rootfs flash partition:

QT2410 # ext2load mmc 0 0x32000000 rootfs.jffs2
QT2410 # nand erase 0x00634000 0x39cc000
QT2410 # nand write.e 0x32000000 0x00634000 real_size_of_rootfs_in_hex

Please note that this will only work with root file system sizes that are smaller than the amount of memory above 0x32000000, which in the case of 64MB SDRAM is something like 32MB.

TFTP on QT2410

The QT2410 cs8900a Ethernet can be used to download images via network.

First, you have to make sure that ipaddr, serverip, ethaddr' and netmaskk are set correctly in the environment:

QT2410 # printenv
ethaddr=00:01:02:03:04:05
netmask=255.255.255.0
ipaddr=192.168.100.100
serverip=192.168.100.1

TFTP kernel download

QT2410 # tftpboot 0x32000000
*** Warning: no boot file name; using 'C0A86464.img'
TFTP from server 192.168.100.1; our IP address is 192.168.100.100
Filename 'C0A86464.img'.
Load address: 0x32000000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##########################################
done
Bytes transferred = 1544788 (179254 hex)

you can then commence booting via

QT2410# bootm 0x32000000
Personal tools

General

The GTA01 uses the u-boot bootloader.

More information on u-boot can be found at [1], [2] and [3].

However, the vanilla u-boot doesn't support many of the features that GTA01 needs, such as

  • Support for boot from NAND flahs using S3C2410 Steppingstone
  • Support for reading kernel/initrd from SD/Transflash
  • Support for S3C2410 NAND flash
  • Support for downloading programs via S3C2410 USB Device Controller
  • Support to display bootup logo / status on S3C2410 Framebuffer

User:HaraldWelte is working on those issues, and in fact most of them have already been implemented.

Bootloader source code

The current bootloader patches can be found at https://svn.openmoko.org/trunk/src/target/u-boot/patches/.

Untar the sources, apply the patch. run "make gta01bv3_config" (or gta01bv2_config, or whatever hardware revision you have), run "make". You will get a resulting "u-boot.bin" image, which you can directly flash (either using existing bootloader or sjf2410-linux) into NAND.

Bootloader binary

The latest bootloader binary (for NAND) can be found at [4]. It should be written to the NAND flash address 0x00000000 (size 0x30000)

Bootloader development

QT2410

If you want to do bootloader development on the QT2410, it's easier to work with a bootloader image that can be downloaded via USB into RAM instead of flashing.

To do so, you need to edit the u-boot/include/configs/qt2410.h file, and change the "if 0" in Line 32 into a "if 1", then recompile with "make".

The resulting "u-boot.bin" is _NOT SUITABLE_ for NAND flash, but only for direct execution from within ram, e.g. by using the s3c2410_boot_usb program.

GTA01

Doing bootloader development on the GTA01 is a bit more tricky. first, we don't have any NOR flash. Second, there is no other way to boot _but_ from NAND. Therefore, we also don't have a USB downloader like the QT2410.

The main problem is: The S3C2410 Steppingstone unconditionally copies the first 4k of flash into its internal SRAM. That SRAM segment stays unconditionally mapped at physical address zero. How do we get around this

Using JTAG to boot from RAM

So how can we boot from RAM? We use JTAG / OpenOCD to

  • reset and halt the cpu at PC=0
> reset halt
target halted in ARM state due to debug request, current mode: Supervisor
cpsr: 0x400000d3 pc: 0x00000000
MMU: disabled, D-Cache: disabled, I-Cache: disabled
  • download a small piece of code for low-level SDRAM timing initialization (overwrite 4k SRAM of steppingstone)
> load_binary /space/misc/gta01/u-boot.git/foo.bin 0            
downloaded 332 byte in 0s 21899us
  • assert a break point at address 0x33f80000 (which indicates that the low-level code has finished)
> bp 0x33f80000 4 hw
breakpoint added at address 0x33f80000
  • run the code up to the break point
> resume
Target 0 resumed
> Target 0 halted
target halted in ARM state due to breakpoint, current mode: Supervisor
cpsr: 0x600000d3 pc: 0x33f80000
MMU: disabled, D-Cache: disabled, I-Cache: enabled
  • download the u-boot RAM image to 0x33f80000
> load_binary /space/misc/gta01/u-boot.git/u-boot.bin 0x33f80000
downloaded 135692 byte in 6s 567264us
  • resume processing
> resume
Target 0 resumed

At this point, the display backlight gets bright and we see the following familiar prompt on the serial console:

U-Boot 1.1.6 (Jan 13 2007 - 23:44:23)

DRAM:  128 MB
NAND:  64 MiB
*** Warning - bad CRC or NAND, using default environment

In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0 
GTA01Bv2 # 

Creating bootable images

u-boot needs bootable images (such as kernels, but also initrd and others) in form of a so-called uImage. In order to create a uImage from e.g. a vmlinux kernel image, you can proceed as follows:

objcopy -O binary -R .note -R .comment -S vmlinux linux.bin
gzip -9 linux.bin
u-boot/tools/mkimage -A arm -O linux -T kernel -C gzip -a 30008000 -e 30008000 -n "Kernel Image QT2410" -d linux.bin.gz uImage

Bootloader prompt

The bootloader prompt is available either on the serial console (via Debug Board), or as virtual USB Serial device (USB CDC_ACM). Whether the serial port or usb i used depends on the u-boot environment variables stdin, stdout and stderr.

Whether or not you use usbtty, the first couple of messages will always be displayed on the serial console.

The bootloader is currently configured to waid for three seconds. If a key press on the serial port is received within those three seconds, auto-boot is aborted.

U-Boot 1.1.4-ga2c95a72-dirty (Aug  6 2006 - 22:05:48)

DRAM:  64 MB
Flash: 512 kB
NAND:  64 MiB
In:    serial
Out:   serial
Err:   serial

cs8900a chipid 0x630e
Hit any key to stop autoboot:  0 
QT2410 #

Auto-boot

Auto-boot executes the command[s] specified in the bootcmd environment variable. The default configuration is:

GTA01Bv2 # printenv
bootcmd=nand read.e 0x32000000 kernel; bootm 0x32000000

This basically tells us that it will load the content of the NAND partition kernel to memory address 0x32000000 and then try to boot it.

Environment

u-boot is configured to manage a non-volatile environment that is stored in NAND flash. You can use the commands to read/alter/store the environment in the following example:

QT2410 # printenv
bootcmd=mmcinit; ext2load mmc 0 0x32000000 uImage; bootm 0x32000000
bootdelay=3
baudrate=115200
ipaddr=10.0.0.110
serverip=10.0.0.1
netmask=255.255.255.0
bootargs=root=/dev/mmcblk0p1 console=ttySAC0,115200 loglevel=8 rootdelay=10
stdin=serial
stdout=serial
stderr=serial

Environment size: 271/16380 bytes
QT2410 # setenv bootdelay 10
QT2410 # printenv bootdelay
bootdelay=10
QT2410 # saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
QT2410 # 

Note: When setting multiple commands, e.g. for bootcmd, you need to escape the ';', for instance

QT2410 # setenv bootcmd mmcinit\; ext2load mmc 0 0x32000000 uImage\; bootm 0x32000000

As of 2007-02-01, laforge says the correct bootargs are:

rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8

Note that this requires flashing the jffs2 root image into NAND.

MMC/SD

in order to initialize a MMC/SD card, you have to use the ``mmcinit command.

QT2410 # mmcinit
trying to detect SD Card...
MMC found. Card desciption is:
Manufacturer ID = 58d564
HW/FW Revision = 3 8
Product Name = 21DN!@X�
Serial Number = 445303
Month = 5
Year = 2000
READ_BL_LEN=15, C_SIZE_MULT=7, C_SIZE=3197
size = 4208984064

afterwards, you can read ext2 filesystems like:

QT2410 # ext2ls mmc 0
<DIR>       1024 .
<DIR>       1024 ..
<DIR>      12288 lost+found
         1544788 uImage

NAND

QT2410 # help nand
nand info                  - show available NAND devices
nand device [dev]     - show or set current device
nand read[.jffs2]     - addr off size
nand write[.jffs2]    - addr off size - read/write `size' bytes starting
    at offset `off' to/from memory address `addr'
nand erase [clean] [off size] - erase `size' bytes from
    offset `off' (entire device if not specified)
nand bad - show bad blocks
nand dump[.oob] off - dump page
nand scrub - really clean NAND erasing bad blocks (UNSAFE)
nand markbad off - mark bad block at offset (UNSAFE)
nand biterr off - make a bit error at offset (UNSAFE)

Loading Kernel from NAND

QT2410 # nand read 0x32000000 0x34000 0x200000

NAND read: device 0 offset 212992, size 2097152 ...  2097152 bytes read: OK
QT2410 # bootm 0x32000000
## Booting image at 32000000 ...
   Image Name:   Kernel Image QT2410
   Created:      2006-08-06  20:23:01 UTC
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    1546258 Bytes =  1.5 MB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
Starting kernel ...

Writing new bootloader to NAND

The following set of commands loads the file u-boot.bin from ext2/mmc and flashes it into the bootloader flash partition:

QT2410 # ext2load mmc 0 0x32000000 u-boot.bin
QT2410 # nand erase u-boot
QT2410 # nand write 0x32000000 u-boot

Writing kernel to NAND

The following set of commands loads the file uImage from ext2/mmc and flashes it into the kernel flash partition:

QT2410 # ext2load mmc 0 0x32000000 uImage
QT2410 # nand erase kernel
QT2410 # nand write.e 0x32000000 kernel

Writing rootfs to NAND

The following set of commands loads the file rootfs.jffs2 from ext2/mmc and flashes it into the rootfs flash partition:

QT2410 # ext2load mmc 0 0x32000000 rootfs.jffs2
QT2410 # nand erase 0x00634000 0x39cc000
QT2410 # nand write.e 0x32000000 0x00634000 real_size_of_rootfs_in_hex

Please note that this will only work with root file system sizes that are smaller than the amount of memory above 0x32000000, which in the case of 64MB SDRAM is something like 32MB.

TFTP on QT2410

The QT2410 cs8900a Ethernet can be used to download images via network.

First, you have to make sure that ipaddr, serverip, ethaddr' and netmaskk are set correctly in the environment:

QT2410 # printenv
ethaddr=00:01:02:03:04:05
netmask=255.255.255.0
ipaddr=192.168.100.100
serverip=192.168.100.1

TFTP kernel download

QT2410 # tftpboot 0x32000000
*** Warning: no boot file name; using 'C0A86464.img'
TFTP from server 192.168.100.1; our IP address is 192.168.100.100
Filename 'C0A86464.img'.
Load address: 0x32000000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##########################################
done
Bytes transferred = 1544788 (179254 hex)

you can then commence booting via

QT2410# bootm 0x32000000