When working on low level kernel code, the indication that something went wrong is often noticed as a kernel oops, or even a totally silent system. This usually implies a modify-recompile-reboot cycle which can become very very annoying if the reboot step implies popping out an SD card from the board, inserting it into the work PC, mounting it, copying the newly compiled kernel over, unmounting, moving the SD card back to the board, to finally hit the reset button.
If you are an old fashioned kernel developer like me and live by the simplest development environment (bash, vi, gcc) and your most trusted debugging tool is printk(), then having the ability to quickly boot a new kernel after moving printk traces around in order to pinpoint a crash location is vital. But even for validation purposes on a remote board, not needing physical intervention is really nice.
So, by popular demand, here's how I accomplished this on VirtualExpress with a TC2 tile. This probably applies to other VirtualExpress configurations too, but TC2 is the only one I tested.
Obtaining U-Boot ----------------
I don't have a particular affection for any bootloaders. They tend to ask for more and more attention and visibility while their raison d'être is actually to get out of the way and disappear as fast as possible.
While U-Boot has many things that certainly gets on my nerves, it has a good point for itself which is its networking support. And here is the key: let's fetch everything we need to boot the board over the network, script it, so not to have to deal with the bootloader (or bootloaders in this case) anymore.
First, let's get a copy of the U-Boot source tree. I used the Linaro version as it includes Versatile Express support.
$ git clone git://git.linaro.org/boot/u-boot-linaro-stable.git $ cd u-boot-linaro-stable/
Now... to get rid of U-Boot's most obnoxious feature (my opinion), the following patch should be applied:
diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h index 88a2c95..3328443 100644 --- a/include/configs/vexpress_common.h +++ b/include/configs/vexpress_common.h @@ -177,6 +177,8 @@ #define CONFIG_CMD_SAVEENV #define CONFIG_CMD_RUN #define CONFIG_CMD_BOOTD +#define CONFIG_CMD_BOOTZ +#define CONFIG_SUPPORT_RAW_INITRD #define CONFIG_CMD_ECHO
#define CONFIG_CMD_FAT
That basically enables U-Boot to boot a plain ARM Linux zImage file without going through the mkimage step (the bootz command), and load a plain ramdisk image without having to run mkimage on it. This mkimage step is just extra fuss I can dispense with when working on and booting kernels frequently.
Now let's build it. There is no TC2 (ca15 or ca7) config, however the ca5 one appears to be close enough for our needs:
$ make vexpress_ca5x2
You should end up with a u-boot.bin to be used later.
ARM Versatile Express Boot Monitor ----------------------------------
This is the native boot loader on the Virtual Express. In fact there are many instances of different loaders even on different processors making the whole system rather weird but flexible. It lacks the ability to load files from the network though. But that's what a second stage bootloader such as U-Boot is for.
Good information on setting up a Virtual Express already exists. While the instructions listed therein may or may not all apply to our case, I still recommend to read the following pages to get familiar with this beast:
https://wiki.linaro.org/PawelMoll/BootingVEMadeEasy
The script to generate a boot script to generate an ATAGS block is a rather nice hack. But I want runtime DTB support and I prefer booting over the network, especially when playing with ramdisk images which is otherwise long to get reflashed. Still this page provides a nice introduction to Virtual Express setup and gives good insights on the micro switch usage and the VE boot monitor structure.
https://wiki.linaro.org/ARM/VersatileExpressSetup
This page shows how to install U-Boot on a Virtual Express and that's what we want here. you should follow the instructions listed for the CA15x2 CoreTile, except that the U-Boot binary to use is the one we just compiled above. Also, for TC2 the images.txt file is located in SITE1/HBI0249A/.
In short, once the internal MicroSD card is mounted over USb, the u-boot.bin file we compiled should be copied to SOFTWARE/u-boot.bin. Then the file SITE1/HBI0249A/images.txt should be updated to contain something similar to this:
NOR4UPDATE: AUTO NOR4ADDRESS: 0f800000 NOR4FILE: \SOFTWARE\u-boot.bin NOR4LOAD: 0x80800000 NOR4ENTRY: 0x80800000
We also need a boot script to start U-Boot automatically:
NOR5UPDATE: AUTO NOR5NAME: BOOTSCRIPT NOR5ADDRESS: 00000000 NOR5FILE: \SOFTWARE\boot.txt
Here the "BOOTSCRIPT" name is important otherwise the script won't be found and executed.
The number after "NOR" may differ, depending on the other images your images.txt may already contain. Don't forget to update the TOTALIMAGES value at the top to reflect the number of image definitions you have, especially if you added new ones.
Finally, the content of SOFTWARE/boot.txt only needs to contain one line:
flash run u-boot
That's it! unmounting the USB disk, setting SW[0] down and booting the main board (entering the "reboot" command on the serial console) should bring you to an U-Boot prompt.
The U-Boot configuration ------------------------
Once at the U-Boot prompt, it is necessary to set a couple environment variables:
VExpress# setenv bootcmd run loadbootscript; source $fileaddr VExpress# setenv loadbootscript dhcp 0x84000000 192.168.2.2:tc2_boot.scr VExpress# saveenv
In the loadbootscript definition, I used an explicit IP address to prefix the file name. This is because my DHCP server is not the same machine as my TFTP server used to provide the location for the loaded files. If your DHCP configuration already provides that information then it is not necessary to provide such prefix. If you prefer using a fixed IP address for the board, you may simply set the ipaddr, netmask and gatewayip environment variables accordingly, and replace dhcp with tftp in the definition of loadbootscript. And don't forget to saveenv again.
That's it! Once the script is loaded over the network, we don't need to deal with U-Boot's configuration anymore.
The U-Boot boot script ----------------------
Now you need a TFTP server (normally tftpd) on your PC or laptop. In its content directory, there should be a file called tc2_boot.scr. Unfortunately, the U-Boot obnoxiousness is striking back at us since this must be mkimage wrapped. Let's start with the source, say tc2_boot.txt which should contain the following U-Boot commands:
# set the TFTP server address (the dhcp command clobbers it) setenv serverip 192.168.2.2 # load a DTB tftp 0x82000000 vexpress-v2p-iks-tc2.dtb # tell U-Boot about it fdt addr $fileaddr # load a ramdisk image tftp 0x88000000 initrd.gz # remember its location and size for later setenv rd_addr $fileaddr setenv rd_size $filesize # load the kernel tftp 0x81000000 zImage # set our kernel parameters setenv bootargs console=ttyAMA0,38400 earlyprintk debug root=/dev/sda1 rootwait # boot the kernel bootz $fileaddr $rd_addr:$rd_size $fdtaddr
The above is what I use and can be adapted to your needs. Again, maybe you don't need to override serverip. Maybe you wish to use a NFS root. Etc. That's the beauty of it: it is just a .txt file on your PC that you can modify at will without having to flash it anywhere. Temporary changes to the DTB with the fdt commands are also possible without having to modify and recompile the corresponding .dts, etc.
However we need to ubootize it into tc2_boot.scr before it is usable:
$ mkimage -A ARM -T script -C none -d tc2_boot.txt tc2_boot.scr
(The one who tells me how to avoid this step gets a cookie.)
Suffice to copy the desired kernel zImage and initrd files there too for the boot to proceed. It might even be possible to use a symbolic link towards the zImage produced by the compilation of the kernel directly so to avoid that copy, but I didn't push my own laziness that far.
Let's boot! -----------
Now you may use the "reboot" command at the "Cmd>" prompt provided by the microcontroller to power up the board. When the board is booted, this prompt is moved from UART 0 to UART 1 while the kernel console output is going to UART 0, so it is possible to shutdown or reboot the board over UART 1 entirely unattended and remotely when both serial ports are connected to a computer.
Enjoy !
Nicolas
Nice article!
On 24 October 2012 08:26, Nicolas Pitre nicolas.pitre@linaro.org wrote:
When working on low level kernel code, the indication that something went wrong is often noticed as a kernel oops, or even a totally silent system. This usually implies a modify-recompile-reboot cycle which can become very very annoying if the reboot step implies popping out an SD card from the board, inserting it into the work PC, mounting it, copying the newly compiled kernel over, unmounting, moving the SD card back to the board, to finally hit the reset button.
You can also connect vexpress board with your PC with a USB cable, and the uSD card will be shown on your PC as data storage, as soon as bootloader or bootmonitor is on. You can simply copy files from your linux pc to this storage and reboot :)
-- viresh
On Wed, 24 Oct 2012, Viresh Kumar wrote:
Nice article!
Thanks.
On 24 October 2012 08:26, Nicolas Pitre nicolas.pitre@linaro.org wrote:
When working on low level kernel code, the indication that something went wrong is often noticed as a kernel oops, or even a totally silent system. This usually implies a modify-recompile-reboot cycle which can become very very annoying if the reboot step implies popping out an SD card from the board, inserting it into the work PC, mounting it, copying the newly compiled kernel over, unmounting, moving the SD card back to the board, to finally hit the reset button.
You can also connect vexpress board with your PC with a USB cable, and the uSD card will be shown on your PC as data storage, as soon as bootloader or bootmonitor is on. You can simply copy files from your linux pc to this storage and reboot :)
I know. But that implies mounting and unmounting the device (unless you have an auto-mounter set up which I haven't). Also, this makes the boot very long when large files have to be reflashed, especially ramdisk images. And this is not very flexible when requiring runtime changes to the DTB.
And for me, the deal breaker is the fact that all the other boards on my desk don't have such fancy USB storage connection and they are set up for booting over the network already.
Nicolas
On 24 October 2012 21:00, Nicolas Pitre nicolas.pitre@linaro.org wrote:
On Wed, 24 Oct 2012, Viresh Kumar wrote:
You can also connect vexpress board with your PC with a USB cable, and the uSD card will be shown on your PC as data storage, as soon as bootloader or bootmonitor is on. You can simply copy files from your linux pc to this storage and reboot :)
I know. But that implies mounting and unmounting the device (unless you have an auto-mounter set up which I haven't). Also, this makes the boot very long when large files have to be reflashed, especially ramdisk images. And this is not very flexible when requiring runtime changes to the DTB.
And for me, the deal breaker is the fact that all the other boards on my desk don't have such fancy USB storage connection and they are set up for booting over the network already.
Got it. Rest of the part of this mail is to make my life simple :)
@Pawell and others: Is there a way in vexpress bootmon to load images directly from uSD card instead of flash? I know we can stop flashing stuff to flash from uSD card by changing config.txt, but with that i need commands to load stuff from uSD card directly.
This will save a lot of time during development.
-- viresh
On Thu, 2012-10-25 at 11:41 +0100, Viresh Kumar wrote:
@Pawell and others: Is there a way in vexpress bootmon to load images
^^ ;-)
directly from uSD card instead of flash?
No, sorry. The uSD card is tied to the microcontroller and there is no "wide enough pipe" between it and the main CPU to make it feasible. I have some ideas about using the PSRAM we have there as a fast "buffer" for the copy-and-boot cycle, but I'll need some (mythical ;-) spare time to try it out.
Paweł
On Tue, 2012-10-23 at 22:56 -0400, Nicolas Pitre wrote:
I still recommend to read the following pages to get familiar with this beast:
<snip>
https://wiki.linaro.org/ARM/VersatileExpressSetup
This page shows how to install U-Boot on a Virtual Express and that's what we want here.
We've been asked to 'garden' the wiki for vexpress related things, and I suspect pages like these are due for the chop in a matter of hours. So I recommend people grab themselves a copy quick.
The official release pages will include _some_ similar (and more up to date information), however you won't find any mention of any bootloader other than UEFI. And, at least for now, no mention of how to boot a kernel other than by removing the SD card and copying it over.
Personally (and unofficially), I find that the simplest and most reliable way to use vexpress is to flash the kernel/dtb/initrd images into NOR flash and use the bootmonitor supplied with the board to load these.
Putting the images into NOR flash involves modifying the contents of the on-board micro-SD card first, which can be done by mounting it over USB from your PC, and so is easily scripted. And, if you have the bootmonitor set to automatically run a bootscript to load the kernel (DIP switch nearest USB cable down), then you can also use the same method to modify this bootscript to change things like kernel command-line args.
As I've started now, I may as well attach my images.txt file for TC2 and my bootscr.txt file from the internal SD card, so you get the idea.
On 24 October 2012 09:29, Jon Medhurst (Tixy) tixy@linaro.org wrote:
On Tue, 2012-10-23 at 22:56 -0400, Nicolas Pitre wrote:
I still recommend to read the following pages to get familiar with this beast:
<snip> > https://wiki.linaro.org/ARM/VersatileExpressSetup > > This page shows how to install U-Boot on a Virtual Express and that's > what we want here.
We've been asked to 'garden' the wiki for vexpress related things, and I suspect pages like these are due for the chop in a matter of hours. So I recommend people grab themselves a copy quick.
Luckily, Anmar and me agreed that we would leave the old pages there and put a huge ugly disclaimer on the top with a link redirecting to the updated content in most cases.
The official release pages will include _some_ similar (and more up to date information), however you won't find any mention of any bootloader other than UEFI. And, at least for now, no mention of how to boot a kernel other than by removing the SD card and copying it over.
Personally (and unofficially), I find that the simplest and most reliable way to use vexpress is to flash the kernel/dtb/initrd images into NOR flash and use the bootmonitor supplied with the board to load these.
No you don't. The party line is: we all use UEFI. ;-)
Putting the images into NOR flash involves modifying the contents of the on-board micro-SD card first, which can be done by mounting it over USB from your PC, and so is easily scripted. And, if you have the bootmonitor set to automatically run a bootscript to load the kernel (DIP switch nearest USB cable down), then you can also use the same method to modify this bootscript to change things like kernel command-line args.
As I've started now, I may as well attach my images.txt file for TC2 and my bootscr.txt file from the internal SD card, so you get the idea.
-- Tixy
linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
On Wed, 24 Oct 2012, Ryan Harkin wrote:
On 24 October 2012 09:29, Jon Medhurst (Tixy) tixy@linaro.org wrote:
Personally (and unofficially), I find that the simplest and most reliable way to use vexpress is to flash the kernel/dtb/initrd images into NOR flash and use the bootmonitor supplied with the board to load these.
No you don't. The party line is: we all use UEFI. ;-)
If it does TFTP and can be scripted then I don't mind.
Otherwise, if I'm going to still use U-Boot in the end then UEFI will be just an extra roundtrip into another to-be-despised bootloader in lack of visibility and attention since it'll do nothing but increase my kernel boot latency.
Did I mention already that I hate bootloaders?
Nicolas
On Wed, 24 Oct 2012, Jon Medhurst (Tixy) wrote:
The official release pages will include _some_ similar (and more up to date information), however you won't find any mention of any bootloader other than UEFI.
Another bootloader to hate. Joy!
And, at least for now, no mention of how to boot a kernel other than by removing the SD card and copying it over.
Maybe good for production, but abominable for development. I'm not buying.
Personally (and unofficially), I find that the simplest and most reliable way to use vexpress is to flash the kernel/dtb/initrd images into NOR flash and use the bootmonitor supplied with the board to load these.
Yes, did that before. The reflashing is still relatively long, enough to annoy me.
Nicolas
On Tue, 2012-10-23 at 22:56 -0400, Nicolas Pitre wrote:
The script to generate a boot script to generate an ATAGS block is a rather nice hack.
These days are, fortunately, long gone :-) New-ish Boot Monitors (5.x.x versions in particular) speak initrd, ATAG _and_ DTB "natively", so one can boot the board with
fl linux initrd busybox fl linux fdt ca9 fl linux boot zimage console=ttyAMA0,38400
It still can't do TFTP though, so it's just a formal remark - I'm not trying to "convert" anyone.
Cheers!
Paweł
On Wed, 24 Oct 2012, Pawel Moll wrote:
On Tue, 2012-10-23 at 22:56 -0400, Nicolas Pitre wrote:
The script to generate a boot script to generate an ATAGS block is a rather nice hack.
These days are, fortunately, long gone :-)
I deduced as much, given your example boot log reported a RTC time in 2004. Still, that was a nice piece of art IMHO.
New-ish Boot Monitors (5.x.x versions in particular) speak initrd, ATAG _and_ DTB "natively", so one can boot the board with
fl linux initrd busybox fl linux fdt ca9 fl linux boot zimage console=ttyAMA0,38400
It still can't do TFTP though, so it's just a formal remark - I'm not trying to "convert" anyone.
I think it is not wrong to have second stage bootloaders. No need to duplicate functionality if an existing piece of software does it well already.
Eventually this is down to personal work habits and preferences. Having the choice is good.
Nicolas