• Stars
    star
    154
  • Rank 242,095 (Top 5 %)
  • Language
    C
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Monolinux distro for the Jiffy board!

buildstatus codecov nala

Monolinux Jiffy

A Monolinux distro for the Jiffy board!

Monolinux: https://github.com/eerimoq/monolinux

Bootloader: https://github.com/jonasblixt/punchboot

Hardware: https://github.com/jonasblixt/jiffy

Features

  • Fast development cycle (a matter of seconds from source code change to entering user space).
  • Everything the Linux kernel provides (networking, filesystems, drivers, etc).
  • Various libraries provided by Monolinux.
  • Efficient and fun unit testing with Nala.

Boot time

The embedded Linux based system enters user space 0.33 seconds after power on. The EXT4 filesystem is ready in 0.37 seconds and networking in 2.2 seconds. Very impressive for an i.MX6UL SoC with a 528 MHz ARMv7-A CPU, 1 GB DDR3 RAM and 4 GB eMMC! A reboot is even faster, only 0.26 seconds from issuing the reboot to entering user space.

Note that all software except the EXT4 filesystem are part of a secure boot chain. The system will boot even faster without secure boot, but unfortunately I've not had the oppertunity to try it.

Measurement point Elapsed time Delta
Hardware 1 ms 1 ms
ROM code 185 ms 184 ms
Bootloader 271 ms 86 ms
Linux user space 333 ms 62 ms
EXT4 filesystem 373 ms 40 ms
TCP/IP networking 2.2 s 1.8 s

More information about the system and its boot sequence:

First of all, the power is turned on. The hardware releases the reset to the i.MX6UL about 1 millisecond later, and soon the ROM code reads the bootloader from eMMC, verifies its integrity and jumps to it. This takes 185 milliseconds, which is far more than expected. It's hard to do anything about it as this is properitary NXP software.

The Punchboot bootloader is very fast out of the box, and to make it even faster the device tree patching was removed (now done compile time) and the eMMC type was changed from DDR52 to HS200. The bootloader reads the Linux kernel (3.5 MB), ramdisk (1.4 MB) and device tree (8 kB) from eMMC and verifies them in only 86 milliseconds. It then start the Linux kernel. No other bootloader was tested, not even U-Boot.

The system's tiny Linux kernel (version 4.14.78) boots in about 62 milliseconds, which is very fast. This is achieved with a minimal kernel configuration, a few patches, a minimal device tree, and uncompressed kernel and ramdisk images.

Here is a brief description of the Linux kernel patches.

  • Unpack the ramdisk after drivers are probed.
  • Removal of unnecessary delays in the MMC driver (I hope). This is possible since we know excatly which MMC is mounted on the board, and that it is always powered on.
  • Start with MMC clock frequency at 52 MHz instaed of 400 kHz. Same reasoning as in the previous bullet, but not according to spec.
  • Async MMC and FEC (Ethernet) driver probes to do other initialization in parallel.
  • 10 Hz Ethernet PHY polling instead of 1 Hz. Would not be needed if the PHY sends an interrupt when its link is up.

The statically linked init process, part of the ramdisk, contains the entire application. It's implemented in C for low overhead, both in RAM and CPU time. No forks. No scripts. No shared libraries. It does however contain cURL and other libraries, which makes it about 800 kB.

The EXT4 filesystem (which is not integrity checked with dmverity) is mounted within 40 ms after entering user space. The enabler is to start the customized MMC driver early.

Networking takes by far the longest time to get ready. The main reason is that Ethernet auto-negotiation takes a significant amount of time, about 1 to 3 seconds. Users that do not need Ethernet, or can use a static link configuration, can save a bunch of time.

Below is selected messages from the Linux kernel log to better understand what is going on. There are a few user space messages in the log as well.

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.14.78 (erik@erik-GR8) (gcc version 9.1.0 (GCC)) #1 Tue Jun 16 19:18:46 UTC 2020

[    0.022802] Unpacking initramfs...
[    0.025535] mmc0: SDHCI controller on 2190000.usdhc [2190000.usdhc] using ADMA
[    0.034262] Freeing initrd memory: 1416K
[    0.035840] Freeing unused kernel memory: 172K
[    0.041533] 1970-01-01 00:00:00 INFO default Successfully inserted '/root/fec.ko'.
[    0.053621] 1970-01-01 00:00:00 INFO default Successfully inserted '/root/ext4.ko'.
[    0.057696] fec 2188000.ethernet eth0: registered PHC device 0
[    0.058009] mmcblk0: p1 p2 p3 p4 p5 p6
[    0.076813] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)
[    0.082744] 1970-01-01 00:00:00 INFO default /ext4fs/README: +-----------------+
[    0.082812] 1970-01-01 00:00:00 INFO default /ext4fs/README: | Monolinux Jiffy |
[    0.082869] 1970-01-01 00:00:00 INFO default /ext4fs/README: +-----------------+
[    0.114466] SMSC LAN8710/LAN8720 2188000.ethernet-1:01: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=2188000.ethernet-1:01, irq=POLL)
[    0.114607] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[    1.892754] fec 2188000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[    1.892791] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[    1.893268] 1970-01-01 00:00:01 INFO dhcp_client Starting on interface 'eth0'.
[    1.900520] 1970-01-01 00:00:01 INFO dhcp_client Received OFFER packet.

More ideas:

  • Compile for the Thumb instruction set for significantly smaller binaries. Has been tested, but the init process crashes.

    [    0.560005] Freeing unused kernel memory: 1024K
    [    0.565155] Internal error: Oops - BUG: 0 [#1] THUMB2
    [    0.570222] Modules linked in:
    [    0.573294] CPU: 0 PID: 1 Comm: init Not tainted 4.14.78 #19
    [    0.578959] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
    [    0.585148] task: c7009800 task.stack: c702e000
    [    0.589685] pc : [<c0205ba2>]    lr : [<c0205ba2>]    psr: 60000013
    [    0.595957] sp : c702ffa8  ip : 50c53c7d  fp : 00000000
    [    0.601187] r10: 00000000  r9 : c702e000  r8 : c0205dc4
    [    0.606420] r7 : 000f0005  r6 : 00000000  r5 : 00000000  r4 : 000224d4
    [    0.612956] r3 : c702e000  r2 : 0002254c  r1 : c702ffb0  r0 : 00000000
    [    0.619492] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
    [    0.626633] Control: 50c53c7d  Table: 871b0059  DAC: 00000051
    [    0.632387] Process init (pid: 1, stack limit = 0xc702e208)
    [    0.637967] Stack: (0xc702ffa8 to 0xc7030000)
    [    0.642340] ffa0:                   000224d4 00000000 0002254c 00022098 beca7fda 00022094
    [    0.650531] ffc0: 000224d4 00000000 00000000 000f0005 00000000 6474e551 00000000 00000000
    [    0.658722] ffe0: 00000037 beca7df0 00010688 000111bc 20000010 0002254c 00000000 00000000
    [    0.666920] Code: 00004770 00000000 00000000 b6720000 (2008f8d9)
    [    0.673020] ---[ end trace e0ea9fb97d0d2058 ]---
    [    0.677644] Kernel panic - not syncing: Fatal exception
    
  • The MMC is setup by the bootlaoder. Update the Linux MMC driver to take advantage of this. No additional setup should be needed.

Measurements

Test sequence

  1. Unmount and power off the board.

    $ umount ext4fs
    $ poweroff
    
  2. Unplug the USB cable.

  3. Start a logic analyzer capture.

  4. Plug in the USB cable.

  5. Wait for the system to start.

  6. Stop the logic analyzer capture.

Measurement points

Hardware:   RST_N high
ROM code:   GPIO low
Bootloader: GPIO high
Linux:      "main" printed
Filesystem: dmesg "mounted..." - dmesg "Freeing..." + "main" printed
Network:    dmesg "Received OFFER..." - dmesg "Freeing..." + "main" printed

Build and run

This requires that punchboot is running and ready to execute commands.

$ ./rundocker.sh
$ make -s -j8 upload

More Repositories

1

gqt

Build and execute GraphQL queries in the terminal.
Python
461
star
2

simba

Simba Embedded Programming Platform.
C
339
star
3

monolinux

Create embedded Linux systems with a single statically linked executable.
Makefile
324
star
4

asn1tools

ASN.1 parsing, encoding and decoding.
Python
290
star
5

detools

Binary delta encoding tools.
Python
159
star
6

moblin

Moblin, a free iOS app for IRL streaming.
Swift
133
star
7

bitstruct

Python bit pack/unpack package.
C
120
star
8

bincopy

Mangling of various file formats that conveys binary information (Motorola S-Record, Intel HEX, TI-TXT, Verilog VMEM, ELF and binary files).
Python
102
star
9

dbg-macro

A set of dbg(…) macros for C
C
79
star
10

pbtools

Google Protocol Buffers tools (C code generator).
C
72
star
11

nala

🦁 Nala - A delightful test framework for C projects.
C
69
star
12

pumbaa

Python on Simba.
C
62
star
13

mqttools

MQTT version 5.0 client and broker using asyncio
Python
61
star
14

hardware-reference

Various documents.
55
star
15

textparser

A text parser.
Python
29
star
16

async

🔀 Asynchronous framework in C.
C
26
star
17

pyfuzzer

Fuzz test Python modules with libFuzzer
Python
24
star
18

asyncudp

Asyncio high level UDP sockets.
Python
24
star
19

asyncbg

Asyncio background tasks
Python
16
star
20

monolinux-raspberry-pi-3

A Monolinux distro for Raspberry Pi 3!
C
15
star
21

bitstream

A bit stream library for C.
C
15
star
22

messi

⚽ Reliable message passing in distributed systems.
C
14
star
23

pictools

Microchip PIC tools for software developers.
C
13
star
24

ecdtools

Electronic circuit design tools.
Python
10
star
25

monolinux-c-library

The Monolinux C library.
C
9
star
26

traceback

Colorful stack traceback in C on Linux.
C
9
star
27

soundid

Sound identification.
Python
7
star
28

humanfriendly

Human friendly C library.
C
7
star
29

monolinux-example-project

A Monolinux example project.
C
6
star
30

irwin

Plotting data in the terminal
Python
5
star
31

expect

Programmed dialogue with interactive streams.
Python
5
star
32

bunga

Control and monitor your system.
C
5
star
33

advent-of-code

https://adventofcode.com/
Python
4
star
34

systest

System test framework.
Python
4
star
35

simba-esp32

ESP32 for Simba
C
4
star
36

moblin-remote-control-relay

Moblin Remote Control Relay
JavaScript
4
star
37

argparse_addons

Additional Python argparse types and actions.
Python
3
star
38

terminal_graphics

Who knows?!?
Python
3
star
39

uml

Unified Modeling Language (UML)
Python
2
star
40

obs-remote-control-relay

OBS Remote Control Relay
JavaScript
2
star
41

romeo

C
2
star
42

drmario

Dr. Mario OBS plugin.
CMake
2
star
43

httpasync

HTTP Async
Python
2
star
44

avr-toolchain-windows

AVR toolchain for Windows
C
2
star
45

rafiki

Rust on Simba.
Rust
2
star
46

moblin_assistant

Moblin remote control assistant.
Python
2
star
47

Rist

librist Swift wrapper
Swift
1
star
48

monolinux-rust-jiffy

Monolinux in Rust for the Jiffy board
Dockerfile
1
star