Odroid-C2: Difference between revisions
m (libssl-dev is required to build kernel from source) |
m (→Booting: typo) |
||
(18 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
==Introduction== | ==Introduction== | ||
The Odroid-C2 single board computer is not very well supported by Alpine/Linux. However the "Generic ARM (aarch64)" build contains almost everything we need ! | The Odroid-C2 single board computer is not very well supported by Alpine/Linux. However the "Generic ARM (aarch64)" build contains almost everything we need ! | ||
What do we need ? | What do we need ? | ||
Line 13: | Line 7: | ||
* u-boot : provided u-boot does not autoboot without serial | * u-boot : provided u-boot does not autoboot without serial | ||
* system files : everything is okay | * system files : everything is okay | ||
On the hardware side: | On the hardware side: | ||
Line 25: | Line 18: | ||
Using GNU/Linux is recommended and this guide and here are the required dependencies, for Debian (as example) : | Using GNU/Linux is recommended and this guide and here are the required dependencies, for Debian (as example) : | ||
<pre> | <pre> | ||
apt install bc bison flex make gcc gcc-aarch64-linux-gnu libssl-dev libncurses-dev git | apt install bc bison flex make gcc gcc-aarch64-linux-gnu libssl-dev libncurses-dev git squashfs-tools | ||
</pre> | </pre> | ||
We need to set specific environment variables IF you are not using an arm64 machine. Usually, you should be running on a x64 architecture (Intel or AMD I guess), so you would like to cross-compile. | We need to set specific environment variables IF you are not using an arm64 machine. Usually, you should be running on a x64 architecture (Intel or AMD I guess), so you would like to cross-compile. | ||
Line 32: | Line 25: | ||
export CROSS_COMPILE=aarch64-linux-gnu | export CROSS_COMPILE=aarch64-linux-gnu | ||
</pre> | </pre> | ||
==Build u-boot from source== | ==Build u-boot from source== | ||
Line 57: | Line 51: | ||
Then, it's time to build : | Then, it's time to build : | ||
<pre> | <pre> | ||
export ARCH=arm64 && export CROSS_COMPILE=aarch64-linux-gnu- | |||
make odroidc2_defconfig | |||
time make -j$(nproc) | time make -j$(nproc) | ||
</pre> | </pre> | ||
Amlogic doesn’t provide sources for the firmware and for tools needed to create the bootloader image, so it is necessary to obtain them from the git tree published by the board vendor. | Amlogic doesn’t provide sources for the firmware and for tools needed to create the bootloader image, so it is necessary to obtain them from the git tree published by the board vendor. | ||
' | |||
So, you need to get Amlogic u-boot's fork to assemble the u-boot binary : | |||
<pre> | |||
cd .. | |||
git clone --depth 1 https://github.com/hardkernel/u-boot.git -b odroidc2-v2015.01 u-boot | |||
cd u-boot | |||
</pre> | |||
Copy "u-boot.bin" from the previous git repository (source.denx.de) to the amlogic u-boot repository: | |||
<pre>cp ../u-boot-denx.de/u-boot.bin .</pre> | |||
Then, generate u-boot using amlogic fip tools: | |||
<pre> | |||
./fip/fip_create --bl30 ./fip/gxb/bl30.bin --bl301 ./fip/gxb/bl301.bin --bl31 ./fip/gxb/bl31.bin --bl33 u-boot.bin ./fip.bin | |||
./fip/fip_create --dump ./fip.bin | |||
cat ./fip/gxb/bl2.package ./fip.bin > ./boot_new.bin | |||
./fip/gxb/aml_encrypt_gxb --bootsig --input ./boot_new.bin --output ./u-boot.img | |||
dd if=./u-boot.img of=./u-boot.gxbb bs=512 skip=96 | |||
</pre> | |||
Line 79: | Line 93: | ||
echo CONFIG_BLK_DEV_RAM_COUNT=16 >> .config | echo CONFIG_BLK_DEV_RAM_COUNT=16 >> .config | ||
echo CONFIG_BLK_DEV_RAM_SIZE=4096 >> .config | echo CONFIG_BLK_DEV_RAM_SIZE=4096 >> .config | ||
</pre> | |||
We can also disable unrequired DRM modules. Hence you'll get les modules, vmlinux will be smaller and building kernel will be faster. | |||
Note that you can also disable more modules or functionalities, by removing all DRM drivers or disable sound if you like it. It'll be perfect for a headless machine. | |||
<pre> | |||
sed -i -e 's/CONFIG_DRM_\(.*\)=.*/# CONFIG_DRM_\1 is not set/' .config | |||
sed -i -e 's/.*CONFIG_DRM_LIMA.*/CONFIG_DRM_LIMA=m/' .config | |||
sed -i -e 's/.*CONFIG_DRM_PANFROST.*/CONFIG_DRM_PANFROST=m/' .config | |||
</pre> | |||
If you want to enable DVFS for the s905 amlogic cpu : | |||
<pre> | |||
git apply --ignore-space-change --ignore-whitespace - << EOF | |||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | |||
index 201596247..027df3756 100644 | |||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | |||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | |||
@@ -348,7 +348,8 @@ &saradc { | |||
}; | |||
&scpi_clocks { | |||
- status = "disabled"; | |||
+ /* Works only with new blobs that have limited DVFS table */ | |||
+ status = "okay"; | |||
}; | |||
/* SD */ | |||
EOF | |||
</pre> | </pre> | ||
Line 98: | Line 140: | ||
==Assembly== | ==Assembly== | ||
Kernel part: | |||
<pre> | |||
DST="/mnt/mmcblk0p1" | |||
gzip -c arch/arm64/boot/Image > ${DST}/vmlinuz | |||
cp .config ${DST}/config | |||
cp modloop ${DST}/modloop | |||
cp System.map ${DST}/System.map | |||
</pre> | |||
Copy dtb: | |||
<pre> | |||
mkdir ${DST}/boot/dtbs | |||
cp arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ${DST}/boot/dtbs | |||
cp arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dtb ${DST}/boot/dtbs | |||
</pre> | |||
System part: | |||
<pre> | |||
tar -C $DST -xzf alpine-uboot-3.15.4-aarch64.tar.gz ./.alpine-release ./alpine.apkovl.tar.gz ./apks ./boot/initramfs-lts 2>/dev/null | |||
</pre> | |||
==U-Boot scripting== | |||
Create boot.cmd file to /dev/mmcblk0: | |||
<pre> | |||
DST="/mnt/mmcblk0p1" | |||
cat << EoF > boot.cmd | |||
#------------------------------------------------------------------------------------------------------ | |||
# | |||
# HELP: | |||
# boot.cmd = source file for humans | |||
# boot.scr = destination file needed for the board | |||
# recompile-me with: | |||
# mkimage -C none -A arm -T script -d boot.cmd boot.scr | |||
# | |||
#------------------------------------------------------------------------------------------------------ | |||
# init. | |||
setenv modloop "/boot/modloop" | |||
setenv console "tty1" | |||
setenv condev "console=ttyAML0,115200n8" | |||
setenv verbosity "7" | |||
setenv display_autodetect "true" | |||
# console arguments configuration | |||
setenv consoleargs "modules=loop,squashfs,sd-mod,usb-storage modloop=\${modloop} \${condev} console=\${console} panic=10" | |||
setenv bootargs "\${consoleargs} loglevel=\${verbosity}" | |||
# load files | |||
setenv devtype "mmc" | |||
setenv devnum "0:1" | |||
load \${devtype} \${devnum} \${kernel_addr_r} /boot/vmlinuz | |||
load \${devtype} \${devnum} \${ramdisk_addr_r} /boot/initramfs-lts | |||
load \${devtype} \${devnum} \${fdt_addr_r} /boot/dtbs/meson-gxbb-odroidc2.dtb | |||
# boot | |||
booti \$kernel_addr_r \$ramdisk_addr_r:3200000 \$fdt_addr_r | |||
EoF | |||
</pre> | |||
Then, build this file for u-boot. The mkimage binary is available in the ./tools/ directory from the source.denx.de repository (see "Build u-boot from source" part). | |||
<pre> | |||
mkimage -C none -A arm -T script -d boot.cmd boot.scr | |||
</pre> | |||
Please note that those two files must be placed in the /boot/ directory. | |||
==Booting== | ==Booting== | ||
Connect your USB to TTL converter on your board : I noticed that you don't need to connect all wires, pin 1 don't seems to be is not mandatory at all. | |||
<pre> | |||
_____UART____ | |||
|Pin 4 - GND| | |||
|Pin 3 - RXD| | |||
|Pin 2 - TXD| | |||
|Pin 1 - VCC| | |||
\___________| | |||
</pre> | |||
All details are available on the odroid wiki : https://wiki.odroid.com/accessory/development/usb_uart_kit | |||
[[Category:ARM]] | |||
[[Category:Hardware]] |
Latest revision as of 15:23, 17 April 2023
Introduction
The Odroid-C2 single board computer is not very well supported by Alpine/Linux. However the "Generic ARM (aarch64)" build contains almost everything we need !
What do we need ?
- kernel : provided kernel by the Alpine team does not boot
- u-boot : provided u-boot does not autoboot without serial
- system files : everything is okay
On the hardware side:
- Odroid-C2
- Official PSU or just a micro-SD cable (notes : the barrel plug (inner(positive) diameter 0.8mm and outer(negative) diameter 2.5mm) is recommended, without the J1 jumper)
- micro-SD (or eMMC)
- USB to TTL (official or CP2102 chipset or an old rpi)
Required environement and toolchain
Using GNU/Linux is recommended and this guide and here are the required dependencies, for Debian (as example) :
apt install bc bison flex make gcc gcc-aarch64-linux-gnu libssl-dev libncurses-dev git squashfs-tools
We need to set specific environment variables IF you are not using an arm64 machine. Usually, you should be running on a x64 architecture (Intel or AMD I guess), so you would like to cross-compile.
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu
Build u-boot from source
We need to build uboot from source as the u-boot provided does not autoboot without UART connected.
git clone --depth 1 https://source.denx.de/u-boot/u-boot.git -b v2022.01 u-boot-denx.de cd u-boot-denx.de export ARCH=arm64 && export CROSS_COMPILE=aarch64-linux-gnu- make mrproper && make odroid-c2_defconfig
We used the specific deconfig for the Odroid-C2 but, as mentionned before : we want to autoboot with or without UART connection. You can still access the SPL prompt by pressing the 'Enter' key twice before the two seconds countdown.
sed -i -e 's/.*CONFIG_SD_BOOT.*/CONFIG_SD_BOOT=y/' .config sed -i -e 's/.*CONFIG_AUTOBOOT_KEYED .*/CONFIG_AUTOBOOT_KEYED=y/' .config echo "CONFIG_AUTOBOOT_FLUSH_STDIN=y" >> .config echo "CONFIG_AUTOBOOT_PROMPT="Press quickly 'Enter' twice to stop autoboot: %d\n"" >> .config echo "# CONFIG_AUTOBOOT_ENCRYPTION is not set" >> .config echo "CONFIG_AUTOBOOT_DELAY_STR=""" >> .config echo "CONFIG_AUTOBOOT_STOP_STR="\xd\xd"" >> .config echo "CONFIG_AUTOBOOT_KEYED_CTRLC=y" >> .config
Then, it's time to build :
export ARCH=arm64 && export CROSS_COMPILE=aarch64-linux-gnu- make odroidc2_defconfig time make -j$(nproc)
Amlogic doesn’t provide sources for the firmware and for tools needed to create the bootloader image, so it is necessary to obtain them from the git tree published by the board vendor.
So, you need to get Amlogic u-boot's fork to assemble the u-boot binary :
cd .. git clone --depth 1 https://github.com/hardkernel/u-boot.git -b odroidc2-v2015.01 u-boot cd u-boot
Copy "u-boot.bin" from the previous git repository (source.denx.de) to the amlogic u-boot repository:
cp ../u-boot-denx.de/u-boot.bin .
Then, generate u-boot using amlogic fip tools:
./fip/fip_create --bl30 ./fip/gxb/bl30.bin --bl301 ./fip/gxb/bl301.bin --bl31 ./fip/gxb/bl31.bin --bl33 u-boot.bin ./fip.bin ./fip/fip_create --dump ./fip.bin cat ./fip/gxb/bl2.package ./fip.bin > ./boot_new.bin ./fip/gxb/aml_encrypt_gxb --bootsig --input ./boot_new.bin --output ./u-boot.img dd if=./u-boot.img of=./u-boot.gxbb bs=512 skip=96
Build the latest LTS kernel from source
git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -b linux-5.15.y linux-stable cd linux-stable export ARCH=arm64 && export CROSS_COMPILE=aarch64-linux-gnu- make mrproper && make defconfig
We need to adapt the default arm64 generated by defconfig. This configuration is required for Alpine/Linux and not enabled by default.
sed -i -e 's/.*CONFIG_SQUASHFS_XZ.*/CONFIG_SQUASHFS_XZ=y/' .config sed -i -e 's/.*CONFIG_UEVENT_HELPER.*/CONFIG_UEVENT_HELPER=y/' .config sed -i -e 's/.*CONFIG_BLK_DEV_RAM.*/CONFIG_BLK_DEV_RAM=y/' .config echo CONFIG_UEVENT_HELPER_PATH=\"/sbin/hotplug\" >> .config echo CONFIG_BLK_DEV_RAM_COUNT=16 >> .config echo CONFIG_BLK_DEV_RAM_SIZE=4096 >> .config
We can also disable unrequired DRM modules. Hence you'll get les modules, vmlinux will be smaller and building kernel will be faster. Note that you can also disable more modules or functionalities, by removing all DRM drivers or disable sound if you like it. It'll be perfect for a headless machine.
sed -i -e 's/CONFIG_DRM_\(.*\)=.*/# CONFIG_DRM_\1 is not set/' .config sed -i -e 's/.*CONFIG_DRM_LIMA.*/CONFIG_DRM_LIMA=m/' .config sed -i -e 's/.*CONFIG_DRM_PANFROST.*/CONFIG_DRM_PANFROST=m/' .config
If you want to enable DVFS for the s905 amlogic cpu :
git apply --ignore-space-change --ignore-whitespace - << EOF diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts index 201596247..027df3756 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -348,7 +348,8 @@ &saradc { }; &scpi_clocks { - status = "disabled"; + /* Works only with new blobs that have limited DVFS table */ + status = "okay"; }; /* SD */ EOF
The, build your kernel, associated modules and the DTB (Device Tree Blob) from the source :
time make -j$(nproc) Image dtbs modules
Create modloop:
rm -rf installed-modules && mkdir installed-modules INSTALL_MOD_PATH=installed-modules make modules_install find installed-modules -type l -delete rm -f modloop mksquashfs installed-modules/lib/ modloop -b 1048576 -comp xz -Xdict-size 100% -all-root rm -rf installed-modules
Assembly
Kernel part:
DST="/mnt/mmcblk0p1" gzip -c arch/arm64/boot/Image > ${DST}/vmlinuz cp .config ${DST}/config cp modloop ${DST}/modloop cp System.map ${DST}/System.map
Copy dtb:
mkdir ${DST}/boot/dtbs cp arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts ${DST}/boot/dtbs cp arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dtb ${DST}/boot/dtbs
System part:
tar -C $DST -xzf alpine-uboot-3.15.4-aarch64.tar.gz ./.alpine-release ./alpine.apkovl.tar.gz ./apks ./boot/initramfs-lts 2>/dev/null
U-Boot scripting
Create boot.cmd file to /dev/mmcblk0:
DST="/mnt/mmcblk0p1" cat << EoF > boot.cmd #------------------------------------------------------------------------------------------------------ # # HELP: # boot.cmd = source file for humans # boot.scr = destination file needed for the board # recompile-me with: # mkimage -C none -A arm -T script -d boot.cmd boot.scr # #------------------------------------------------------------------------------------------------------ # init. setenv modloop "/boot/modloop" setenv console "tty1" setenv condev "console=ttyAML0,115200n8" setenv verbosity "7" setenv display_autodetect "true" # console arguments configuration setenv consoleargs "modules=loop,squashfs,sd-mod,usb-storage modloop=\${modloop} \${condev} console=\${console} panic=10" setenv bootargs "\${consoleargs} loglevel=\${verbosity}" # load files setenv devtype "mmc" setenv devnum "0:1" load \${devtype} \${devnum} \${kernel_addr_r} /boot/vmlinuz load \${devtype} \${devnum} \${ramdisk_addr_r} /boot/initramfs-lts load \${devtype} \${devnum} \${fdt_addr_r} /boot/dtbs/meson-gxbb-odroidc2.dtb # boot booti \$kernel_addr_r \$ramdisk_addr_r:3200000 \$fdt_addr_r EoF
Then, build this file for u-boot. The mkimage binary is available in the ./tools/ directory from the source.denx.de repository (see "Build u-boot from source" part).
mkimage -C none -A arm -T script -d boot.cmd boot.scr
Please note that those two files must be placed in the /boot/ directory.
Booting
Connect your USB to TTL converter on your board : I noticed that you don't need to connect all wires, pin 1 don't seems to be is not mandatory at all.
_____UART____ |Pin 4 - GND| |Pin 3 - RXD| |Pin 2 - TXD| |Pin 1 - VCC| \___________|
All details are available on the odroid wiki : https://wiki.odroid.com/accessory/development/usb_uart_kit