Thursday, September 25, 2008

From Diminuto to Arroyo

If you've lasted this long reading my articles on Diminuto, you know it's my attempt to create an environment for teaching real-time software design, embedded development, and assembly language programming, using commercially available hardware and open source software. Diminuto uses the Atmel AT91RM9200-EK evaluation kit (EK), a single board computer (SBC) that has an ARM9 processor with memory management and a host of peripherals, including Ethernet, USB ports, and a Secure Digital (SD) card slot. You may also recall that Diminuto was built using uClibc, a reduced memory footprint C library, and has a root file system that is memory resident.

(Not that everyone doesn't know what these look like, but below is a photograph of an SD card, which is a little larger than the size of my thumbnail, and a USB storage drive, which is about the size of my thumb. Both of these particular examples hold two gigabytes, a fact that an old guy like me finds astounding.)

Removable "Disk" Drives

Now it's time for Diminuto Phase II, which I call Arroyo. Arroyo has a vastly larger root file system that runs "disk" resident on an SD card. I'm using an EXT3 journaled file system on a 2GB SD card; the root file system utilizes less than 10% of the card. Arroyo is still based on BusyBox (1.11.2), but it uses the full Standard C Library and includes a complete Bash (3.2) shell. Because Arroyo doesn't use a RAM-resident root file system, it has a memory footprint not much larger than Diminuto. Like Diminuto, Arroyo supports USB storage drives as well, making it easy for students to take their projects with them.

(Below is a photograph of the EK SBC with the SD card in its card slot in the left rear and two USB drives in the host USB ports in the center front. Both Diminuto and Arroyo can access these devices just like disk drives. Very slow disk drives. Arroyo uses the SD card for its root file system, although in practice, as with any other Linux system, just about everything commonly used ends up cached in memory.)

Arroyo/Diminuto with Three "Disk" Drives

Arroyo was not built using Buildroot, although it does make use of the genext2fs host utility created by the same folks to build the EXT2 file system image. Arroyo was built using individual open source components including the Linux 2.6.26.3 kernel. The only patch required to any of the open source software was to the kernel to address the wrong board type code reported by U-Boot that I've discussed before.

Arroyo was created using a pre-built tool chain, Sourcery G++ Lite, provided by ARM, Ltd. and the folks at CodeSourcery. The tool chain can be downloaded for free, and provides full support for the later ARM Embedded Application Binary Interface (EABI).

I've ported the Desperado embedded C++ library to Arroyo, including John Sadler's Ficl embeddable Forth interpreter, and ran most of the unit tests.

Here is an example of booting Arroyo on the EK SBC. Note that I overrode the U-Boot bootargs environmental variable to point the kernel at the SD card for its root file system. Since the SD card device driver is hot plugged into the system when you insert the SD card, I told the kernel to delay for a couple of seconds to allow the device to come online. (You can also see this log file here.)


boot 1.0 (Aug 8 2003 - 12:29:00)

Uncompressing image...



U-Boot 1.1.1 (Oct 2 2004 - 19:04:01)

U-Boot code: 21F00000 -> 21F16DF0 BSS: -> 21F1B4AC
RAM Configuration:
Bank #0: 20000000 32 MB
Atmel: AT49BV6416 (64Mbit)
Flash: 8 MB
In: serial
Out: serial
Err: serial
Uboot> printenv
baudrate=115200
ethaddr=02:00:00:00:00:00
bootdelay=5
kernel=tftp 21000000 linux-ek
ramdisk=tftp 21100000 ramdisk
bootargs=console=ttyS0,115200 mem=32M
filesize=1ab33c
fileaddr=21000000
ipaddr=192.168.1.223
serverip=192.168.1.222
start=bootm 21000000
netmask=255.255.255.0
gatewayip=192.168.1.1
diminuto=tftp 21000000 diminuto-linux-2.6.25.10
arroyo=tftp 21000000 arroyo-linux-2.6.26.3
stdin=serial
stdout=serial
stderr=serial

Environment size: 427/8188 bytes
Uboot> run arroyo
TFTP from server 192.168.1.222; our IP address is 192.168.1.223
Filename 'arroyo-linux-2.6.26.3'.
Load address: 0x21000000
Loading: #################################################################
#################################################################
#################################################################
#######################################################
done
Bytes transferred = 1279692 (1386cc hex)
Uboot> setenv bootargs 'console=ttyS0,115200 mem=32M rootdelay=2 root=/dev/mmcblk0p1'
Uboot> run start
## Booting image at 21000000 ...
Image Name: Linux-2.6.26.3
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1279628 Bytes = 1.2 MB
Load Address: 20008000
Entry Point: 20008000
Verifying Checksum ... OK
OK

Starting kernel ...

Uncompressing Linux................................................................................... done, booting the kernel.
Linux version 2.6.26.3 (jsloan@silver) (gcc version 4.2.3 (Sourcery G++ Lite 2008q1-126)) #35 Thu Sep 25 14:05:44 MDT 2008
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: Atmel AT91RM9200-EK
Memory policy: ECC disabled, Data cache writeback
Clocks: CPU 179 MHz, master 59 MHz, main 18.432 MHz
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 8128
Kernel command line: console=ttyS0,115200 mem=32M rootdelay=2 root=/dev/mmcblk0p1
AT91: 128 gpio irqs in 4 banks
PID hash table entries: 128 (order: 7, 512 bytes)
Console: colour dummy device 80x30
console [ttyS0] enabled
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 32MB = 32MB total
Memory: 29728KB available (2344K code, 274K data, 96K init)
SLUB: Genslabs=12, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 192 bytes
NET: Registered protocol family 16
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
NET: Registered protocol family 1
msgmni has been set to 58
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
Non-volatile memory driver v1.2
atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
atmel_usart.1: ttyS1 at MMIO 0xfffc4000 (irq = 7) is a ATMEL_SERIAL
brd: module loaded
loop: module loaded
eth0: Link now 100-FullDuplex
eth0: AT91 ethernet at 0xfefbc000 int=24 100-FullDuplex (02:00:00:00:00:00)
eth0: Davicom 9161 PHY (Copper)
Driver 'sd' needs updating - please use bus_type methods
atmel_spi atmel_spi.0: Atmel SPI Controller at 0xfffe0000 (irq 13)
at91_ohci at91_ohci: AT91 OHCI
at91_ohci at91_ohci: new USB bus registered, assigned bus number 1
at91_ohci at91_ohci: irq 23, io mem 0x00300000
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver libusual
at91_rtc at91_rtc: rtc core: registered at91_rtc as rtc0
AT91 Real Time Clock driver.
i2c /dev entries driver
i2c-gpio i2c-gpio: using pins 57 (SDA) and 58 (SCL)
AT91 Watchdog Timer enabled (5 seconds)
at91_mci at91_mci: 4 wire bus mode not supported - using 1 wire
Registered led device: green
Registered led device: yellow
Registered led device: red
TCP cubic registered
NET: Registered protocol family 17
at91_rtc at91_rtc: setting system clock to 1998-01-01 00:00:59 UTC (883612859)
Waiting 2sec before mounting root device...
mmc0: card is read-write
mmc0: new SD card at address e624
mmcblk0: mmc0:e624 SD02G 1985024KiB
mmcblk0: p1
kjournald starting. Commit interval 5 seconds
EXT3 FS on mmcblk0p1, internal journal
EXT3-fs: mounted filesystem with ordered data mode.
VFS: Mounted root (ext3 filesystem).
Freeing init memory: 96K
Initializing random number generator... done.
Starting network...
ip: RTNETLINK answers: File exists
eth0: Link now 100-FullDuplex



www.diag.com Arroyo 0.0
arroyo login: root
# ifconfig
eth0 Link encap:Ethernet HWaddr 02:00:00:00:00:00
inet addr:192.168.1.223 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:195 (195.0 B) TX bytes:0 (0.0 B)
Interrupt:24 Base address:0xc000

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

# df
Filesystem Size Used Available Use% Mounted on
rootfs 1.9G 133.2M 1.7G 7% /
/dev/root 1.9G 133.2M 1.7G 7% /
tmpfs 14.6M 0 14.6M 0% /tmp
# bash
[root@arroyo ~]# cat /proc/meminfo
MemTotal: 29824 kB
MemFree: 19696 kB
Buffers: 888 kB
Cached: 6552 kB
SwapCached: 0 kB
Active: 3600 kB
Inactive: 4588 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 4 kB
Writeback: 0 kB
AnonPages: 756 kB
Mapped: 1480 kB
Slab: 1332 kB
SReclaimable: 232 kB
SUnreclaim: 1100 kB
PageTables: 92 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 14912 kB
Committed_AS: 1912 kB
VmallocTotal: 989184 kB
VmallocUsed: 1088 kB
VmallocChunk: 986108 kB
[root@arroyo ~]#


Diminuto and Arroyo are both excellent teaching examples of embedded Linux systems at opposite ends of the resource spectrum, and both run on the identical EK hardware and firmware. I'll be writing more about both Diminuto and Arroyo in articles to come.

1 comment:

Cleber Vinícius Ribeiro de Almeida said...

Hi, Mr. Sloan (Chip Overclock).

I think you have made a good work! Very, very interesting for me.

I'm a Brazilian Electronic Engineer and I'm also developing using Embedded Linux (in fact, I have used the same platform than you, the AT91RM9200-EK). Your articles have helped me a lot of times!

Today, I have installed your Arroyo on the FLASH of my AT91RM9200-EK in the Address 0x10030000, in the end of U-Boot. My U-Boot is still the version 1.1.1. The root file system is installed on the SD Card.

Unfortunately, I had some problems when I tried to compile Arroyo again (encouraged by you). I have had a lot of error messages about directories don't found and other things.

So, I have some questions:

1. Using Sorcery G++ Lite, which "linker script" can I specify in the line command to create applications for the Arroyo? For example: "$ arm-none-eabi-gcc -o hello hello.c -T script", where script is the "linker script" specified into the getting-started documentation of the Sorcery G++ Lite.

2. Do you will write some article about make applications (executables) and "device drives" for your Arroyo? It'll be very interesting and useful!

Sorry about my terrible English! :-)

I hope you can help me.

Thanks and best regards,

Cleber Vinícius R. Almeida