edit SideBar

Main / Embstuff


Running valgrind on your embedded machine may be a little tricky because of toolchain and kernel version concerns and the like. But there are other ways to check your program for memory issues:

  • Code analysis on usage of new/delete, malloc/free
  • cat /proc/meminfo, free, top

Bootloader link

Boot time notes

For faster boot, your bootloader needs to enable caches. Using NAND or SD/MMC require more SW overhead, but may be faster overall. Typical Linux boot sequence:

--- (kernel)
Hardware Init
Core Init
Calibration loop (jiffy timer)
Memory Init
Driver Init
Bus Probing
--- (rootfs)
Filesystem Init
UBI scan
rootfs Mount
--- (user)
Userland Init (systemd)
Subsystem Init

The bootloader uses a very small amount of boot time. Kernel might be 25%, but bulk is the userspace time. This includes system init scripts that engage kernel services.

Other tips: size matters; consider using decompressed kernel; configure drivers as modules; consider deferred initcall patch (move to userspace); execute in place out of flash; limit console prints; pre-config or eliminate udev; consider RTC_nosync; cache systemd config; reduce rootfs size; avoid discovery/probe code; consider using DMA for bootloader; consider UBI filesystem (next gen of JFFS2); avoid initramfs and use a preloading FS instead; consider a tiny kernel kexec to full kernel.

For userspace: use busybox; use native code instead of scripts; customize useland init with init=myinit; eliminate wasteful steps in given startup scripts; run scripts in parallel; use SystemD instead of SysV; prelink to reduce dynamic linking time;

Root File System

The RFS and kernel are related, but separate entities that can change independently. The RFS must be present for the kernel to start successfully. It can be attached to the kernel loaded into memory. Other file systems are implemented usually as kernel modules compiled in directly.

Initramfs sets up an initial root FS and init program in kernel's cache, as opposed to initrd which uses a ramdisk. It is created as part of the kernel build process. Set the location with CONFIG_INITRAMFS_SOURCE. At boot time, the kernel extracts a cpio format archive into a ramfs filesystem, called rootfs. When this archive isn’t present, an empty rootfs is created. The kernel looks at the filesystem for an init, and runs it if it exists.

How do I upgrade the boot loader or kernel or root filesystem?

Each component (boot loader, kernel, root filesystem) usually has its own MTD device partition, which can be accessed by the MTD character device. Usually the kernel is executing instructions from RAM – although some handheld computers do execute in flash, a.k.a. XIP (execute-in-place). When the kernel is executing from RAM, the kernel flash partition may be updated freely. The root filesystem is a special case – if files are open in the root filesystem (i.e. executables) during the update, confusion will result. Even without open files, a root JFFS2 filesystem would get its internal data structures out-of-sync with the flash contents.

Upgrading the root filesystem usually is done on a file-by-file basis. Sometimes it is convenient to package the upgrade as a .tar or .tar.gz archive.

More on RFS:

Let's talk about /var

Used for storing volatile information.

What is /proc/filesystems?

Displays a list of the file system types currently supported by the kernel.

What is /dev/pts?

A virtual FS mounted on boot (e.g. /etc/init.d/ for pseudo-terminal use. "should be enabled : most pseudo terminals programs like XTerm, RXVT, GNOME Terminal and Konsole do need it"


The root password (used for console or SSH access) is defined in the RFS, not in the kernel image itself.


There are print levels like KERN_INFO and you are supposed to be able to set these using parameters in proc like /proc/sys/kernel/printk. The four values in this file are console_loglevel, default_message_loglevel, minimum_console_level default_console_loglevel. But haven't seen this effect work properly yet.

There are a series of pr_ defines that are simply macros for printk with different KERN_ levels. For example, pr_info and pr_dbg. It looks like you can get access to these with the io.h file.

You also have the dev_ series of macros that come from device.h rather than the printk files. But they call a dev_printk with the same kernel level id types KERN_.

Looks like once the kernel boots and turns on the MMU, debuggers have trouble accessing proc registers. I think this is the same reason that you need the mmap command to access those registers in an app. For the ARM DS-5 debugger, here's how to adjust:

Debugging the kernel after the MMU is on Now it‘s time to examine or create a debug configuration for the kernel when the MMU is on. -With the target still stopped, click the Disconnect From Target button () in the Debugger Control view to disconnect the U-Boot debug configuration. -Choose Run > Debug Configurations... then expand DS-5 Debugger. The Kernel debug connection may already have been created for you in which case you can just select it, examine the settings and choose the DSTREAM unit. -If there is no Kernel debug connection as a child of DS-5 Debugger, then select DS-5 Debugger and click the New launch configuration mini-icon () to create a new debug configuration. (You can also double-click DS-5 Debugger or right-click it and choose New instead.) -Give the debug configuration a name, I used Kernel. In the Connection pane of the debug configuration we need to specify the platform and choose the DSTREAM. -Choose the i.MX53 Quick Start as the Platform. -Choose the Linux Kernel and/or Device Driver Debug as the Project type. -Choose the Debug and Kernel-only ETB Trace Cortex-A8 via DSTREAM/RVI as the Debug operation.


Useful tool for creating root ownership files for deployment, without needing to have root privileges. Using `fakeroot` is not an absolute substitute for actually being root. `fakeroot` only ever fakes the file access rights and types (regular,block-or-char device...) and uid/gid; these are emulated in-memory.

So when you ls a file, it may appear differently using fakeroot or not. Here's the best description I've come across:

You can save a fakeroot environment with -s, and recall it with -i.

Page last modified on December 04, 2023, at 03:32 PM