U-boot
U-boot must be cross-compiled on an x86 Linux PC.
Essential packages
You have to install some essential packages to build our u-boot.
Enter the following command.
Some packages listed in the below might not be essential but it is worth to install since these are also used when you build a kernel.
- host
$ sudo apt install git lzop build-essential gcc bc libncurses5-dev libc6-i386 lib32stdc++6 zlib1g:i386
Toolchain
Click one of the site to download toolchain to build U-boot.
Once the download is done, extract the tarball to /opt/toolchains/.
- host
$ sudo mkdir -p /opt/toolchains $ sudo tar xvf gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt/toolchains/ $ sudo tar xvf xpack-riscv-none-embed-gcc-10.2.0-1.2-linux-x64.tar.gz -C /opt/toolchains/
In order to add the toolchain path to PATH, paste below lines to $HOME/.bashrc.
- host
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- export PATH=$TOPDIR/opt/toolchains/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/toolchains/xpack-riscv-none-embed-gcc-10.2.0-1.2/bin:$PATH
You can apply the change if you login again or import to apply this change, login again or evaluate $HOME/.bashrc with source command.
- host
$ source ~/.bashrc
You can check if the toolchain installed above works properly while checking the version of toolchain. If you can find gcc version 7.4.1 20181213 [linaro-7.4-2019.02 revision 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4] at the end of the line, the toolchain is well installed.
- host
$ aarch64-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=aarch64-linux-gnu-gcc COLLECT_LTO_WRAPPER=/opt/toolchains/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/../libexec/gcc/aarch64-linux-gnu/7.4.1/lto-wrapper Target: aarch64-linux-gnu Configured with: '/home/tcwg-buildslave/workspace/tcwg-make-release_1/snapshots/gcc.git~linaro-7.4-2019.02/configure' SHELL=/bin/bash --with-mpc=/home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/destdir/x86_64-unknown-linux-gnu --with-mpfr=/home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gmp=/home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gnu-as --with-gnu-ld --disable-libmudflap --enable-lto --enable-shared --without-included-gettext --enable-nls --with-system-zlib --disable-sjlj-exceptions --enable-gnu-unique-object --enable-linker-build-id --disable-libstdcxx-pch --enable-c99 --enable-clocale=gnu --enable-libstdcxx-debug --enable-long-long --with-cloog=no --with-ppl=no --with-isl=no --disable-multilib --enable-fix-cortex-a53-835769 --enable-fix-cortex-a53-843419 --with-arch=armv8-a --enable-threads=posix --enable-multiarch --enable-libstdcxx-time=yes --enable-gnu-indirect-function --with-build-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/sysroots/aarch64-linux-gnu --with-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/destdir/x86_64-unknown-linux-gnu/aarch64-linux-gnu/libc --enable-checking=release --disable-bootstrap --enable-languages=c,c++,fortran,lto --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=aarch64-linux-gnu --prefix=/home/tcwg-buildslave/workspace/tcwg-make-release_1/_build/builds/destdir/x86_64-unknown-linux-gnu Thread model: posix gcc version 7.4.1 20181213 [linaro-7.4-2019.02 revision 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4] (Linaro GCC 7.4-2019.02)
- host
$ riscv-none-embed-gcc -v Using built-in specs. COLLECT_GCC=/opt/toolchains/xpack-riscv-none-embed-gcc-10.2.0-1.2/bin/riscv-none-embed-gcc COLLECT_LTO_WRAPPER=/opt/toolchains/xpack-riscv-none-embed-gcc-10.2.0-1.2/bin/../libexec/gcc/riscv-none-embed/10.2.0/lto-wrapper Target: riscv-none-embed Configured with: /Host/home/ilg/Work/riscv-none-embed-gcc-10.2.0-1.2/linux-x64/sources/riscv-gcc-10.2.0-1.1/configure --prefix=/Host/home/ilg/Work/riscv-none-embed-gcc-10.2.0-1.2/linux-x64/install/riscv-none-embed-gcc --infodir=/Host/home/ilg/Work/riscv-none-embed-gcc-10.2.0-1.2/linux-x64/install/riscv-none-embed-gcc/share/doc/info --mandir=/Host/home/ilg/Work/riscv-none-embed-gcc-10.2.0-1.2/linux-x64/install/riscv-none-embed-gcc/share/doc/man --htmldir=/Host/home/ilg/Work/riscv-none-embed-gcc-10.2.0-1.2/linux-x64/install/riscv-none-embed-gcc/share/doc/html --pdfdir=/Host/home/ilg/Work/riscv-none-embed-gcc-10.2.0-1.2/linux-x64/install/riscv-none-embed-gcc/share/doc/pdf --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=riscv-none-embed --with-pkgversion='xPack GNU RISC-V Embedded GCC x86_64' --with-bugurl=https://github.com/sifive/freedom-tools/issues/ --enable-languages=c,c++ --disable-mingw-wildcard --enable-plugins --enable-lto --enable-checking=yes --disable-tls --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-threads --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-riscv-none-embed --with-sysroot=/Host/home/ilg/Work/riscv-none-embed-gcc-10.2.0-1.2/linux-x64/install/riscv-none-embed-gcc/riscv-none-embed --with-native-system-header-dir=/include --with-abi=ilp32 --with-arch=rv32imac --disable-build-format-warnings --with-system-zlib Thread model: single Supported LTO compression algorithms: zlib gcc version 10.2.0 (xPack GNU RISC-V Embedded GCC x86_64)
Checkout & compile
You can checkout U-boot source tree from Hardkernel's Github.
- host
$ git clone https://github.com/hardkernel/u-boot.git -b odroidm1-v2017.09 $ cd u-boot $ git submodule init $ git submodule update
Before you compile U-boot, you must configure for ODROID-M1 with following command.
- host
$ ./make.sh odroid_rk3568
Installation
Installation to memory card directly
Basically U-Boot for ODROID-M1 is stored in on-board SPI flash memory and OS image for ODROID-M1 does not contain the bootloader blobs at all. In order to prevent your ODROID-M1 to brick by replacing malfunctioning U-Boot, SD or eMMC can be used for your custom U-Boot for developemnt or debugging. The memory card requires to be inititated in GPT partition table and U-Boot image must be placed in the partition labled as uboot so that the U-Boot blob can be loaded properly.
We will use gdisk commnad in Linux to create GPT partition and instruction in this section assumes to use SD card using USB card reader Transcend RDF5. The first thing is to install gdisk and run it to access a SD card.
sudo apt install gdisk ... $ sudo gdisk /dev/disk/by-id/usb-TS-RDF5_SD_Transcend_000000000039-0\:0 GPT fdisk (gdisk) version 1.0.8 Partition table scan: MBR: MBR only BSD: not present APM: not present GPT: not present *************************************************************** Found invalid GPT and valid MBR; converting MBR to GPT format in memory. THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if you don't want to convert your MBR partitions to GPT format! ***************************************************************
Creating GPT partition table on the SD card using the command o then add a partition in 4MB.
Command (? for help): o This option deletes all partitions and creates a new protective MBR. Proceed? (Y/N): y Command (? for help): n Partition number (1-128, default 1): First sector (34-15523806, default = 2048) or {+-}size{KMGTP}: Last sector (2048-15523806, default = 15523806) or {+-}size{KMGTP}: +4MB Current type is 8300 (Linux filesystem) Hex code or GUID (L to show codes, Enter = 8300): Changed type of partition to 'Linux filesystem'
Once the partition is created, most important thing is to label to partition with uboot since U-Boot blob will be discovered and loaded by the partition label regardless its offset in SD card.
Command (? for help): c Using 1 Enter name: uboot
Check out the partition table and save it if nothing wrong. Please note that partition type is not the matter since U-Boot blob is raw image, not any partition type.
Command (? for help): p Disk /dev/disk/by-id/usb-TS-RDF5_SD_Transcend_000000000039-0:0: 15523840 sectors, 7.4 GiB Sector size (logical/physical): 512/512 bytes Disk identifier (GUID): 2A716E36-4F68-4EF9-910D-74BFA3E10FC5 Partition table holds up to 128 entries Main partition table begins at sector 2 and ends at sector 33 First usable sector is 34, last usable sector is 15523806 Partitions will be aligned on 2048-sector boundaries Total free space is 15515581 sectors (7.4 GiB) Number Start (sector) End (sector) Size Code Name 1 2048 10239 4.0 MiB 8300 uboot Command (? for help): w Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING PARTITIONS!! Do you want to proceed? (Y/N): y OK; writing new GUID partition table (GPT) to /dev/disk/by-id/usb-TS-RDF5_SD_Transcend_000000000039-0:0. The operation has completed successfully.
When the partition is labeled properly in the memory card, the partition will be appeared in /dev/disk/by-partlabel/uboot whenever the memory card is inserted and U-Boot image can be flashed to the device node.
$ sudo dd if=uboot.img of=/dev/disk/by-partlabel/uboot conv=fsync 4096+0 records in 4096+0 records out 2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.674858 s, 3.1 MB/s $ sync
Now your ODROID-M1 will load the bootloader (U-Boot) from the memory card when it's inserted and the boot log through UART debugging port show like line #3 to #8. MMC1 and MMC2 are dedicated to eMMC and SD card respectively, the last device name before the log ## Verified-boot: 0 tells you where U-Boot is loaded from.
1 U-Boot SPL board init 2 U-Boot SPL 2017.09 (Mar 03 2022 - 23:58:53) 3 Trying to boot from MMC1 4 MMC error: The cmd index is 0, ret is -110 5 mmc_init: -110, time 4 6 spl: mmc init failed with error: -110 7 Trying to boot from MMC2 8 No misc partition 9 ## Verified-boot: 0 10 ## Checking atf-1 0x00040000 ... sha256(2f01bd8955...) + OK 11 ## Checking uboot 0x00a00000 ... sha256(8e1c3a1b75...) + OK 12 ## Checking fdt 0x00b1e370 ... sha256(06b6d16a4d...) + OK 13 ## Checking atf-2 0xfdcc9000 ... sha256(f1fecab971...) + OK 14 ## Checking atf-3 0xfdcd0000 ... sha256(d7aa45eb18...) + OK 15 ## Checking optee 0x08400000 ... sha256(b8cddafab0...) + OK 16 Jumping to U-Boot(0x00a00000) via ARM Trusted Firmware(0x00040000) 17 Total: 347.450 ms
If the SD card is removed, ODROID-M1 will load U-Boot from SPI flash memory again and the serial log will shows MTD2 like line #12 which is on-board SPI flash memory.
1 U-Boot SPL board init 2 U-Boot SPL 2017.09 (Mar 03 2022 - 23:58:53) 3 Trying to boot from MMC1 4 MMC error: The cmd index is 0, ret is -110 5 mmc_init: -110, time 4 6 spl: mmc init failed with error: -110 7 Trying to boot from MMC2 8 MMC error: The cmd index is 1, ret is -110 9 Card did not respond to voltage select! 10 mmc_init: -95, time 10 11 spl: mmc init failed with error: -95 12 Trying to boot from MTD2 13 No misc partition 14 ## Verified-boot: 0