openSUSE:ARM Tech Symposia 2014/STM32F429
As demonstration of openSUSE 13.2 development tools for ARM and on ARM, Andreas Färber presented a project from SUSE Hackweek Interstellar: Linux running on the STM32F4 microcontroller.
Hardware
The STM32F4 Discovery kit for STM32F429 was kindly provided by Rutronik.
- STM32F429ZIT6 microcontroller
- ARM Cortex-M4F at 180 MHz
- 2 MB of internal flash
- 256 KB of internal SRAM
- 8 MB of on-board SDRAM
New at ARM Tech Symposium
What was new about the demo at ARM Tech Symposium Europe is the kernel. It was originally based on v3.18-rc5, later rebased onto v3.18-rc6, and used the new Device Tree concept to describe the hardware.
The following minimal set of kernel drivers was implemented:
- USART3 earlyprintk support
- SysTick clock source
- RCC clock controller
- TIM2 clock events
- USART3 serial console
- LTDC framebuffer
Not implemented were, among others:
- GPIO controller (relying on bootloader)
- RCC reset controller (using ad-hoc reset code instead)
- DMA for serial
- DMA2D framebuffer acceleration
- LTDC initialization (relying on bootloader)
- RTC
- USB
The U-Boot bootloader was taken from here and only modified to load the kernel from a different flash address and to pass the device tree flash address to the kernel.
Updates
The genromfs package from home:a_faerber:arm was deleted, as it is available in Base:System already.
The latest kernel work rebased onto v3.19-rc1 is here:
- reset driver for RCC (WIP)
Initial U-Boot bootloader work is here, not yet fully building. Also see "[U-Boot] [PATCH v2] arm: build arch memset/memcpy in Thumb2 mode" on the U-Boot mailing list.
As alternative, a non-interactive custom bootloader has been made available. It uses less than 2 KB of flash, freeing some more space for kernel and device tree.
Details
Flash layout
| Start | End | Size | Used | Contents |
|---|---|---|---|---|
| 0x08000000 | 0x0801FFFF | 128 KB | 75048 B | U-Boot bootloader |
| 0x08020000 | 0x08020FFF | 4096 B | 3017 B | Flat device tree |
| 0x08021000 | 0x0811FFFF | 1 MB minus 4096 B | 1025908 B | Linux kernel (XIP) |
| 0x08120000 | 0x081FFFFF | 1 MB minus 128 KB | 293888 B | ROMFS filesystem with busybox |
Note: Due to flash erase size restrictions, the kernel and device tree needed to be flashed together.
Commands
openocd -f board/stm32f429discovery.cfg \
-c "init" \
-c "reset init" \
-c "flash probe 0" \
-c "flash info 0" \
-c "flash write_image erase dtb+uImage.bin 0x08020000" \
-c "reset run" \
-c "shutdown"
Tools
Compiler for kernel: gcc 4.8-6.1 / gcc48 4.8.3+r212056-5.1 from openSUSE Factory
$ gcc --version gcc (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064] Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Assembler for kernel: binutils 2.24-5.1 from openSUSE Factory
$ as --version GNU assembler (GNU Binutils; openSUSE Factory) 2.24.0.20140403-5 Copyright 2013 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or later. This program has absolutely no warranty. This assembler was configured for a target of `armv7hl-suse-linux-gnueabi'.
Flasher and on-chip debugger: openocd 0.8.0-4.1 from openSUSE Factory
$ openocd --version Open On-Chip Debugger 0.8.0 (2014-10-11-17:40) Licensed under GNU GPL v2 For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html
Debugger: gdb 7.8-4.1 from openSUSE Factory
$ gdb --version GNU gdb (GDB; openSUSE Factory) 7.8 Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "armv7hl-suse-linux". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://bugs.opensuse.org/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word".
File system creation: genromfs 0.5.2-95.1.2 from openSUSE 13.2 (on x86_64)
$ genromfs -h genromfs 0.5.2 Usage: genromfs [OPTIONS] -f IMAGE Create a romfs filesystem image from a directory -f IMAGE Output the image into this file -d DIRECTORY Use this directory as source -v (Too) verbose operation -V VOLUME Use the specified volume name -a ALIGN Align regular file data to ALIGN bytes -A ALIGN,PATTERN Align all objects matching pattern to at least ALIGN bytes -x PATTERN Exclude all objects matching pattern -h Show this help
Output
U-Boot 2010.03-00003-g934021a-dirty (Nov 29 2014 - 02:04:13)
CPU : STM32F4 (Cortex-M4)
Freqs: SYSCLK=180MHz,HCLK=180MHz,PCLK1=45MHz,PCLK2=90MHz
Board: STM32F429I-DISCOVERY board,Rev 1.0
DRAM: 8 MB
Using default environment
Hit any key to stop autoboot: 0
## Booting kernel from Legacy Image at 08021000 ...
Image Name: Linux-3.18
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1025844 Bytes = 1001.8 kB
Load Address: 08021040
Entry Point: 08021041
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
Booting Linux on physical CPU 0x0
Linux version 3.18.0-rc6-00016-g4c00142-dirty (andreas@droide) (gcc version 4.8.3 20140627 [gcc-4_8-branch revision 212064] (SUSE Linux) ) #165 Mon Dec 1 04:27:08 CET 2014
CPU: ARMv7-M [410fc241] revision 1 (ARMv7M), cr=00000000
CPU: unknown data cache, unknown instruction cache
Machine model: ST STM32F4 Discovery kit for STM32F429
bootconsole [earlycon0] enabled
debug: ignoring loglevel setting.
On node 0 totalpages: 2048
free_area_init_node: node 0, pgdat 9001fb60, node_mem_map 906f0000
Normal zone: 16 pages used for memmap
Normal zone: 0 pages reserved
Normal zone: 2048 pages, LIFO batch:0
pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
pcpu-alloc: [0] 0
Built 1 zonelists in Zone order, mobility grouping off. Total pages: 2032
Kernel command line: console=ttystm3,115200n8 earlyprintk ignore_loglevel debug clk_ignore_unused ihash_entries=64 dhash_entries=64 uclinux.physaddr=0x08120000 root=/dev/mtdblock0 rdinit=/sbin/init
PID hash table entries: 32 (order: -5, 128 bytes)
Dentry cache hash table entries: 64 (order: -4, 256 bytes)
Inode-cache hash table entries: 64 (order: -4, 256 bytes)
Memory: 6904K/8192K available (758K kernel code, 76K rwdata, 104K rodata, 60K init, 55K bss, 1288K reserved)
Virtual kernel memory layout:
vector : 0x00000000 - 0x00001000 ( 4 kB)
fixmap : 0xffc00000 - 0xffe00000 (2048 kB)
vmalloc : 0x00000000 - 0xffffffff (4095 MB)
lowmem : 0x90000000 - 0x90800000 ( 8 MB)
.text : 0x08021040 - 0x080f8928 ( 863 kB)
.init : 0x9000a000 - 0x9000f000 ( 20 kB)
.data : 0x90008000 - 0x90020200 ( 97 kB)
.bss : 0x90020200 - 0x9002debc ( 56 kB)
NR_IRQS:16 nr_irqs:16 16
rcc @ 0x40023800
clk HSI @ 16000000
clk HSE @ 8000000
clk PLLSRC @ 8000000
clk PLL @ 360000000
clk PLLCLK @ 180000000
clk PLL48CK @ 51428572
clk SYSCLK @ 180000000
clk AHB @ 180000000
clk APB1 @ 45000000
clk TIM2 @ 45000000
clk TIM3 @ 45000000
clk TIM4 @ 45000000
clk TIM5 @ 45000000
clk USART3 @ 45000000
clk APB2 @ 90000000
timer @ 0x40000000 (90000000)
before TIMx CR1 (40000000)
before TIMx CR1 (40000000)
systick @ 0xe000e010 (22500000)
sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 21474836480000000ns
Console: colour dummy device 80x30
Calibrating delay loop... 118.68 BogoMIPS (lpj=593408)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
devtmpfs: initialized
Switched to clocksource cortex-m3-systick
futex hash table entries: 256 (order: -1, 3072 bytes)
romfs: ROMFS MTD (C) 2007 Red Hat, Inc.
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered
io scheduler deadline registered (default)
Console: switching to colour frame buffer device 30x40
stm32_usart 40004800.uart: ttystm3 at MMIO 0x40004800 (irq = 17, base_baud = 0) is a stm32_usart
console [ttystm3] enabled
bootconsole [earlycon0] disabled
brd: module loaded
uclinux[mtd]: probe address=0x8120000 size=0x48000
Creating 1 MTD partitions on "rom":
0x000000000000-0x000000048000 : "ROMfs"
clk: Not disabling unused clocks
VFS: Mounted root (romfs filesystem) readonly on device 31:0.
devtmpfs: mounted
Freeing unused kernel memory: 20K (9000a000 - 9000f000)
starting pid 23, tty '/dev/ttystm3': '/bin/login -f root'
Welcome to
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ \| | | |\ \/ /
| |_| | |__| || | | | | |_| |/ \
| ___\____|_||_|_| |_|\____|\_/\_/
| |
|_|
For further information check:
http://www.uclinux.org/
Jan 1 00:00:00 login[23]: root login on 'ttystm3'
~ #
~ # cat /proc/cpuinfo processor : 0 model name : ARMv7-M rev 1 (v7ml) Features : half thumb fastmult idivt CPU implementer : 0x41 CPU architecture: 7M CPU variant : 0x0 CPU part : 0xc24 CPU revision : 1 Hardware : STM32 (Device Tree Support) Revision : 0000 Serial : 0000000000000000
~ # cat /proc/meminfo MemTotal: 6924 kB MemFree: 3752 kB MemAvailable: 3664 kB Buffers: 264 kB Cached: 296 kB SwapCached: 0 kB Active: 508 kB Inactive: 32 kB Active(anon): 0 kB Inactive(anon): 0 kB Active(file): 508 kB Inactive(file): 32 kB Unevictable: 0 kB Mlocked: 0 kB MmapCopy: 824 kB SwapTotal: 0 kB SwapFree: 0 kB Dirty: 0 kB Writeback: 0 kB AnonPages: 0 kB Mapped: 0 kB Shmem: 0 kB Slab: 612 kB SReclaimable: 100 kB SUnreclaim: 512 kB KernelStack: 136 kB PageTables: 0 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 3460 kB Committed_AS: 0 kB VmallocTotal: 0 kB VmallocUsed: 0 kB VmallocChunk: 0 kB
~ # cat /proc/iomem 90000000-907fffff : System RAM 90008000-9002debb : Kernel data
~ # busybox
BusyBox v1.22.1 (2014-11-29 03:23:08 CET) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
Usage: busybox [function [arguments]...]
or: busybox --list
or: function [arguments]...
BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable. Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as.
Currently defined functions:
bash, cat, chgrp, chmod, chown, chroot, clear, cp, date, dd, df, dmesg,
du, fbset, free, freeramdisk, fuser, getty, halt, hd, head, hexdump,
hush, init, insmod, iostat, kill, killall, killall5, less, ln, login,
ls, lsmod, md5sum, mkdir, mkdosfs, mke2fs, mkfs.ext2, mkfs.vfat, mknod,
modinfo, more, mount, mv, passwd, pgrep, pidof, pkill, poweroff, ps,
pstree, pwd, reboot, renice, reset, rm, rmdir, rmmod, sh, sleep, stat,
sync, sysctl, tail, time, top, umount, uname, uptime, vi, watch