News:

Registered a URL and setup a forum as the IPCam stuff really needed its own site vs my irregular blog posts about IPCam hacking at http://www.computersolutions.cn/blog

Author Topic: Making ROM's not war, or ROM wasn't built in a day.  (Read 6190 times)

  • No avatar
  • *****
February 10, 2011, 04:54:02 pm
So, what does it take to make a rom?

For our firmware, we need 2 files.  One is our Linux kernel - which we get from our build process.
The second is our rom.

What is a rom anyway?

A rom is a group of files in a suitable filesystem image.
Our kernel uses romfs for its rom file system, but there are a few different ones that can be used.

We use romfs mainly as its the easiest one to use.  romfs is small, but has one downside, its readonly.
Later versions of linux can also use xip (execute in place), but we're on 2.4, so none of that for us.

What rom types can we use then, and what are the pro's and con's?
For our build environment, we have the following common options.  (More can be added, but these are the ones available in the default BSP)

ROMFS
This is the simplest format, its a very basic file system.
Doesn't support compression of the filesystem.  Read only.

http://romfs.sourceforge.net/

CRAMFS
This is also a read only file system.  Supports compression though.
From the notes - cramfs is designed to be simple and small, and to compress things well.
Doesn't support timestamps in files though, and cramfs creation needs to be on a machine with the same endian'ness - so watch out for little endian / big endian issues (byte order swaps in little endian vs big endian systems).

http://en.wikipedia.org/wiki/Cramfs

JFFS2
This is a read / write file system.  Writing to flash is slow however for obvious reasons.  This is a journalled file system - meaning it writes a log of file system changes when it writes to a disk.
Mounting is generally slower than the above filesystems.

http://sourceware.org/jffs2/

YAFFS2
This is another read/write file system. YAFFS2 is simple, portable, reliable and self-contained. It is log-structured, and single-threaded. It does not do compression.

http://www.yaffs.net/yaffs-overview

NFS
Network filing System
This isn't like the others above - its a network file system.  We can have the machine boot from an external network.
We'll probably use NFS for additional storage or testing when needed. 


For a full list of available options, take a look at the BSP uClinux-dist/linux-2.4.x/fs folder.

So, what should we use?

Well, we have plenty of ram 16M, but limited flash - 2M - 4M.
So we need a file system thats small, and compressed.  We don't need write access except for a small subset of files - eg the configuration, so in theory we could use 2 file systems - one for the main binaries, and a smaller one for read/write access for the config files.

Initially we'll work with romfs, as its the simplest, and used by default.

Now we know what we need, how do we make a file system?

The BSP people have kindly given us a default file system setup in the romdisk directory.
This has the more or less basic linux defaults of

Code: [Select]
/bin
/dev
/etc
/flash
/proc
/usb
/usr
/var


If we compare with the camera (below), we have some extra folders.   Not so important though.

Code: [Select]
/bin
/dev
/etc
/flash
/home
/proc
/swap
/usr
/var

A full listing of the default camera files and folders is below

Code: [Select]
# tree
.
├── bin
│   ├── camera
│   ├── dhcpc
│   ├── ifconfig
│   ├── init
│   ├── iwconfig
│   ├── iwpriv
│   ├── mypppd
│   │   ├── chap-secrets
│   │   ├── options
│   │   ├── pap-secrets
│   │   └── pppd
│   ├── route
│   ├── sh
│   ├── wetctl
│   └── wpa_supplicant
├── dev
│   ├── console
│   ├── display
│   ├── dsp -> dsp1
│   ├── dsp0
│   ├── dsp1
│   ├── fb0
│   ├── hda
│   ├── hda1
│   ├── hda2
│   ├── hdb
│   ├── i2c0
│   ├── i2c1
│   ├── key
│   ├── keypad
│   ├── lp0
│   ├── mixer -> mixer1
│   ├── mixer0
│   ├── mixer1
│   ├── mouse
│   ├── mtd0
│   ├── mtd1
│   ├── mtdblock0
│   ├── mtdblock1
│   ├── nftla
│   ├── nftlA1
│   ├── null
│   ├── ppp
│   ├── ppp1
│   ├── ptmx
│   ├── pts
│   ├── ptyp0
│   ├── ptyp1
│   ├── ptyp2
│   ├── ptyp3
│   ├── ptyp4
│   ├── ptyp5
│   ├── ptyp6
│   ├── ptyp7
│   ├── ptyp8
│   ├── ptyp9
│   ├── rom0
│   ├── rom1
│   ├── rom2
│   ├── sda
│   ├── sda1
│   ├── sda2
│   ├── sdb
│   ├── sdb1
│   ├── sdb2
│   ├── smartcard0
│   ├── smartcard1
│   ├── tty
│   ├── tty1
│   ├── ttyp0
│   ├── ttyp1
│   ├── ttyp2
│   ├── ttyp3
│   ├── ttyp4
│   ├── ttyp5
│   ├── ttyp6
│   ├── ttyp7
│   ├── ttyp8
│   ├── ttyp9
│   ├── ttyS0
│   ├── ttyS1
│   ├── ttyS2
│   ├── ttyS3
│   ├── urandom
│   ├── usb
│   │   ├── lp0
│   │   ├── lp1
│   │   ├── lp2
│   │   ├── lp3
│   │   ├── lp4
│   │   ├── lp5
│   │   ├── lp6
│   │   ├── lp7
│   │   ├── lp8
│   │   ├── lp9
│   │   └── lp.sh
│   ├── usi
│   ├── video0
│   └── video1
├── etc
├── flash
├── home
├── proc
├── swap
├── usr
└── var
    └── run

13 directories, 95 files



You'll notice that the BSP folder effectively has the same layout as the camera one.
Our dev folder is the only folder we really need to take care on, as we need to ensure that the file nodes for that match up with whats available in the hardware (see my other post on that for more details).

All we need to do for our filesystem is to make the appropriate folders, links and files within a given folder, then run genromfs.

Lets look at how that works.

In our BSP there are tools to generate a romfs in the build process, but I prefer to do it by hand.
All we need to do is to copy the appropriate binary files we need into our bin folder, and setup an appropriate boot script.

We'll probably use busybox for a shell (using either lash or msh).  We could also use sash, but busybox is just as small and has more features / capability.

So first we'll need to compile busybox with msh or lash, and a few other tools.
Once compiled, copy those to /bin in our romfs folder.

We'll need to also create an alias for init -> busybox as init gets called by the kernel when it hands off to our romfs.

/bin will probably look something like this at a minimum

Code: [Select]
busybox
init -> busybox
msh -> busybox
mount -> busybox
ifconfig -> busybox

Next off we'll need to go to /etc
/etc needs to have an init script called inittab

Mine looks like this

Code: [Select]
cat inittab
# Setup our shell run scripts
::sysinit:/etc/init.d/rcS

# Start an "askfirst" shell on the console (whatever that may be)
::respawn:-/bin/sh

Finally, we'll need to put some run scripting into the /etc/init.d/rcS file we specified above.

Code: [Select]
cat rcS
#!/bin/sh
/bin/mount -t proc none /proc

At a minimum, our run script needs to remount /proc, as we are using a read only file system.
If /proc is not remounted we break a few programs, as they can't read the relevant files from /proc (as its not writable by the kernel).

The above is a fairly minimal basic bootable environment with a shell.

Assuming you've gone and done the above, we can now make a file system.
Get out of the romdisk folder and into a folder above it.

To create our romfs file system we call a command called genromfs
Lets look at the parameters for genromfs.

Code: [Select]
#genromfs -h
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
  -h                     Show this help

Seems simple enough.

Our command to generate a file system will look something like the below

Code: [Select]

# genromfs -d romdisk/  -f myromfs.img


This will generate a file called myromfs.img, which contains our romfs filesytem.
Nice and easy.

We can easily mount and check this filesystem on Linux with the mount command.

Code: [Select]
mkdir /mnt/myrom
mount -t romfs -o loop myromfs.img /mnt/myrom

We tell mount to use romfs as the filesystem (-t romfs) , and to mount the file as a block device (-o loop) in our newly created /mnt/myrom folder.

If we visit the myrom folder, you'll see the same files we put in the romdisk folder.
We can also mount existing firmware to check whats inside those files in a similar manner.

Its good practice to take a look at a few different romfs files and see how people lay out their stuff.
If people are interested, I can upload a few different romfs files for the camera's that I've split out from their firmwares so they can take a peek.

Lawrence.



« Last Edit: February 10, 2011, 04:55:40 pm by admin »

February 10, 2011, 08:43:05 pm
Wow !! I like it !!! Its help alot for user like me, now I understand a bit much more Thank you !!