Installing Linux onto a CompactFlash Card
By Torrey Vigesaa
05/09/02
As a demonstration of what
steps are needed to put together Linux on an embedded system, I have included
directions on how to put together Linux onto a 64MB Compact Flash card for use
on an x86 system. This Linux system
setup was designed as the simplest method to put the pieces of Linux together
onto a flash memory device without getting into compiling the kernel or any
other parts of the operating system.
x86 hardware is used as the target system which is not a typical
embedded platform but the hardware is very accessible, any x86 PC mother board
with IDE and an Ethernet adapter, keyboard and monitor should work. Also using a target system that is the same
as the development host avoids the extra steps needed for cross-platform
development.
This system does not make
good use of flash memory and would be considered unnecessarily large for an
embedded system. Also the Ext2 file
system is used which does not make use of auto leveling of flash media as do
many RAM file systems. Auto leveling is
a technique used to evenly use the cells of flash memory, which has a limited
amount of read/write life cycles. Many
CF media devices support over 100,000 read/writes per cell.
This system creates a Linux
system manually installed onto a CompactFlash card. The CompactFlash system can then be booted and used as a hard
drive-less Linux system for use as a web server or other services.
Setup of the CF Linux
system requirements:
An x86 PC with 2 IDE
adapters, monitor, keyboard, and an Ethernet adapter is required for the host
development system. This host system
will then become the target system. If
the CF Linux system is for use on a different target system than the host, it
will be easier if both target and host are as similar as possible, having the
same Ethernet adapter is the most important.
The target system software
will be assembled on a CompactFlash card of 64MB or greater. Also a hard to find CF-to-IDE adapter is
required. I purchase from PCEngines (www.pcengines.com) shown below with 128MB
CF card.
For a development host I
used a 500Mhz AMD mainboard with a Via chipset, Award BIOS, and a Realtech network
adapter. I recommend Realtech because
of its RedHat 6.2 Linux kernel support.
CF Linux Development Host
Setup:
On the host system, install
RedHat Linux 6.2 and any other software that you may want on the target CF card
onto the hosts IDE hard drive on the primary IDE adapter. Installed the CF card into the CF-to-IDE
adapter, and attach the adapter to the secondary IDE adapter.
The instructions for
creating the CF system are listed below.
‘%’ or ‘#’ is used to signify your command prompt. I added notes to the instruction in italic.
These are mostly the step by step instructions I performed in creating a CF
system, along with important output captured.
Your output may differ.
Installing Linux on
CompactFlash
CF setup 04/28/02, based on BAH RH6.2
Setup on 128MB CompactFlash
SanDisk
1. Partition the CompactFlash device
Here I use the Linux fdisk utility, remember to login as root.
% fdisk /dev/hdc
Command (m for help): p
Disk /dev/hdc: 8 heads, 32
sectors, 980 cylinders
Units = cylinders of 256 *
512 bytes
Device Boot Start End
Blocks Id System
/dev/hdc1 *
1 979 125296
6 FAT16
Command (m for help): d
Partition number (1-4): 1
Command (m for help): p
Disk /dev/hdc: 8 heads, 32
sectors, 980 cylinders
Units = cylinders of 256 *
512 bytes
Device Boot Start End
Blocks Id System
Command (m for help): n
Command action
e extended
p primary partition
(1-4)
p
Partition number (1-4): 1
First cylinder (1-980,
default 1): 1
Last cylinder or +size or
+sizeM or +sizeK (1-980, default 980): +2M
Command (m for help): n
Command action
e extended
p primary partition
(1-4)
p
Partition number (1-4): 2
First cylinder (18-980,
default 18):
Using default value 18
Last cylinder or +size or
+sizeM or +sizeK (18-980, default 980):
Using default value 980
Command (m for help): p
Disk /dev/hdc: 8 heads, 32
sectors, 980 cylinders
Units = cylinders of 256 *
512 bytes
Device Boot Start End
Blocks Id System
/dev/hdc1 1 17 2160
83 Linux
/dev/hdc2 18 980 123264 83
Linux
Make partition #1 bootable:
Command (m for help): a
Partition number (1-4): 1
Write out partition info to
disk:
Command (m for help): w
The partition table has been
altered!
Calling ioctl() to re-read
partition table.
WARNING: If you have created
or modified any DOS 6.x
partitions, please see the
fdisk manual page for additional
information.
Syncing disks.
2. Format CF:
% mke2fs /dev/hdc1
mke2fs 1.18, 11-Nov-1999 for
EXT2 FS 0.5b, 95/08/09
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
272 inodes, 2160 blocks
108 blocks (5.00%) reserved
for the super user
First data block=1
1 block group
8192 blocks per group, 8192 fragments
per group
272 inodes per group
Writing inode tables: done
Writing superblocks and
filesystem accounting information: done
% mke2fs /dev/hdc2
mke2fs 1.18, 11-Nov-1999 for
EXT2 FS 0.5b, 95/08/09
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
30848 inodes, 123264 blocks
6163 blocks (5.00%) reserved
for the super user
First data block=1
16 block groups
8192 blocks per group, 8192
fragments per group
1928 inodes per group
Superblock backups stored on
blocks:
8193, 24577, 40961,
57345, 73729
Writing inode tables: done
Writing superblocks and
filesystem accounting information: done
3. Copy files to CF
Many time I use the –dpR
flag when using the cp command for coping files,
-d, --no-dereference preserve links
-p, --preserve preserve file attributes if
possible
-R, --recursive copy directories recursively
% cp /etc/* /mnt/cf/etc/
du = 1512
You can use df to display
partition space:
# df
Filesystem 1k-blocks Used Available Use%
Mounted on
/dev/hda6 4008380 988908
2815852 26% /
/dev/hda1 23302 8817
13282 40% /boot
/dev/hdc2 119363 1512
111688 1% /mnt/cf
# du /bin
4072 /bin
# cp -dpR /bin/*
/mnt/cf/bin/
# du
4197 .
# du /sbin/
8 /sbin/pam_filter
3228 /sbin
# cp -dpR /sbin/* ./
# du
5 ./pam_filter
3539 .
When coping files from
/dev be sure to use the –dp flag.
/dev file are special
files that refer to hardware devices.
Also if you are using
Linux kernel 2.4.2 or greater the /dev directory is a virtual directory, much
like /proc so, this procedure may not work.
# cp -dpR /dev /mnt/cf
du /dev
12 /dev/ida
0 /dev/pts
4 /dev/raw
32 /dev/rd
112 /dev
# du /mnt/cf/dev/
12 /mnt/cf/dev/ida
1 /mnt/cf/dev/pts
4 /mnt/cf/dev/raw
33 /mnt/cf/dev/rd
114 /mnt/cf/dev
# mkdir root
# cd root
# cp /root/.* ./
# mkdir home
[root@beathome cf]# mkdir
var
[root@beathome cf]# mkdir
var/log
# cp -dpR /var/lock/subsys/*
/mnt/cf/var/lock/subsys/
# cp -dpR
/var/run/random-seed ./
in /mnt/cf/usr/:
# mkdir bin
[root@beathome usr]# mkdir
lib
[root@beathome usr]# mkdir
sbin
[root@beathome usr]# mkdir
share
in /usr/bin :
# cp -dpR /usr/bin/du ./
[root@beathome bin]# cp -dpR
/usr/bin/find ./
[root@beathome bin]# cp -dpR
/usr/bin/free ./
[root@beathome bin]# cp -dpR
/usr/bin/ftp ./
[root@beathome bin]# cp -dpR
/usr/bin/gzip ./
[root@beathome bin]# cp -dpR
/usr/bin/killall ./
[root@beathome bin]# cp -dpR
/usr/bin/passwd ./
[root@beathome bin]# cp -dpR
/usr/bin/perl ./
[root@beathome bin]# cp -dpR
/usr/bin/pico ./
[root@beathome bin]# cp -dpR
/usr/bin/telnet ./
[root@beathome bin]# cp -dpR
/usr/bin/top ./
[root@beathome bin]# cp -dpR
/usr/bin/uptime ./
[root@beathome bin]# cp -dpR
/usr/bin/uuidgen ./
[root@beathome bin]# cp -dpR
/usr/bin/which ./
in /usr/lib :
]# cp -dpR
/usr/lib/libcrypto.a ./
[root@beathome lib]# cp -dpR
/usr/lib/libcrypto.so ./
[root@beathome lib]# cp -dpR
/usr/lib/libcrypto.so.0 ./
[root@beathome lib]# cp -dpR
/usr/lib/libcrypto.so.0.9.5 ./
[root@beathome lib]# cp -dpR
/usr/lib/libncurses.a ./
[root@beathome lib]# cp -dpR
/usr/lib/libncurses.so.4 ./
[root@beathome lib]# cp -dpR
/usr/lib/libncurses.so.4.0 ./
[root@beathome lib]# cp -dpR
/usr/lib/libpopt.a ./
[root@beathome lib]# cp -dpR
/usr/lib/libpopt.la ./
[root@beathome lib]# cp -dpR
/usr/lib/libpopt.so ./
[root@beathome lib]# cp -dpR
/usr/lib/libpopt.so.0 ./
[root@beathome lib]# cp -dpR
/usr/lib/libpopt.so.0.0.0 ./
[root@beathome lib]# cp -dpR
/usr/lib/libreadline.a ./
[root@beathome lib]# cp -dpR
/usr/lib/libreadline.so ./
[root@beathome lib]# cp -dpR
/usr/lib/libreadline.so.3 ./
[root@beathome lib]# cp -dpR
/usr/lib/libreadline.so.3.0 ./
[root@beathome lib]# cp -dpR
/usr/lib/libz.a ./
[root@beathome lib]# cp -dpR
/usr/lib/libz.so ./
[root@beathome lib]# cp -dpR
/usr/lib/libz.so.1 ./
[root@beathome lib]# cp -dpR
/usr/lib/libz.so.1.1.3 ./
# du
3393 .
in /usr/sbin:
# cp -dpR /usr/sbin/* ./
in /usr/share (defined
terminal types):
# mkdir terminfo
# mkdir terminfo/l
# cp -dpR
/usr/share/terminfo/l/linux ./
# mkdir terminfo/x
# cp /usr/share/terminfo/x/*
./
4. Edit file system table (fstab).
This defines how to mount partition that should be mounted on
boot:
original RH6.2 install
(development host):
# cat fstab
/dev/hda6 / ext2 defaults 1 1
/dev/hda1 /boot ext2 defaults 1 2
/dev/cdrom /mnt/cdrom iso9660
noauto,owner,ro 0 0
/dev/fd0 /mnt/floppy auto noauto,owner 0 0
none /proc proc defaults 0 0
none /dev/pts devpts
gid=5,mode=620 0 0
/dev/hda5 swap
swap defaults 0 0
change to (target):
# cat fstab
/dev/hda2 / ext2
defaults 1 1
/dev/hda1 /boot ext2
defaults 1 2
none /proc proc
defaults 0 0
5. Networking Setup:
you may need to modify network settings if the target needs to be different from devel host. Below are the settings I used.
in : /mnt/cf/etc/sysconfig
]# cat network
NETWORKING=yes
HOSTNAME="tav14"
GATEWAY=192.168.1.1
in:
/mnt/cf/etc/sysconfig/network-scripts
# cat ifcfg-eth0
DEVICE="eth0"
#BOOTPROTO="dhcp"
BOOTPROTO="static"
IPADDR="192.168.1.14"
NETMASK="255.255.255.0"
NETWORK=192.168.1.0
ONBOOT="yes"
6. Setup boot partition
first mount the CF boot partition:
[root@beathome /mnt]# mkdir
cfboot
# mount /dev/hdc1
/mnt/cfboot/
# df
Filesystem 1k-blocks Used Available Use% Mounted on
/dev/hda6 4008380 988124
2816636 26% /
/dev/hda1 23302
8817 13282 40% /boot
/dev/hdc2 119363 16072
97128 14% /mnt/cf
/dev/hdc1 2121 13 2000 1% /mnt/cfboot
in: /mnt/cfboot/ copy necessary file:
# cp -dpR
/boot/System.map-2.2.14-logo ./
[root@beathome cfboot]# cp
-dpR /boot/boot.b ./
[root@beathome cfboot]# cp
-dpR /boot/chain.b ./
[root@beathome cfboot]# cp
-dpR /boot/map ./
[root@beathome cfboot]# cp
-dpR /boot/module-info-2.2.14-5.0 ./
[root@beathome cfboot]# cp
-dpR /boot/os2_d.b ./
[root@beathome cfboot]# cp
-dpR /boot/vmlinuz-beathome ./
7. Prepare LILO bootloader configuration
Edit /etc/lilo.conf:
# cat lilo.conf
boot=/dev/hdc
disk=/dev/hdc
bios = 0x80
map=/mnt/cfboot/map
install=/mnt/cfboot/boot.b
prompt
timeout=50
linear
default=linux
vga=normal
image=/mnt/cfboot/vmlinuz-beathome
label=linux
read-only
root=/dev/hda2
Execute the LILO writer. After execution, do not move files in the CF /boot partition, LILO keeps static memory addresses to some of these files.
# lilo -C
/mnt/cf/etc/lilo.conf
8. Add files to the CF that I forgot to add
earlier
Added linux *
I forgot to create /proc and /lib:
# mkdir proc
# mkdir lib
# ls /lib
# cp -dpR /lib/* ./
9. Dump directory size information
This is only to show the size of directories of my CF system:
# du
12 ./lost+found
3 ./etc/X11/applnk/Utilities
6 ./etc/X11/applnk/Internet
2 ./etc/X11/applnk/System
12 ./etc/X11/applnk
2 ./etc/X11/fs
31 ./etc/X11
1 ./etc/autorpm.d/addons
3 ./etc/autorpm.d/pools
12 ./etc/autorpm.d
2 ./etc/chatscripts
2 ./etc/cron.d
7 ./etc/cron.daily
1 ./etc/cron.hourly
2 ./etc/cron.monthly
3 ./etc/cron.weekly
2 ./etc/default
1 ./etc/dhcpc
1 ./etc/gtk
4 ./etc/logrotate.d
28 ./etc/mail
13 ./etc/pam.d
4 ./etc/ppp/peers
16 ./etc/ppp
10 ./etc/profile.d
45 ./etc/rc.d/init.d
32 ./etc/rc.d/rc0.d
29 ./etc/rc.d/rc1.d
29 ./etc/rc.d/rc2.d
32 ./etc/rc.d/rc3.d
27 ./etc/rc.d/rc4.d
29 ./etc/rc.d/rc5.d
32 ./etc/rc.d/rc6.d
276 ./etc/rc.d
1 ./etc/rpm
2 ./etc/security/console.apps
18 ./etc/security
4 ./etc/skel
1 ./etc/smrsh
8 ./etc/ssh
1 ./etc/ssl/certs
1 ./etc/ssl/private
10 ./etc/ssl
1 ./etc/sysconfig/apm-scripts
1 ./etc/sysconfig/console
42 ./etc/sysconfig/network-scripts
57 ./etc/sysconfig
1 ./etc/vga
1499 ./etc
4197 ./bin
5 ./sbin/pam_filter
3539 ./sbin
12 ./dev/ida
1 ./dev/pts
4 ./dev/raw
33 ./dev/rd
114 ./dev
1 ./boot
41 ./root
1 ./home
1 ./var/log
1 ./var/lock/subsys
2 ./var/lock
2 ./var/run
6 ./var
979 ./usr/bin
3393 ./usr/lib
2207 ./usr/sbin
3 ./usr/share/terminfo/l
76 ./usr/share/terminfo/x
80 ./usr/share/terminfo
81 ./usr/share
6661 ./usr
1 ./proc
48 ./lib/modules/2.2.14-5.0/net
126 ./lib/modules/2.2.14-5.0/misc
177 ./lib/modules/2.2.14-5.0
2558 ./lib/modules/misc
12 ./lib/modules/2.2.16/block
48 ./lib/modules/2.2.16/net
70 ./lib/modules/2.2.16/fs
87 ./lib/modules/2.2.16/misc
219 ./lib/modules/2.2.16
2623 ./lib/modules/misc.old
12 ./lib/modules/2.2.14/block
48 ./lib/modules/2.2.14/net
70 ./lib/modules/2.2.14/fs
440 ./lib/modules/2.2.14/misc
575 ./lib/modules/2.2.14
6153 ./lib/modules
446 ./lib/security
16670 ./lib
32743 .
10. Attempt first boot
shutdown the development host
unplug the HDD and CF device
plug the CF device into the primary IDE
adapter
boot system
---------------
BOOT OK
---------------
If your system does not
boot check these items:
1. Verify that the BIOS detected your CF device
correctly
2. Verify that the boot partition is setup correctly
3. Verify that the /etc/lilo.conf is configured
correctly
While attemping to boot
you only get part of the message “LILO” from the boot loader then a problem
exists with your LILO configuration.
For example, if you only get the message “LI” during boot, then the boot
loader cannot find the loaders second stage boot.p. For more trouble shooting, lookup LILO documentation not in this
document.
My system booted, so I
logged in, entered the df command to display partition info, entered ps to
display the process table, and entered top to display process resource info.
# df
Filesystem 1k-blocks Used Available Use% Mounted on
/dev/hda2 119363 32804
80396 29% /
/dev/hda1 2121 696 1317 35% /boot
]# ps ax
PID TTY STAT TIME COMMAND
1 ? S 0:04 init [3]
2 ? SW 0:00 [kflushd]
3 ? SW 0:00 [kupdate]
4 ? SW 0:00 [kpiod]
5 ? SW 0:00 [kswapd]
283 ? S 0:00 syslogd -m 0
292 ? S 0:00 klogd
306 ? S 0:00 crond
316 ? S 0:00 sshd
333 tty3 S 0:00 login -- root
334 tty4 S 0:00 /sbin/mingetty tty4
335 tty5 S 0:00 /sbin/mingetty tty5
336 tty6 S 0:00 /sbin/mingetty tty6
342 tty3 S 0:00 -bash
365 ? S 0:00 sshd
366 ttyp0 S 0:00 -bash
386 ttyp0 R 0:00 ps ax
# top
6:04am up 3 min, 2 users,
load average: 0.03, 0.07, 0.03
17 processes: 16 sleeping, 1
running, 0 zombie, 0 stopped
CPU states: 0.0% user,
0.1% system, 0.0% nice, 99.8%
idle
Mem: 55252K av, 13368K used, 41884K
free, 8068K shrd, 372K buff
Swap: 0K av, 0K used, 0K
free 8880K cached
PID USER PRI NI
SIZE RSS SHARE STAT LIB %CPU %MEM TIME COMMAND
387 root 17 0
840 840 668 R
0 0.1 1.5 0:00 top
1 root 0 0
476 476 404 S
0 0.0 0.8 0:04 init
2 root 0 0
0 0 0 SW 0 0.0
0.0 0:00 kflushd
3 root 0 0
0 0 0 SW 0 0.0
0.0 0:00 kupdate
4 root 0 0
0 0 0 SW 0 0.0
0.0 0:00 kpiod
5 root 0 0
0 0 0 SW 0 0.0
0.0 0:00 kswapd
283 root 0 0
732 732 592 S
0 0.0 1.3 0:00 syslogd
292 root 0 0
480 480 364 S
0 0.0 0.8 0:00 klogd
306 root 0 0
628 628 516 S
0 0.0 1.1 0:00 crond
316 root 1 0
1088 1088 952 S 0
0.0 1.9 0:00 sshd
333 root 0 0
972 972 736 S
0 0.0 1.7 0:00 login
334 root 0 0
412 412 344 S
0 0.0 0.7 0:00 mingetty
335 root 0 0
412 412 344 S
0 0.0 0.7 0:00 mingetty
336 root 0 0
412 412 344 S
0 0.0 0.7 0:00 mingetty
342 root 1 0
972 972 740 S
0 0.0 1.7 0:00 bash
365 root 1 0
1696 1696 1396 S 0
0.0 3.0 0:00 sshd
366 root 15 0
976 976 740 S
0 0.0 1.7 0:00 bash
Embedded Linux Journal has
published a bi-monthly magazine covering Embedded Linux since January
2001. http://embedded.linuxjournal.com/about/
LinuxDevice.com covers the
embedded Linux industry and embedded Linux products. http://www.linuxdevices.com
An on-line book covering ARM
Linux. http://www.aleph1.co.uk/armlinux/book/mail-list.html
The site where ARM Linux is
maintained. http://www.arm.linux.org.uk/
The Linux Documentation
Project. http://www.tldp.org/
Intel’s StrongARM product
site. http://developer.intel.com/design/pca/applicationsprocessors/1110_brf.htm
Lart Linux ARM development
systems, good resource for beginning Linux ARM development. http://www.aleph1.co.uk/armlinux/index.html