W tym poście opiszę sposób przygotowania U-Boot'a oraz Kernel dla modułu Toradex Colibri w wersji BSP 3.0.
U-Boot kompilacja:
Na samym początku należy zainstalować potrzebne pakiety:
- sudo apt-get install u-boot-tools
- sudo apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev
Warto także doinstalować kilka dodatkowych pakietów:
- sudo apt-get install device-tree-compiler bizon flex
- sudo apt-get update -y
Następnie tworzymy katalog w którym przechowywane będą pliki U-Boot. Po czym pobieramy toolchain ze strony producenta.
- $ wget -O gcc-arm-8.2-2019.01-x86_64-arm-linux-gnueabihf.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu-a/8.2-2019.01/gcc-arm-8.2-2019.01-x86_64-arm-linux-gnueabihf.tar.xz?revision=c69ea519-a965-4359-84a4-cbd440ff4130&la=en&hash=09C47C70EEE96D17EA036A7A59AE961972320A31"
- $ tar xvf gcc-arm-8.2-2019.01-x86_64-arm-linux-gnueabihf.tar.xz
- $ ln -s gcc-arm-8.2-2019.01-x86_64-arm-linux-gnueabihf gcc-arm
Następnie tworzymy plik export-gcc w którym będą zdefiniowane lokalizacje potrzebnych bibliotek. Należy go wywołać każdorazowo po otwarciu okna konsoli:
- export ARCH=arm
- export PATH=~/toradex_clear/toradex-uboot/gcc-arm/bin/:$PATH
- export CROSS_COMPILE=arm-linux-gnueabihf-
Trzeba również pobrać kod źródłowy U-Boot:
- git clone -b toradex_2019.07 git://git.toradex.com/u-boot-toradex.git
Wywołanie wszystkich zmiennych z pliku wykonuje się w następujący sposób:
- source ./export-gcc
Najszybciej zacząć od wykonania standardowej kompilacji zapisanej w pliku colibri_imx6_defconfig.
- make colibri_imx6_defconfig
- #
- # configuration written to .config
- #
Modyfikacje ustawień wykonujemy przez polecenie:
- make menuconfig
Plik znajduje się w katalogu /home/rcpkd/toradex_clear/toradex-uboot/u-boot-toradex/configs. Jego zawartość wygląda następująco:
- CONFIG_ARM=y
- CONFIG_ARCH_MX6=y
- CONFIG_SYS_TEXT_BASE=0x17800000
- CONFIG_SPL_GPIO_SUPPORT=y
- CONFIG_SPL_LIBCOMMON_SUPPORT=y
- CONFIG_SPL_LIBGENERIC_SUPPORT=y
- CONFIG_TARGET_COLIBRI_IMX6=y
- CONFIG_SPL_MMC_SUPPORT=y
- CONFIG_SPL_SERIAL_SUPPORT=y
- CONFIG_NR_DRAM_BANKS=1
- CONFIG_SPL=y
- CONFIG_CMD_HDMIDETECT=y
- CONFIG_DISTRO_DEFAULTS=y
- CONFIG_FIT=y
- CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6DL"
- CONFIG_BOOTDELAY=1
- # CONFIG_CONSOLE_MUX is not set
- CONFIG_SYS_CONSOLE_IS_IN_ENV=y
- CONFIG_MISC_INIT_R=y
- CONFIG_VERSION_VARIABLE=y
- # CONFIG_DISPLAY_BOARDINFO is not set
- CONFIG_DISPLAY_BOARDINFO_LATE=y
- CONFIG_BOUNCE_BUFFER=y
- CONFIG_BOARD_EARLY_INIT_F=y
- CONFIG_SPL_TEXT_BASE=0x00908000
- CONFIG_SPL_DMA_SUPPORT=y
- CONFIG_SPL_I2C_SUPPORT=y
- CONFIG_SPL_USB_HOST_SUPPORT=y
- CONFIG_SPL_USB_GADGET=y
- CONFIG_SPL_USB_SDP_SUPPORT=y
- CONFIG_SYS_PROMPT="Colibri iMX6 # "
- # CONFIG_CMD_ELF is not set
- # CONFIG_CMD_IMI is not set
- # CONFIG_CMD_XIMG is not set
- CONFIG_CMD_ASKENV=y
- CONFIG_CRC32_VERIFY=y
- CONFIG_CMD_MEMTEST=y
- CONFIG_SYS_ALT_MEMTEST=y
- CONFIG_CMD_GPIO=y
- CONFIG_CMD_GPT=y
- CONFIG_CMD_I2C=y
- CONFIG_CMD_MMC=y
- CONFIG_CMD_USB=y
- CONFIG_CMD_USB_SDP=y
- CONFIG_CMD_USB_MASS_STORAGE=y
- CONFIG_CMD_BMP=y
- CONFIG_CMD_BOOTCOUNT=y
- CONFIG_CMD_CACHE=y
- CONFIG_CMD_UUID=y
- CONFIG_CMD_PMIC=y
- CONFIG_CMD_REGULATOR=y
- CONFIG_OF_CONTROL=y
- CONFIG_DEFAULT_DEVICE_TREE="imx6-colibri"
- CONFIG_ENV_IS_IN_MMC=y
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
- CONFIG_IP_DEFRAG=y
- CONFIG_TFTP_BLOCKSIZE=16352
- CONFIG_BOOTCOUNT_LIMIT=y
- CONFIG_BOOTCOUNT_ENV=y
- CONFIG_DM_GPIO=y
- CONFIG_DM_I2C=y
- CONFIG_DM_MMC=y
- CONFIG_SUPPORT_EMMC_BOOT=y
- CONFIG_FSL_ESDHC=y
- CONFIG_PHYLIB=y
- CONFIG_PHY_MICREL=y
- CONFIG_PHY_MICREL_KSZ8XXX=y
- CONFIG_MII=y
- CONFIG_PINCTRL=y
- CONFIG_PINCTRL_IMX6=y
- CONFIG_DM_PMIC=y
- CONFIG_DM_PMIC_PFUZE100=y
- CONFIG_DM_REGULATOR=y
- CONFIG_DM_REGULATOR_PFUZE100=y
- CONFIG_DM_REGULATOR_FIXED=y
- CONFIG_IMX_THERMAL=y
- CONFIG_USB=y
- CONFIG_DM_USB=y
- CONFIG_USB_KEYBOARD=y
- CONFIG_USB_GADGET=y
- CONFIG_USB_GADGET_MANUFACTURER="Toradex"
- CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
- CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
- CONFIG_CI_UDC=y
- CONFIG_USB_GADGET_DOWNLOAD=y
- CONFIG_USB_HOST_ETHER=y
- CONFIG_DM_VIDEO=y
- CONFIG_SYS_WHITE_ON_BLACK=y
- CONFIG_VIDEO_IPUV3=y
- CONFIG_FAT_WRITE=y
- CONFIG_OF_LIBFDT_OVERLAY=y
Następnie należy skompilować projekt. Kompilacja przygotuje pliki SPL oraz u-boot.img.
- make -j$(nproc) 2>&1 | tee build.log
Linux Kernel:
Następnym krokiem jest przygotowanie jądra systemu.
Na samym początku należy pobrać obraz jaki będzie wykorzystywany.
- git clone -b toradex_4.9-2.3.x-imx git://git.toradex.com/linux-toradex.git
Kolejnym krokiem jest pobranie zestawu narzędzi nie zbędnego do wykonania poprawnej kompilacji. Całość należy pobrać ze strony Linaro. Gdzie pobieramy paczkę gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz i rozpakowujemy ją w folderze zawierającym jądro systemu.
Teraz należy wypakować pobrany pakiet i przygotować dowiązanie do folderu gcc-linaro.
- tar xvf gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz
- ln -s gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf gcc-linaro
Załadowanie zmiennych środowiskowych. Podobnie jak to miało miejsce w przypadku u-boot przygotowujemy plik potrzebny do szybkiego ich ustawienia:
- export ARCH=arm
- export PATH=~/toradex_clear/toradex-kernel/gcc-linaro/bin/:$PATH
- export CROSS_COMPILE=arm-linux-gnueabihf-
- export INSTALL_MOD_PATH=~/toradex_clear/toradex-kernel/linux-toradex/modules
- export KLIB=~/toradex-kernel/linux-toradex/modules
- export KLIB_BUILD=~/toradex_clear/toradex-kernel/linux-toradex
- source ./export-gcc
Teraz przejście do folderu linux-toradex i wykonanie konfiguracji. Używam płytki Aster, więc przygotuję konfigurację dla niej. W związku tym, że jest to płytka przygotowana przez producenta, device tree dla niej jest już przygotowany. Pliki znajdują się w folderze arch/arm/boot/dts.
- make colibri_imx6_defconfig
- make nconfig
- make -j$(nproc) zImage LOADADDR=10008000 2>&1 | tee build.log
- make imx6dl-colibri-aster.dtb
Po tych operacjach zostanie przygotowany obraz systemu:
- /*
- ...
- ...
- */
- LD arch/arm/boot/compressed/vmlinux
- OBJCOPY arch/arm/boot/zImage
- Kernel: arch/arm/boot/zImage is ready
Tak przygotowane pliki należy umieścić w pobranym obrazie systemu. Wykorzystuje obraz:
- Colibri-iMX6_LXDE-Image-Tezi_2.8b6.184
Struktura katalogu z obrazem producenta jest następująca:
Po pobraniu obrazu należy wykonać następujące operacje:
- tar xf ~/Pobrane/Colibri-iMX6_LXDE-Image-Tezi_2.8b6.184.tar
- cd Colibri-iMX6_LXDE-Image-Tezi_2.8b6.184/
- mkdir Colibri-iMX6_LXDE-Image.bootfs
- cd Colibri-iMX6_LXDE-Image.bootfs/
- tar xJf ../Colibri-iMX6_LXDE-Image.bootfs.tar.xz
- cp ~/toradex_clear/toradex-kernel/linux-toradex/arch/arm/boot/dts/imx6dl-colibri-aster.dtb .
- cp ~/toradex_clear/toradex-kernel/linux-toradex/arch/arm/boot/zImage .
- tar cJf ../Colibri-iMX6_LXDE-Image.bootfs.tar.xz *
- cd ..
- rm -rf Colibri-iMX6_LXDE-Image.bootfs
Plik image.json może zostać dostosowany do potrzeb:
- {
- "config_format": 2,
- "autoinstall": true,
- "name": "Toradex Embedded Linux with LXDE - test",
- "description": "Angstrom-based image with the LXDE desktop environment - test",
- "version": "1.0",
- "release_date": "2022-09-10",
- "u_boot_env": "uEnv.txt",
- "prepare_script": "prepare.sh",
- "wrapup_script": "wrapup.sh",
- "marketing": "marketing.tar",
- "icon": "toradexlinux.png",
- "supported_product_ids": [
- "0014",
- "0015",
- "0016",
- "0017"
- ],
- "blockdevs": [
- {
- "name": "mmcblk0",
- "partitions": [
- {
- "partition_size_nominal": 16,
- "want_maximised": false,
- "content": {
- "label": "BOOT",
- "filesystem_type": "FAT",
- "mkfs_options": "",
- "filename": "Colibri-iMX6_LXDE-Image.bootfs.tar.xz",
- "uncompressed_size": 5.0703125
- }
- },
- {
- "partition_size_nominal": 1024,
- "want_maximised": true,
- "content": {
- "label": "RFS",
- "filesystem_type": "ext4",
- "mkfs_options": "-E nodiscard",
- "filename": "Colibri-iMX6_LXDE-Image.rootfs.tar.xz",
- "uncompressed_size": 460.7265625
- }
- }
- ]
- },
- {
- "name": "mmcblk0boot0",
- "content": {
- "filesystem_type": "raw",
- "rawfiles": [
- {
- "filename": "SPL",
- "dd_options": "seek=2"
- },
- {
- "filename": "u-boot.img",
- "dd_options": "seek=138"
- }
- ]
- }
- }
- ]
- }
Powyższy plik może zostać dostosowany do własnych potrzeb. Można w nim zmienić np. nazwę, opis, wersję, dane ale także wielkość partycji czy nazwy plików jakie mają być brane do instalacji.
Należy także przenieść wygenerowane elementy U-Boot:
- cp ~/toradex_clear/toradex-uboot/u-boot-toradex/SPL .
- cp ~/toradex_clear/toradex-uboot/u-boot-toradex/u-boot.img .
Następnym etapem jest przygotowanie modułów. Tutaj należy pamiętać, że przygotowane biblioteki muszą być połączone z wygenerowanym obrazem systemu. W innym przypadku nie będą one działać prawidłowo.
- make -j$(nproc) modules
- mkdir modules
- export INSTALL_MOD_PATH=modules
- make modules_install
- cd modules
- tar -czf ../modules.tar.gz .
- cd ~/Colibri-iMX6_LXDE-Image-Tezi_2.8b6.184/
- cp ~/toradex_clear/toradex-kernel/linux-toradex/modules.tar.gz .
Wygenerowane moduły dołączam do obrazu systemu. Po uruchomieniu ich wgrywanie przeprowadzę bezpośrednio z pendriva.
Przygotowany obraz należy wrzucić na pendrive i podłączyć go do złącza USB znajdującego się na płytce Aster. Dodatkowo należy podłączyć kabel USB z komputerem, tak aby program Toradex Easy Installer mógł rozpocząć pracę. Dobrze jest także podłączyć monitor, w celu obserwacji przebiegu instalacji systemu. Urządzenia manipulacyjne jak myszka czy klawiatura są opcjonalne i nie ma potrzeby ich podpinania.
[Źródło: https://developer.toradex.com/easy-installer/how-to/loading-toradex-easy-installer#colibriimx6]
Przed podłączeniem zasilania do płytki Aster należy zewrzeć piny widoczne na zdjęciu np. za pomocą pęsety. Następnie podłączamy kabel USB do złącza X10. Po czym podłączamy zasilanie i uruchamiamy program toradex easy installer. Poprawne uruchomienie powinno dać następujący efekt:
Po poprawnym wgraniu obrazu systemu należy odłączyć płytkę od zasilnia oraz przełożyć kabel USB do złącza SerialToUSB.
Po uruchomieniu należy zatrzymać proces autoboot i zmodyfikować zmienną środowiskową wskazującą na wygenerowany plik device tree:
Do logowania podajemy nazwę użytkownika root. Hasło nie jest przypisane.
Kolejnym krokiem jest instalacja wygenerowanych modułów:
- tar -xzf /media/sda1/modules.tar.gz -C /
- depmod
- umount /media/sda1/
Po wgraniu odpowiedniej paczki modułów wszystkie błędy pojawiające się po starcie systemu powinny zniknąć.