Try   HackMD

2025q1 Homework1 (ideas)

contributed by <kk908676>

作業書寫規範:

  • 無論標題和內文中,中文和英文字元之間要有空白字元 (對排版和文字搜尋有利)
  • 文字訊息 (尤其是程式執行結果) 請避免用圖片來表示,否則不好搜尋和分類
  • 共筆書寫請考慮到日後協作,避免過多的個人色彩,用詞儘量中性
  • 不要在筆記內加入 [TOC] : 筆記左上方已有 Table of Contents (TOC) 功能,不需要畫蛇添足
  • 不要變更預設的 CSS 也不要加入任何佈景主題: 這是「開發紀錄」,用於評分和接受同儕的檢閱
  • 在筆記中貼入程式碼時,避免非必要的行號,也就是該手動將 c=cpp= 變更為 ccpp。行號只在後續討論明確需要行號時,才要出現,否則維持精簡的展現。可留意「你所不知道的 C 語言: linked list 和非連續記憶體」裡頭程式碼展現的方式
  • HackMD 不是讓你張貼完整程式碼的地方,GitHub 才是!因此你在開發紀錄只該列出關鍵程式碼 (善用 diff 標示),可附上對應 GitHub commit 的超連結,列出程式碼是為了「檢討」和「便於他人參與討論」
  • 留意科技詞彙的使用,請參見「資訊科技詞彙翻譯」及「詞彙對照表
  • 不要濫用 :::info, :::success, :::warning 等標示,儘量用清晰的文字書寫。:::danger 則僅限授課教師作為批注使用
  • 避免過多的中英文混用,已有明確翻譯詞彙者,例如「鏈結串列」(linked list) 和「佇列」(queue),就使用該中文詞彙,英文則留給變數名稱、人名,或者缺乏通用翻譯詞彙的場景
  • 在中文敘述中,使用全形標點符號,例如該用「,」,而非 ","。注意書名號的使用,即 ,非「小於」和「大於」符號
  • 避免使用不必要的 emoji 字元

軟硬體整合

參考 STM32F407 的 Reference Manual

  • ARM Cross Compile Toolchain:
    sudo apt-get install arm-linux-gnueabi-gcc
    which arm-linux-gnueabi-gcc
    export PATH=/usr/bin:$PATH
    source ~/.bashrc
-   sudo apt-get install arm-linux-gnueabi-gcc
+   sudo apt install gcc-arm-linux-gnueabi
  • STLINK Tools: stlink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics.
    cd ~
    git clone https://github.com/texane/stlink.git
    cd ./stlink
    sudo apt-get install libusb-1.0-0-dev
    sudo apt-get -y install cmake
    sudo apt-get install libstlink1
    make
    cd build/Release
    sudo make install       

To verify the successful installation

$ st-flash 
invalid command line
usage: st-flash [options] read [file] [addr] [size]
       st-flash [options] write <file> [addr] [size]
       st-flash [options] write <value>
       st-flash [options] erase <addr> <size>
       st-flash [options] reset

options:
  --freq <kHz>           Frequency of JTAG/SWD, default 1800kHz.
  --serial <serial>      STLink device to use.
  --connect-under-reset  Pull reset low while connecting.
  --hot-plug             Connect without reset.
  --reset                Reset after writing.
  --format {binary|ihex} Format of file to read or write. When writing
                         with ihex specifying addr is not needed.
  --flash <size>         Specify size of flash, e.g. 128k, 1M.
  --area <area>          Area to access, one of: main(default), system,
                         otp, option, option_boot_add, optcr, optcr1.
  --opt                  Skip writing empty bytes at the tail end.
  --debug                Output extra debug information.
  --version              Print version information.
  --help                 Show this help.

examples:
  st-flash --area=option read [file] [size]
  st-flash --area=option write 0xXXXXXXXX
  st-flash --area=option_boot_add read
  st-flash --area=option_boot_add write 0xXXXXXXXX
  st-flash --area=optcr read
  st-flash --area=optcr write 0xXXXXXXXX
  st-flash --area=optcr1 read
  st-flash --area=optcr1 write 0xXXXXXXXX
  st-flash --area=otp read <file>
  st-flash --area=otp write <file> 0xXXXXXXXX

這時候可能會發現有這麼一段錯誤訊息

$ st-info --probe
2025-03-11T21:19:20 ERROR usb.c: Could not open USB device 0x0483:0x374b, access error.

大多數發行版不允許存取 USB 裝置,從官方文件中我們可以解決這問題

Set device access permissions and the role of udev
By default most distributions don't allow access to USB devices. In this context udev rules, which create devices nodes, are necessary to run the tools without root permissions. To achieve this you need to ensure that the group plugdev exists and the user who is trying to access these devices is a member of this group.

Within the sourcefolder of the project, these rules are located in the subdirectory config/udev/rules.d and are automatically installed along with sudo make install on linux. Afterwards it may be necessary to reload the udev rules:

$ sudo cp -a config/udev/rules.d/* /lib/udev/rules.d/
$ sudo udevadm control --reload-rules
$ sudo udevadm trigger

udev will now create device node files, e.g. /dev/stlinkv3_XX, /dev/stlinkv2_XX, /dev/stlinkv1_XX.

如此一來就順利讀取到我們想要的開發板了

$ st-info --probe
Found 1 stlink programmers
  version:    V2J37S26
  serial:     066CFF525377524867015421
  flash:      1048576 (pagesize: 16384)
  sram:       196608
  chipid:     0x413
  dev-type:   STM32F4x5_F4x7

燒錄測試

  • blink.c
#define RCC_AHB1_PERI_ENBLR_ADDR (*((volatile unsigned long *) (0x40023800 + 0x30)))
#define GPIO_D_PORTMODE (*((volatile unsigned long *) 0x40020C00))
#define GPIO_D_OUTPUT_TYPE (*((volatile unsigned long *) (0x40020C00 + 0x4)))
#define GPIO_D_PUPD (*((volatile unsigned long *) (0x40020C00 + 0xC)))
#define GPIO_D_PORT_SETRESET (*((volatile unsigned long *) (0x40020C00 + 0x18)))

asm(".word 0x20001000");
asm(".word main ");

int main()
{
    int i;

    RCC_AHB1_PERI_ENBLR_ADDR |= (0x00000001 << 3); /*Enalbe GPIO D clock*/

    GPIO_D_PORTMODE |= (0x00000001 << 28 | 0x00000001 << 30); /* Set PD14 PD15 mode to GPIO */
    GPIO_D_PORTMODE &= ~(0x00000001 << 29 | 0x00000001 << 31);

    GPIO_D_OUTPUT_TYPE &= ~(0x00000001 << 13 | 0x00000001 << 14); /*Set PD14 PD15 to push-pull*/
    GPIO_D_PUPD |= (0x00000001 << 27 | 0x00000001 << 29); /*Set PD14 PD15 to pull-down*/

    while (1) {
        GPIO_D_PORT_SETRESET = 0x40008000; /*PD14 off, PD15 on*/
        for (i = 0; i < 100000; i++)
            ;
        GPIO_D_PORT_SETRESET = 0x80004000; /*PD15 off, PD14 on*/
        for (i = 0; i < 100000; i++)
            ;
    }

    return 0;
}
  • Makefile
CROSS_COMPILE ?= arm-none-eabi-

.PHONY: all

all: blink.bin

blink.o: blink.c
        $(CROSS_COMPILE)gcc -mcpu=cortex-m4 -mthumb -nostartfiles -c blink.c -o blink.o

blink.out: blink.o blink.ld
        $(CROSS_COMPILE)ld -T blink.ld -o blink.out blink.o             

blink.bin: blink.out
        $(CROSS_COMPILE)objcopy -j .text -O binary blink.out blink.bin

clean:
        rm -rf *.o *.out *.bin
  • blink.ld
SECTIONS
{
    . = 0x0;
    .text :
    {
        *(.text)
    }
}

編譯完後會產生 blink.outblink.bin ,將 blink.bin 燒進 flash

$ st-flash --reset write blink.bin 0x08000000
st-flash 1.8.0
2025-03-13T16:45:58 INFO common_legacy.c: STM32F4x5_F4x7: 192 KiB SRAM, 1024 KiB flash in at least 16 KiB pages.
file blink.bin md5 checksum: 4bb06e5d434b414b47c0f421f60e795, stlink checksum: 0x00002cae
2025-03-13T16:45:58 INFO common_flash.c: Attempting to write 160 (0xa0) bytes to stm32 address: 134217728 (0x8000000)
2025-03-13T16:45:58 INFO flash_loader.c: Starting Flash write for F2/F4/F7/L4
2025-03-13T16:45:58 INFO flash_loader.c: Successfully loaded flash loader in sram
2025-03-13T16:45:58 INFO flash_loader.c: Clear DFSR
2025-03-13T16:45:58 INFO flash_loader.c: Clear CFSR
2025-03-13T16:45:58 INFO flash_loader.c: Clear HFSR
2025-03-13T16:45:58 INFO flash_loader.c: enabling 32-bit flash writes
2025-03-13T16:45:58 INFO common_flash.c: Starting verification of write complete
2025-03-13T16:45:58 INFO common_flash.c: Flash written and verified! jolly good!

燒進 flash 可能會遇到寫入保護( Write Protection )鎖定 , 因此要先解除保護:

$ st-flash erase

USART Connection

  • The STM32F429 Discovery is equipped with various USARTs. USART stands for Universal Synchronous Asynchronous Receiver Transmitter. The USARTs on the STM32F429 support a wide range of serial protocols, the usual asynchronous ones, plus things like IrDA, SPI etc. Since the STM32 works on 3.3V levels, a level shifting component is needed to connect the USART of the STM32F429 to a PC serial port.
STM32 PIN VCP
PA9 USART1_TX
PA10 USART1_RX

USB to TTL 接線:

  • PA9 > RXD
  • PA10 > TXD
  • GND > GND

image

$ sudo dmesg | grep tty
[    0.222738] printk: legacy console [tty0] enabled
[18797.223501] usb 1-11: pl2303 converter now attached to ttyUSB0

$ sudo chmod 666 /dev/ttyUSB0

安裝 kermit

$ sudo apt-get install ckermit

可以從 官方文件中 得知 Baud Rate 預設為 115200UART number 預設為 1

config BAUDRATE
	int "Default baudrate"
	default 115200
	help
	  Select a default baudrate, where "default" has a driver-specific
	  meaning of either setting the baudrate for the early debug UART
	  in the SPL stage (most drivers) or for choosing a default baudrate
	  in the absence of an environment setting (serial_mxc.c).


config CONS_INDEX
	int "UART used for console"
	depends on SPECIFY_CONSOLE_INDEX
	range 0 6
	default 1
	help
	  Set this to match the UART number of the serial console.    

設定與開發板溝通的基本參數
輸入 vi ~/.kermit

set line /dev/ttyUSB0
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type binary
set file name literal
set receive packet-length 1000
set send packet-length 1000
set window 5

接著輸入 kermit 就可以看到

$ kermit
C-Kermit 10.0 pre-Beta.11, 06 Feb 2024, for Linux+SSL (64-bit)
 Copyright (C) 1985, 2024,
  Trustees of Columbia University in the City of New York.
  Open Source 3-clause BSD license since 2011.
Type ? or HELP for help.
(~/Desktop/) C-Kermit>

因為剛剛已經設定好了一些基本的參數,這時只要在命令列輸入 c 且按下開發板上的 RESET 就可以看到

(~/Desktop/) C-Kermit>c
Connecting to /dev/ttyUSB1, speed 115200
 Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------


U-Boot 2025.04-rc4-00008-g15d6518c942f (Mar 17 2025 - 16:28:20 +0800)

DRAM:  8 MiB
Core:  73 devices, 11 uclasses, devicetree: separate
Flash: 2 MiB
Loading Environment from Flash... *** Warning - bad CRC, using default environment

In:    serial@40011000
Out:   serial@40011000
Err:   serial@40011000
U-Boot > help
?         - alias for 'help'
base      - print or set address offset
bdinfo    - print Board Info structure
boot      - boot default, i.e., run 'bootcmd'
bootd     - boot default, i.e., run 'bootcmd'
bootelf   - Boot from an ELF image in memory
bootm     - boot application image from memory
bootvx    - Boot vxWorks from an ELF image
cmp       - memory compare
coninfo   - print console devices and information
cp        - memory copy
crc32     - checksum calculation
dm        - Driver model low level access
echo      - echo args to console
editenv   - edit environment variable
env       - environment handling commands
erase     - erase FLASH memory
exit      - exit script
false     - do nothing, unsuccessfully
fdt       - flattened device tree utility commands
flinfo    - print FLASH memory information
go        - start application at address 'addr'
help      - print command description/usage
iminfo    - print header information for application image
imls      - list all images found in flash
imxtract  - extract a part of a multi-image
itest     - return true/false on integer compare
loadb     - load binary file over serial line (kermit mode)
loads     - load S-Record file over serial line
loadx     - load binary file over serial line (xmodem mode)
loady     - load binary file over serial line (ymodem mode)
loop      - infinite loop on address range
md        - memory display
mm        - memory modify (auto-incrementing address)
mw        - memory write (fill)
nm        - memory modify (constant address)
panic     - Panic with optional message
pinmux    - show pin-controller muxing
printenv  - print environment variables
protect   - enable or disable FLASH write protection
reset     - Perform RESET of the CPU
run       - run commands in an environment variable
saveenv   - save environment variables to persistent storage
setenv    - set environment variables
showvar   - print local hushshell variables
sleep     - delay execution for some time
source    - run script from memory
test      - minimal test like /bin/sh
timer     - access the system timer
true      - do nothing, successfully
version   - print monitor, compiler and linker version
U-Boot >

version -> 顯示目前 U-Boot 版本

U-Boot > version
U-Boot 2024.07-rc3-00020-gea722aa5eb (Jun 09 2024 - 22:25:14 +0800)

bdinfo -> 顯示目前板子資訊

U-Boot > bdinfo
boot_params = 0x00000000
DRAM bank   = 0x00000000
-> start    = 0x90000000
-> size     = 0x00800000
flashstart  = 0x08000000
flashsize   = 0x00200000
flashoffset = 0x000241b8
baudrate    = 115200 bps
relocaddr   = 0x907ca000
reloc off   = 0x887ca000
Build       = 32-bit
fdt_blob    = 0x905c2cb0
new_fdt     = 0x905c2cb0
fdt_size    = 0x00005220
lmb_dump_all:
 memory.cnt = 0x1 / max = 0x10
 memory[0]      [0x90000000-0x907fffff], 0x00800000 bytes flags: 0
 reserved.cnt = 0x1 / max = 0x10
 reserved[0]    [0x905be9a8-0x907fffff], 0x00241658 bytes flags: 0
devicetree  = separate
arch_number = 0x00000000
TLB addr    = 0x907f0000
irq_sp      = 0x905c2ca0
sp start    = 0x905c2c90
Early malloc usage: f40 / 2000

Kernel 核心編譯

Linux-6.14.0

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

詳細內容請參閱核心程式碼目錄下的文件 ./Documentation/kbuild/kconfig-language.rst

使用預設 .config

cd linux/
make ARCH=arm stm32_defconfig

用來對剛剛已經產生的 .config 再做一些調整

make ARCH=arm menuconfig

先檢查是否有安裝 libncurses5-dev

sudo apt-get install libncurses5-dev

之後可以看到以下畫面
Screenshot from 2025-03-22 17-15-41

Initramfs

他是在啟動階段被 Linux 核心呼叫的臨時檔案系統,用於根目錄被掛載之前的準備工作, 這裡用 Embedded Linux Wiki 所提供的 Stm32 mini rootfs.cpio.bz2

下載之後先解壓縮成 cpio 檔 :

bzip2 -d Stm32_mini_rootfs.cpio.bz2

接下來創建資 rootfs 用以之後 Linux 啟動時的臨時檔案系統:

mkdir rootfs

將下載的文件解壓縮到 rootfs

cpio -idmv < ../Stm32_mini_rootfs.cpio

確認 dev 中是否有
null : 創建系統控制台設備,允許內核和用戶程序輸出錯誤和信息
tty0 : 創建丟棄數據的設備
console : 創建虛擬終端設備

如果沒有就需要手動加入

sudo mknod console c 5 1
 
sudo mknod null c 1 3
 
sudo mknod tty0 c 204 64

最後在 rootfs 新增 init 文件, 用來手動掛載 /dev 目錄並初始化設備節點,然後將標準輸入、輸出和錯誤輸出重定向到控制台,最後執行系統的初始化程序 /sbin/init

#!/bin/sh
# devtmpfs does not get automounted for initramfs
/bin/mount -t devtmpfs devtmpfs /dev
exec 0</dev/console
exec 1>/dev/console
exec 2>/dev/console
exec /sbin/init $

rootfs 準備好了之後要在 menuconfig 設定根文件系統的來源位置, 這樣內核可以在啟動時加載它作為初始根文件系統

位置 : General setup -> Initial RAM filesystem and RAM disk (initramfs/initrd) support

[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support           
(/home/an/Downloads/rootfs) Initramfs source file(s) 

Screenshot from 2025-03-22 19-42-08

編譯核心 :

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-  -j4

編譯 Linux 內核並生成可啟動的內核映像 uImage
(你會在 linux/arch/arm/boot/ 看到 uImage , uImageU-Boot 用來引導內核的映像格式)

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage LOADADDR=0x90008000 -j4

編譯設備樹二進制檔案 :
(你會在 linux/arch/arm/boot/dts/st/ 看到 stm32f429-disco.dtb 設備樹描述了硬體設備的結構,並告訴內核如何與這些設備進行交互,因此在編譯內核時需要生成對應的設備樹檔案,這樣內核才能正確識別並配置硬體設備)

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dtbs

等待這幾個核心檔案都產生之後, 接下來就是放入到 SDRAM 之後內核才能做後續相對應的硬體和設備的初始化

從剛剛 U-Boot 所產生的資訊來看, SDRAM 的起始位置是 0x90000000 大小是 8MB

U-Boot > bdinfo
boot_params = 0x00000000
DRAM bank   = 0x00000000
-> start    = 0x90000000
-> size     = 0x00800000
flashstart  = 0x08000000
flashsize   = 0x00200000
flashoffset = 0x000241b8
baudrate    = 115200 bps
relocaddr   = 0x907ca000
reloc off   = 0x887ca000
Build       = 32-bit
fdt_blob    = 0x905c2cb0
new_fdt     = 0x905c2cb0
fdt_size    = 0x00005220

因此我們使用 loadbuImage 傳入位置 0x90100000

U-Boot 2025.04-rc4-00008-g15d6518c942f (Mar 17 2025 - 16:28:20 +0800)

DRAM:  8 MiB
Core:  73 devices, 11 uclasses, devicetree: separate
Flash: 2 MiB
Loading Environment from Flash... OK
In:    serial@40011000
Out:   serial@40011000
Err:   serial@40011000
U-Boot > <INTERRUPT>
U-Boot > <INTERRUPT>
U-Boot > loadb 90100000
## Ready for binary (kermit) download to 0x90100000 at 115200 bps...

可以看到在等待檔案, 接著輸入 Ctrl + \ + c 來回到指令模式並傳送 uImage ,待傳完之後打 c 回到 U-Boot

(Back at an-Pro-E500-G6-WS720T)
----------------------------------------------------
(~/Desktop/) C-Kermit>send linux/arch/arm/boot/uImage
(~/Desktop/) C-Kermit>c
Connecting to /dev/ttyUSB1, speed 115200
 Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------
## Total Size      = 0x001b48d8 = 1788120 Bytes
## Start Addr      = 0x90100000

接下來將 dtb 傳入位置 0x90500000

U-Boot > loadb 90500000
## Ready for binary (kermit) download to 0x90500000 at 115200 bps...

(Back at an-Pro-E500-G6-WS720T)
----------------------------------------------------
(~/Desktop/) C-Kermit>send linux/arch/arm/boot/dts/st/stm32f429-disco.dtb
(~/Desktop/) C-Kermit>c           
Connecting to /dev/ttyUSB1, speed 115200
 Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------
## Total Size      = 0x00004c90 = 19600 Bytes
## Start Addr      = 0x90500000

最後在 U-Boot 設定內核的啟動參數

U-Boot > setenv bootargs 'console=ttySTM0,115200 root=/dev/ram earlyprintk'
U-Boot > bootm 90100000 - 90500000

就可以看到成功啟動了 linux

## Booting kernel from Legacy Image at 90100000 ...
   Image Name:   Linux-6.14.0-rc7-00179-gb3ee1e46
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1788056 Bytes = 1.7 MiB
   Load Address: 90008000
   Entry Point:  90008001
   Verifying Checksum ... OK
## Flattened Device Tree blob at 90500000
   Booting using the fdt blob at 0x90500000
Working FDT set to 90500000
   Loading Kernel Image to 90008000
   Loading Device Tree to 905b7000, end 905bec8f ... OK
Working FDT set to 905b7000

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 6.14.0-rc7-00179-gb3ee1e460951-dirty (an@an-Pro-E500-G6-WS720T) (arm-linux-gnueabi-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #18 PREEMPT Sat Mar 22 15:48:05 CST 2025
[    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] printk: legacy bootconsole [earlycon0] enabled
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000090000000-0x00000000907fffff]
[    0.000000] OF: reserved mem: Reserved memory: No reserved-memory node in the DT
[    0.000000] Kernel command line: console=ttySTM0,115200 root=/dev/ram earlyprintk
[    0.000000] printk: log buffer data + meta data: 65536 + 204800 = 270336 bytes
[    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2048
[    0.000000] mem auto-init: stack:all(zero), heap alloc:off, heap free:off
[    0.000000] SLUB: HWalign=8, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000] rcu: 	RCU event tracing is enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[    0.000000] /soc/interrupt-controller@40013c00: bank0
[    0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[    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.000036] sched_clock: 32 bits at 90MHz, resolution 11ns, wraps every 23860929530ns
[    0.009485] timers@40000c00: STM32 sched_clock registered
[    0.016161] Switching to timer-based delay loop, resolution 11ns
[    0.023345] timers@40000c00: STM32 delay timer registered
[    0.029965] clocksource: timers@40000c00: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 21236227187 ns
[    0.041948] /soc/timers@40000c00: STM32 clockevent driver initialized (32 bits)
[    0.058845] Calibrating delay loop (skipped), value calculated using timer frequency.. 180.00 BogoMIPS (lpj=900000)
[    0.071494] pid_max: default: 4096 minimum: 301
[    0.080117] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.089280] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.157293] rcu: Hierarchical SRCU implementation.
[    0.163581] rcu: 	Max phase no-delay instances is 1000.
[    0.188171] Memory: 4588K/8192K available (1677K kernel code, 272K rwdata, 628K rodata, 240K init, 102K bss, 3240K reserved, 0K cma-reserved)
[    0.209267] devtmpfs: initialized
[    0.462273] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.474441] pinctrl core: initialized pinctrl subsystem
[    0.756757] /soc/spi@40015000/display@1: Fixed dependency cycle(s) with /soc/display-controller@40016800
[    0.769703] /soc/display-controller@40016800: Fixed dependency cycle(s) with /soc/spi@40015000/display@1
[    0.830969] /soc/spi@40015000/display@1: Fixed dependency cycle(s) with /soc/display-controller@40016800
[    0.853089] /soc/spi@40015000/display@1: Fixed dependency cycle(s) with /soc/display-controller@40016800
[    0.869242] /soc/display-controller@40016800: Fixed dependency cycle(s) with /soc/spi@40015000/display@1
[    0.956606] stm32f429-pinctrl soc:pinctrl@40020000: GPIOA bank added
[    0.976370] stm32f429-pinctrl soc:pinctrl@40020000: GPIOB bank added
[    1.000595] stm32f429-pinctrl soc:pinctrl@40020000: GPIOC bank added
[    1.025950] stm32f429-pinctrl soc:pinctrl@40020000: GPIOD bank added
[    1.048708] stm32f429-pinctrl soc:pinctrl@40020000: GPIOE bank added
[    1.072381] stm32f429-pinctrl soc:pinctrl@40020000: GPIOF bank added
[    1.097161] stm32f429-pinctrl soc:pinctrl@40020000: GPIOG bank added
[    1.123180] stm32f429-pinctrl soc:pinctrl@40020000: GPIOH bank added
[    1.149769] stm32f429-pinctrl soc:pinctrl@40020000: GPIOI bank added
[    1.177386] stm32f429-pinctrl soc:pinctrl@40020000: GPIOJ bank added
[    1.200420] stm32f429-pinctrl soc:pinctrl@40020000: GPIOK bank added
[    1.209116] stm32f429-pinctrl soc:pinctrl@40020000: Pinctrl STM32 initialized
[    1.326514] stm32-dma 40026000.dma-controller: STM32 DMA driver registered
[    1.380118] stm32-dma 40026400.dma-controller: STM32 DMA driver registered
[    1.400838] vcc5v-otg-regulator enforce active low on GPIO handle
[    1.435452] clocksource: Switched to clocksource timers@40000c00
[    1.544632] workingset: timestamp_bits=30 max_order=11 bucket_order=0
[    1.559542] io scheduler mq-deadline registered
[    1.565121] io scheduler kyber registered
[    1.640383] io scheduler bfq registered
[    2.412772] STM32 USART driver initialized
[    2.454646] 40011000.serial: ttySTM0 at MMIO 0x40011000 (irq = 47, base_baud = 5625000) is a stm32-usart
[    2.487278] printk: legacy console [ttySTM0] enabled
[    2.487278] printk: legacy console [ttySTM0] enabled
[    2.514769] printk: legacy bootconsole [earlycon0] disabled
[    2.514769] printk: legacy bootconsole [earlycon0] disabled
[    2.578654] stm32_rtc 40002800.rtc: registered as rtc0
[    2.586152] stm32_rtc 40002800.rtc: setting system clock to 2000-01-01T02:29:39 UTC (946693779)
[    2.601124] stm32_rtc 40002800.rtc: Date/Time must be initialized
[    2.615053] i2c_dev: i2c /dev entries driver
[    2.652100] stmpe-i2c 0-0041: stmpe811 detected, chip id: 0x811
[    2.701109] stm32f4-i2c 40005c00.i2c: STM32F4 I2C driver registered
[    3.156715] input: gpio-keys as /devices/platform/gpio-keys/input/input0
[    3.188285] clk: Disabling unused clocks
[    3.228156] Freeing unused kernel image (initmem) memory: 240K
[    3.235916] This architecture does not have kernel memory protection.
[    3.243884] Run /init as init process
[    3.250807] Failed to execute /init (error -13)
[    3.257230] Run /sbin/init as init process
/ # ls
bin      dev      etc      init     linuxrc  proc     sbin     sys      usr