Embedded Linux Wiki Highlights
- The latest github version of buildroot runs with this config (11 2022): here
- Older buildroot config file: here for buildroot 2015-08.1 - later versions fail on uclibc
- Yocto build instructions can be found here
- Beaglebone Black kernel config improved here: dotconfig-beagleboneblack.txt
- Hello World ARM cross compilation using the Ubuntu packaged cross compiler: here
- Yocto course lab files
- Hello World kernel module including time exercise here
- nInvaders solution for lab 3
- How to boot from the provided sd card
Insert the micro-sd card into the board and attach the board with the usb cable to the laptop.
The board will boot as soon as it gets power, so it will already boot the included read-only ramdisk from internal SPI flash. We are going to change the preinstalled u-boot boot loader to automagically boot from SD card. For that we open a picocom connection to our board in a terminal window:
sudo picocom -b 115200 /dev/ttyUSB0
Provide your password.
Once inside picocom, press enter to see if we get some output back from the board. If that is the case, press the blue botton next to the dip switches on the board and immediately press any key on the keyboard to stop autoboot (you have only 3 seconds). If you where not in time, reset the board by pressing the blue botton again.
You should now see a u-boot prompt like this: zynq-uboot>
Copy/paste the following line:
setenv bootcmd "run superboot"
And press enter.
ZedBoard specific memory values, change the load addresses to match your board.
Also copy/paste the following line (in one line):
setenv superboot "echo Performing Superboot && mmcinfo && ext2load mmc 0 0x3000000 uImage && ext2load mmc 0 0x2A000000 zynq-zed.dtb && setenv bootargs root=/dev/mmcblk0p1 consoleblank=0 rw rootwait earlyprintk console=ttyPS0,115200 && bootm 0x3000000 - 0x2A00000"
And now reset your board with:
You are booting from the SD card if you are now welcomed with the following:
Welcome to SuperZynq
You can provide the username 'root' to login without a password (yet).
With the df -h command you can check how much disk space is available.
Notice that you are not using a lot of space yet.
- To avoid I/O errors; does this kernel argument work?
Maybe init_emmc_clock=125000000 works too.
- Increase memory to 1Gb: add in device tree - Zedboard specific:
reg= <0x0 0x40000000>;
- How to change language from Chinese to English in Mini2440:
- USB firmware transfer tool: s3c2410_boot_usb - was compiled following: http://www.friendlyarm.net/forum/topic/3386
- the original firmware: factory_setup.zip
- our uboot image: u-boot-256M.bin
- our hacked fullscreen fancybrowser (QT webkit): fancybrowser.tgz
- a working rootfilesystem with webkit and such: rootfs-web.jffs2
- A working kernel: uImage
- Factory kernel:uImage_from_factory_zImage
- Buildroot config: buildroot-config-08-2013. Download this file and put it in the extracted buildroot directory. Rename the file to .config and run make
- Change leds directly through /sys/class/gpio/gpioN/value which is N on the mini2440?
- Put uboot on the mini2440
By first downloading the s3c2410_boot_usb, and the u-boot-256M.bin files.
Second, switch to NOR and reboot with minicom running.
In minicom, type 'v' to 'download vivi', and while the usb device-cable is connected, run in another terminal ./s3c2410_boot_usb u-boot-256M.bin
Possibly chmod 755 s3c2410_boot_usb first.
Now we have uboot on the NAND flash on our bord, we can test that by booting into NAND. However our work isn't done yet. The uboot-env partition isn't working and we don't have a bad block table on the NAND flash yet.
To put that on the NAND, we will have to erase uboot however. No, problem, after erasing it, we will put uboot back:
dynenv set u-boot_env
Now we need to put u-boot back. So boot in NOR, in supervivi 'send vivi', ./s3c2410_boot_usb u-boot-256M.bin and boot in NAND.
Also enable the u-boot_env parition back:
dynenv set u-boot_env
Now we test if uboot environment works in the u-boot prompt:
setenv foo bar
If everything is ok, the foo=bar will be visible.
- Booting kernel directly from NAND
nand erase kernel
ext2load mmc 0:1 0x32000000 uImage
nand write 0x32000000 kernel
and then use nboot.e kernel
to boot the kernel
We can use the 'kernel' name because the partition is named as such in the partitioning (mtdparts).
- Booting from the network using TFTP and NFS
Following the boot sequence, the following needs to be accomplished:
Uboot needs to be configured to get an IP adres (dhcp) and get the linux kernel image over TFTP. For this we need a tftp server on our workstation.
Then we also need to set in uboot the boot arguments for the kernel to use a NFS server as root filesystem. For that we need an nfs server on our workstation.
The kernel also needs to be able to boot over nfs, so we need to change or verify the kernel configuration.
So here are the commands (out of my head - might need some tweaking):
On the workstation to install tftpd and nfs server:
apt-get install nfs-kernel-server tftpd-hpa tftp
The NFS server on Ubuntu 20.04 uses a newer, more secure version by default, which will not work to use 'NFS ROOT' from the Linux kernel. This is why we need to allow older versions by adding this line to /etc/default/nfs-kernel-server:
RPCNFSDOPTS="--nfs-version 2,3,4 --debug"
And restart the service:
sudo systemctl restart nfs-kernel-server.service
We need to put the zImage file in the /srv/tftp directory to be able to be transferred. It can be practical to test if the tftp server works by using a tftp client on our workstation and try to get zImage file locally to the /tmp directory:
cp /usr/src/buildroot/output/images/zImage /srv/tftp
If this works, we know the tftp server is ready to serve our kernel to the board.
So let's put something on the NFS server first.
cp /usr/src/buildroot/output/images/rootfs.tar /export/
tar xvf rootfs.tar
Then we can export (share over the network) the directory with nfs in the /etc/exports file, by adding this line to it:
Then we restart the NFS server and the rpcbind deamon:
Be aware that we serve it to any IP on the network (security alert).
We could test out on a fellow student his or her laptop if the exported nfs is visible and if we can mount it.
Or we could try it right away if we feel lucky :)
How to try it out?
In uboot we do - assuming your laptop IP is 192.168.1.12 and for the board: 192.168.1.101 (replace as needed):
setenv bootargs root=/dev/nfs nfsroot=192.168.1.12:/export/,vers=4 ip=dhcp console=ttyO0,115200
setenv tftpip 192.168.1.12
setenv serverip 192.168.1.12
setenv ipaddr 192.168.1.101
Where you provide the IP adres of your laptop instead of .12
And get the zImage over tftp
tftp 0x82000000 zImage
Now you should see lots of #-signs to indicate the zImage file transfer. They might stutter over the wifi connection to your laptop or get more errors if you have a duplicate IP address or MAC address.
And the device tree in a simular manner:
tftp 0x88000000 am335x-boneblack.dtb
bootz 0x82000000 - 0x88000000
or if you have a uImage instead use bootm
On most boards you can do:
But on the BeagleBone Black, we will have to put the correct boot command into the uEnv.txt
If we don't get a kernel panic we have probably booted over nfs. Verify by doing df to check how much diskspace we have.
Do we have a read-write filesystem over NFS? If not, how can we fix that the most easily? Maybe compare with previous boot arguments.
Verify if NFS root capabilities are part of the linux kernel:
This is not the general buildroot menuconfig, but the menuconfig specific for the linux kernel. If we download the linux kernel outside of buildroot and run in the source directory 'make menuconfig ARCH=arm', we would get the same screen.
Inside this menuconfig we are going to look for NFS root capability:
Filesystems -- Network Filesystems -- Root Filesystem over NFS
On the git version this is already enabled. If it would not be visible, it might be necessary to enable 'kernel IP configuration first. This is located on a completely different location:
Networking Support -- Networking Options -- IP: Kernel level autoconfiguration
Best to enable DHCP and BOOTP there (already the case on the git version of august 2013).
otherwise, after making changes, run make again and use this newer kernel.
- Change the MAC address in uboot
setenv ethaddr 01:02:03:04:05:06
Please ensure you have a random or different mac address on your board than the other people on the network, otherwise switches get confused and you don't have a reliable network connection.
Most boards have unique MAC addresses as they should, but there are cheap chinese boards without.
By default the screen brightness is turned off, turn it on with:
echo 255 > /sys/class/leds/backlight/brightness
Look at this patch: https://patchwork.kernel.org/patch/1169951/
Or download 3.6.2 with ts capabilities here
Also add this kernel argument in uboot: mini2440=3tb
And for the touchscreen interaction to work, we need to put some environmental variables too:
ln -s /dev/input/event0 /dev/ts
I like to use the fancybrowser app to connect to a web server running locally to create an interface written in php:
/usr/share/qt/examples/webkit/fancybrowser/fancybrowser -qws -geometry 320x240+0+0 -decoration Default http://localhost/linux-php.php
For this, I also run a patched version of fancybrowser without window dressing (done by stripping some code and creating a decoration with nothing:
- Update uboot env from within Linux
First we need to add the Uboot tools fw_printenv/fw_setenv in buildroot.
Then we need a configuration file in Linux which explains how the internal NAND flash is partitioned.
This file is called: /etc/fw_env.config
Content should be in this format:
/dev/mtd1 0x0 0x20000 0x20000
If this is not correct, verify in uboot with dynpart what the offset of the partition is.