Monday, January 16, 2012

How to make a makefile

Sometimes a part of makefile needs to be dynamically generated. Instead of doing it prior to running make you can do a cool trick with GNU Make. You can just usually write the rule how to generate dynamic makefile and define dependencies and the recipe.

dynamic.mk: generate.sh config_file.xml
$< > $@

include dynamic.mk

A bit of explanation $< is the first prerequisite $@ is the target being made and the > is the normal bash redirection of standard output to file. So the second line is equivalent to:
generate.sh > dynamic.mk

When make encounters an include directive of a makefile it tires to look up the rules to update it as a target. It will remake any that are out of date or don't exist (issuing a warning for the non-existent ones).

You can define dependencies when the dynamic part of the makefile needs to be remade and when it is up to date. This way make itself ensures that makefiles are up to date.

Sunday, January 15, 2012

How to mount an UBI image

UBI and UBIFS do not work on top of block devices. So simple loop-mount will not work.

UBI is an abstraction layer that works on top of MTD raw flash devices. It's worth to note that raw flash is not the typical pen-drive, memory card or SSD but it is a flash chip without a FTL. UBI is usually it's used in embedded devices.

UBI is usually used as a supporting layer for the UBIFS filesystem. It's a successor to JJFS2 which does not use a supporting layer like UBI but works directly on MTD devices. UBIFS mounting works across these layers:

/mnt/fs (mount point) => /dev/ubi0_0 (UBIFS) => /dev/ubi0 (UBI) => /dev/mtd0 (MTD raw flash device)
TODO: make a simple diagram here

UBIFS images are created by mkfs.ubifs. UBI images are created by the ubinize utility taking UBIFS images as input. Note that an UBI image may contain multiple UBIFS filesystems.

For further information about UBI and UBIFS check the documentation and FAQ.

To mount an UBI image an MTD device is needed. If you have it on your system you can use it to flash the UBI image to the device. If you want to do this on a regular computer you need to emulate it. One way to do it is to use the mtdram linux kernel module. You need root to do it like this:

modprobe mtdram total_size=X

X is the size in KB of the emulated MTD device. Make sure it is larger than the image you wish to mount. To check the status of MTD devices you can use:

cat /proc/mtd

You should see a mtd0 device. Now you need to prepare it and flash the UBI image into it:

flash_erase /dev/mtd0 0 0
ubiformat /dev/mtd0 -f image.ubi

Now the MTD device contains the contents of the UBI image. Now you need to tell the UBI module to use it:

modprobe ubi
ubiattach -p /dev/mtd0

This will create UBI device (/dev/ubi0) and  the UBIFS (/dev/ubi0_0) partitions. Now just mount it:

mount -t ubifs /dev/ubi0_0 /mnt/ubifs

You could also use nandsim but then you would have to know the bytes of READ ID response of the particular flash chip and pass these during modprobe.

Tuesday, January 10, 2012

Build a module on Fedora

If you need to build a kernel module on Fedora you need the kernel-devel rpm. Don't forget you also need gcc :)