wtorek, 20 września 2022

Colibri IMx6 - BSP - Linux U-Boot i Kernel

W tym poście opiszę sposób przygotowania U-Boot'a oraz Kernel dla modułu Toradex Colibri w wersji BSP 3.0.

[Źródło: https://developer.toradex.com/hardware/colibri-som-family/modules/colibri-imx6]

Po dokładniejszy opis polecam zajrzeć na stronę producenta [link] [link]

U-Boot kompilacja:


Na samym początku należy zainstalować potrzebne pakiety:

  1. sudo apt-get install u-boot-tools
  2. sudo apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev

Warto także doinstalować kilka dodatkowych pakietów:

  1. sudo apt-get install device-tree-compiler bizon flex
  2. 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.

  1. $ 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"
  2. $ tar xvf gcc-arm-8.2-2019.01-x86_64-arm-linux-gnueabihf.tar.xz
  3. $ 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:

  1. export ARCH=arm
  2. export PATH=~/toradex_clear/toradex-uboot/gcc-arm/bin/:$PATH
  3. export CROSS_COMPILE=arm-linux-gnueabihf-

Trzeba również pobrać kod źródłowy U-Boot:

  1. 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:

  1. source ./export-gcc

Najszybciej zacząć od wykonania standardowej kompilacji zapisanej w pliku colibri_imx6_defconfig.

  1. make colibri_imx6_defconfig
  2.  
  3. #
  4. # configuration written to .config
  5. #

Modyfikacje ustawień wykonujemy przez polecenie:

  1. make menuconfig

Plik znajduje się w katalogu /home/rcpkd/toradex_clear/toradex-uboot/u-boot-toradex/configs. Jego zawartość wygląda następująco:

  1. CONFIG_ARM=y
  2. CONFIG_ARCH_MX6=y
  3. CONFIG_SYS_TEXT_BASE=0x17800000
  4. CONFIG_SPL_GPIO_SUPPORT=y
  5. CONFIG_SPL_LIBCOMMON_SUPPORT=y
  6. CONFIG_SPL_LIBGENERIC_SUPPORT=y
  7. CONFIG_TARGET_COLIBRI_IMX6=y
  8. CONFIG_SPL_MMC_SUPPORT=y
  9. CONFIG_SPL_SERIAL_SUPPORT=y
  10. CONFIG_NR_DRAM_BANKS=1
  11. CONFIG_SPL=y
  12. CONFIG_CMD_HDMIDETECT=y
  13. CONFIG_DISTRO_DEFAULTS=y
  14. CONFIG_FIT=y
  15. CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6DL"
  16. CONFIG_BOOTDELAY=1
  17. # CONFIG_CONSOLE_MUX is not set
  18. CONFIG_SYS_CONSOLE_IS_IN_ENV=y
  19. CONFIG_MISC_INIT_R=y
  20. CONFIG_VERSION_VARIABLE=y
  21. # CONFIG_DISPLAY_BOARDINFO is not set
  22. CONFIG_DISPLAY_BOARDINFO_LATE=y
  23. CONFIG_BOUNCE_BUFFER=y
  24. CONFIG_BOARD_EARLY_INIT_F=y
  25. CONFIG_SPL_TEXT_BASE=0x00908000
  26. CONFIG_SPL_DMA_SUPPORT=y
  27. CONFIG_SPL_I2C_SUPPORT=y
  28. CONFIG_SPL_USB_HOST_SUPPORT=y
  29. CONFIG_SPL_USB_GADGET=y
  30. CONFIG_SPL_USB_SDP_SUPPORT=y
  31. CONFIG_SYS_PROMPT="Colibri iMX6 # "
  32. # CONFIG_CMD_ELF is not set
  33. # CONFIG_CMD_IMI is not set
  34. # CONFIG_CMD_XIMG is not set
  35. CONFIG_CMD_ASKENV=y
  36. CONFIG_CRC32_VERIFY=y
  37. CONFIG_CMD_MEMTEST=y
  38. CONFIG_SYS_ALT_MEMTEST=y
  39. CONFIG_CMD_GPIO=y
  40. CONFIG_CMD_GPT=y
  41. CONFIG_CMD_I2C=y
  42. CONFIG_CMD_MMC=y
  43. CONFIG_CMD_USB=y
  44. CONFIG_CMD_USB_SDP=y
  45. CONFIG_CMD_USB_MASS_STORAGE=y
  46. CONFIG_CMD_BMP=y
  47. CONFIG_CMD_BOOTCOUNT=y
  48. CONFIG_CMD_CACHE=y
  49. CONFIG_CMD_UUID=y
  50. CONFIG_CMD_PMIC=y
  51. CONFIG_CMD_REGULATOR=y
  52. CONFIG_OF_CONTROL=y
  53. CONFIG_DEFAULT_DEVICE_TREE="imx6-colibri"
  54. CONFIG_ENV_IS_IN_MMC=y
  55. CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
  56. CONFIG_IP_DEFRAG=y
  57. CONFIG_TFTP_BLOCKSIZE=16352
  58. CONFIG_BOOTCOUNT_LIMIT=y
  59. CONFIG_BOOTCOUNT_ENV=y
  60. CONFIG_DM_GPIO=y
  61. CONFIG_DM_I2C=y
  62. CONFIG_DM_MMC=y
  63. CONFIG_SUPPORT_EMMC_BOOT=y
  64. CONFIG_FSL_ESDHC=y
  65. CONFIG_PHYLIB=y
  66. CONFIG_PHY_MICREL=y
  67. CONFIG_PHY_MICREL_KSZ8XXX=y
  68. CONFIG_MII=y
  69. CONFIG_PINCTRL=y
  70. CONFIG_PINCTRL_IMX6=y
  71. CONFIG_DM_PMIC=y
  72. CONFIG_DM_PMIC_PFUZE100=y
  73. CONFIG_DM_REGULATOR=y
  74. CONFIG_DM_REGULATOR_PFUZE100=y
  75. CONFIG_DM_REGULATOR_FIXED=y
  76. CONFIG_IMX_THERMAL=y
  77. CONFIG_USB=y
  78. CONFIG_DM_USB=y
  79. CONFIG_USB_KEYBOARD=y
  80. CONFIG_USB_GADGET=y
  81. CONFIG_USB_GADGET_MANUFACTURER="Toradex"
  82. CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
  83. CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
  84. CONFIG_CI_UDC=y
  85. CONFIG_USB_GADGET_DOWNLOAD=y
  86. CONFIG_USB_HOST_ETHER=y
  87. CONFIG_DM_VIDEO=y
  88. CONFIG_SYS_WHITE_ON_BLACK=y
  89. CONFIG_VIDEO_IPUV3=y
  90. CONFIG_FAT_WRITE=y
  91. CONFIG_OF_LIBFDT_OVERLAY=y

Następnie należy skompilować projekt. Kompilacja przygotuje pliki SPL oraz u-boot.img. 

  1. 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. 

  1. 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.

  1. tar xvf gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz
  2. 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:

  1. export ARCH=arm
  2. export PATH=~/toradex_clear/toradex-kernel/gcc-linaro/bin/:$PATH
  3. export CROSS_COMPILE=arm-linux-gnueabihf-
  4. export INSTALL_MOD_PATH=~/toradex_clear/toradex-kernel/linux-toradex/modules
  5. export KLIB=~/toradex-kernel/linux-toradex/modules
  6. export KLIB_BUILD=~/toradex_clear/toradex-kernel/linux-toradex

  1. 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. 

  1. make colibri_imx6_defconfig
  2. make nconfig
  3. make -j$(nproc) zImage LOADADDR=10008000 2>&1 | tee build.log
  4. make imx6dl-colibri-aster.dtb

Po tych operacjach zostanie przygotowany obraz systemu:

  1. /*
  2. ...
  3. ...
  4. */
  5.  
  6. LD arch/arm/boot/compressed/vmlinux
  7. OBJCOPY arch/arm/boot/zImage
  8. Kernel: arch/arm/boot/zImage is ready

Tak przygotowane pliki należy umieścić w pobranym obrazie systemu. Wykorzystuje obraz:

  1. Colibri-iMX6_LXDE-Image-Tezi_2.8b6.184

Struktura katalogu z obrazem producenta jest następująca: 


Z folderu toradex-uboot należy zaktualizować pliki u-boot.img oraz SPL. 

Po pobraniu obrazu należy wykonać następujące operacje:

  1. tar xf ~/Pobrane/Colibri-iMX6_LXDE-Image-Tezi_2.8b6.184.tar
  2. cd Colibri-iMX6_LXDE-Image-Tezi_2.8b6.184/
  3. mkdir Colibri-iMX6_LXDE-Image.bootfs
  4. cd Colibri-iMX6_LXDE-Image.bootfs/
  5. tar xJf ../Colibri-iMX6_LXDE-Image.bootfs.tar.xz
  6. cp ~/toradex_clear/toradex-kernel/linux-toradex/arch/arm/boot/dts/imx6dl-colibri-aster.dtb .
  7. cp ~/toradex_clear/toradex-kernel/linux-toradex/arch/arm/boot/zImage .
  8. tar cJf ../Colibri-iMX6_LXDE-Image.bootfs.tar.xz *
  9. cd ..
  10. rm -rf Colibri-iMX6_LXDE-Image.bootfs

Plik image.json może zostać dostosowany do potrzeb:

  1. {
  2.     "config_format": 2,
  3.     "autoinstall": true,
  4.     "name": "Toradex Embedded Linux with LXDE - test",
  5.     "description": "Angstrom-based image with the LXDE desktop environment - test",
  6.     "version": "1.0",
  7.     "release_date": "2022-09-10",
  8.     "u_boot_env": "uEnv.txt",
  9.     "prepare_script": "prepare.sh",
  10.     "wrapup_script": "wrapup.sh",
  11.     "marketing": "marketing.tar",
  12.     "icon": "toradexlinux.png",
  13.     "supported_product_ids": [
  14.         "0014",
  15.         "0015",
  16.         "0016",
  17.         "0017"
  18.     ],
  19.     "blockdevs": [
  20.         {
  21.             "name": "mmcblk0",
  22.             "partitions": [
  23.                 {
  24.                     "partition_size_nominal": 16,
  25.                     "want_maximised": false,
  26.                     "content": {
  27.                         "label": "BOOT",
  28.                         "filesystem_type": "FAT",
  29.                         "mkfs_options": "",
  30.                         "filename": "Colibri-iMX6_LXDE-Image.bootfs.tar.xz",
  31.                         "uncompressed_size": 5.0703125
  32.                     }
  33.                 },
  34.                 {
  35.                     "partition_size_nominal": 1024,
  36.                     "want_maximised": true,
  37.                     "content": {
  38.                         "label": "RFS",
  39.                         "filesystem_type": "ext4",
  40.                         "mkfs_options": "-E nodiscard",
  41.                         "filename": "Colibri-iMX6_LXDE-Image.rootfs.tar.xz",
  42.                         "uncompressed_size": 460.7265625
  43.                     }
  44.                 }
  45.             ]
  46.         },
  47.         {
  48.             "name": "mmcblk0boot0",
  49.             "content": {
  50.                 "filesystem_type": "raw",
  51.                 "rawfiles": [
  52.                     {
  53.                         "filename": "SPL",
  54.                         "dd_options": "seek=2"
  55.                     },
  56.                     {
  57.                         "filename": "u-boot.img",
  58.                         "dd_options": "seek=138"
  59.                     }
  60.                 ]
  61.             }
  62.         }
  63.     ]
  64. }

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:

  1. cp ~/toradex_clear/toradex-uboot/u-boot-toradex/SPL .
  2. 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. 

  1. make -j$(nproc) modules
  2. mkdir modules
  3. export INSTALL_MOD_PATH=modules
  4. make modules_install
  5. cd modules
  6. tar -czf ../modules.tar.gz .
  7. cd ~/Colibri-iMX6_LXDE-Image-Tezi_2.8b6.184/
  8. 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:


  1. env set fdt_file 'imx6dl-colibri-aster.dtb'
  2. env save
  3. reset

Poleceniem reset ponownie ładujemy system, który tym razem należy uruchomić normalnie.

Do logowania podajemy nazwę użytkownika root. Hasło nie jest przypisane.

Kolejnym krokiem jest instalacja wygenerowanych modułów:

  1. tar -xzf /media/sda1/modules.tar.gz -C /
  2. depmod
  3. umount /media/sda1/

Po wgraniu odpowiedniej paczki modułów wszystkie błędy pojawiające się po starcie systemu powinny zniknąć.