:::: MENU ::::

Установка uClinux на STM32F429 DISCO

uClinux — специальная редакция ядра Linux, способная работать без блока управления памятью [MMU]. ARM Cortex-M MMU не имеют, поэтому на микроконтроллеры на этом ядре, полноценный Linux не поставишь (если только написать эмулятор, как это сделано здесь http://dmitry.gr/index.php?r=05.Projects&proj=07.%20Linux%20on%208bit для AVR).

Значит ставим uCLinux.

Простенькая инструкция по установке.


1. Качаем Linux

uClinux был объединен с основной веткой Linux kernel, поэтому можно брать последнюю стабильную версию ядра — https://www.kernel.org/pub/linux/kernel/ .

Для компиляции ядра у вас должен стоять компилятор ARM — берем отсюда — https://launchpad.net/gcc-arm-embedded .

2. Качаем initramfs

Качаем отсюда — http://elinux.org/images/5/51/Stm32_mini_rootfs.cpio.bz2 — и разархивируем.

mkdir rootfs
cd rootfs
wget http://elinux.org/images/5/51/Stm32_mini_rootfs.cpio.bz2
bzcat ./Stm32_mini_rootfs.cpio.bz2 | sudo cpio -i
rm ./Stm32_mini_rootfs.cpio.bz2

Данный initramfs уже содержит в себе Busybox, скомпилированный для нашей платформы. Поэтому, при компиляции ядра, просто выберем использовать initramfs и укажем путь к нему — см. следующий пункт.

Более подробно про создание initramfs и busybox можно почитать эту статью — https://badembed.ru/qemu-busybox-linux-kernel .

3. Компилируем uClinux

make ARCH=arm CROSS_COMPILE=arm-none-eabi- stm32_defconfig

Далее открываем появившейся файл .config в корне исходников ядра Linux, находим в нем строку CONFIG_INITRAMFS_SOURCE и прописываем путь к нашему initramfs (который вы разархивировали на предыдущем этапе).

CONFIG_INITRAMFS_SOURCE="/home/alex/uclinux_stm32_v2/rootfs"

Далее:

make ARCH=arm CROSS_COMPILE=arm-none-eabi-

На запрос INITRAMFS_ROOT_UID и INITRAMFS_ROOT_GID ставим 0.

4. Качаем и компилируем Bootloader

git clone https://github.com/afaerber/afboot-stm32
cd afboot-stm32
make

5. Заливаем все на STM32F429 DISCO

Заливаем через ST-LINK утилиту — качаем отсюда — https://github.com/texane/stlink

Нужно залить Bootloader, Device Tree и сам kernel


NOTE: Device Tree позволяет конфигурировать оборудовaние во время загрузки при помощи специальных dts-файлов и мeнять установки без пересборки ядра.


st-flash --reset write afboot-stm32/test.bin 0x08000000 
st-flash --reset write linux/arch/arm/boot/dts/stm32f429-disco.dtb 0x08004000
st-flash --reset write linux/arch/arm/boot/xipImage 0x08008000

6. Проверяем загрузку Linux на STM32F429 DISCO:

Смотрим linux/arch/arm/boot/dts/stm32f429-disco.dts и определяем на какой USART выведен serial0. В моем случае на USART1:

serial0 = &usart1;

Подключаем к данному USART (USART1 это ножки PA9 PA10) переходник USART<->RS232 или USART<->USB-virtual-com-port, открываем в каком либо serial port терминале (например minicom) serial port этого переходника. Параметры — 115200-8n1.

Перезагружаем STM32F429 DISCO через кнопочку reset на плате и видим:

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.8.6 (alex@alex-N56VZ) (gcc version 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496] (GNU Tools for ARM Embedded Processo6
[    0.000000] CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
[    0.000000] CPU: unknown data cache, unknown instruction cache
[    0.000000] OF: fdt:Machine model: STMicroelectronics STM32F429i-DISCO board
[    0.000000] Built 1 zonelists in Zone order, mobility grouping off.  Total pages: 2032
[    0.000000] Kernel command line: root=/dev/ram rdinit=/linuxrc
[    0.000000] PID hash table entries: 32 (order: -5, 128 bytes)
[    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Memory: 7880K/8192K available (863K kernel code, 63K rwdata, 276K rodata, 56K init, 102K bss, 312K reserved, 0K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0x00000000 - 0x00001000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0x00000000 - 0xffffffff   (4095 MB)
[    0.000000]     lowmem  : 0x90000000 - 0x90800000   (   8 MB)
[    0.000000]       .text : 0x08008000 - 0x08124d7c   (1140 kB)
[    0.000000]       .init : 0x9000a000 - 0x9000d000   (  12 kB)
[    0.000000]       .data : 0x90008000 - 0x9001ac40   (  76 kB)
[    0.000000]        .bss : 0x9001ac40 - 0x90034574   ( 103 kB)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000]  Build-time adjustment of leaf fanout to 32.
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] clocksource: arm_system_timer: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 331816030 ns
[    0.000000] ARM System timer initialized as clocksource
[    0.000000] /soc/timer@40000c00: STM32 clockevent driver initialized (32 bits)
[    0.000000] sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 21474836475000000ns
[    0.010000] Calibrating delay loop... 118.68 BogoMIPS (lpj=593408)
[    0.100000] pid_max: default: 4096 minimum: 301
[    0.100000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.100000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.110000] devtmpfs: initialized
[    0.140000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.140000] pinctrl core: initialized pinctrl subsystem
[    0.210000] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
[    0.220000] stm32-dma 40026400.dma-controller: STM32 DMA driver  registered
[    0.220000] clocksource: Switched to clocksource arm_system_timer
[    0.400000] workingset: timestamp_bits=30 max_order=11 bucket_order=0
[    0.460000] io scheduler noop registered (default)
[    0.460000] stm32f429-pinctrl soc:pin-controller: GPIOA bank added
[    0.460000] stm32f429-pinctrl soc:pin-controller: GPIOB bank added
[    0.460000] stm32f429-pinctrl soc:pin-controller: GPIOC bank added
[    0.460000] stm32f429-pinctrl soc:pin-controller: GPIOD bank added
[    0.460000] stm32f429-pinctrl soc:pin-controller: GPIOE bank added
[    0.460000] stm32f429-pinctrl soc:pin-controller: GPIOF bank added
[    0.460000] stm32f429-pinctrl soc:pin-controller: GPIOG bank added
[    0.460000] stm32f429-pinctrl soc:pin-controller: GPIOH bank added
[    0.470000] stm32f429-pinctrl soc:pin-controller: GPIOI bank added
[    0.470000] stm32f429-pinctrl soc:pin-controller: GPIOJ bank added
[    0.480000] stm32f429-pinctrl soc:pin-controller: GPIOK bank added
[    0.480000] stm32f429-pinctrl soc:pin-controller: Pinctrl STM32 initialized
[    0.480000] STM32 USART driver initialized
[    0.480000] 40011000.serial: ttyS0 at MMIO 0x40011000 (irq = 17, base_baud = 5625000) is a stm32-usart
[    0.830000] console [ttyS0] enabled
[    0.850000] Freeing unused kernel memory: 12K (9000a000 - 9000d000)
[    0.860000] This architecture does not have kernel memory protection.

На этом все.

Также смотрим:

http://elinux.org/STM32
https://github.com/lag-linaro/stm32/blob/master/quickstart.sh
https://en.opensuse.org/openSUSE:ARM_Tech_Symposia_2014/STM32F429
https://github.com/jserv/stm32f429-linux-builder