Modify U-Boot to rely on addresses in mmc instead of filesystem - u-boot

For context, I'm trying to make everything in flash as fault-tolerant as possible. Ideally, I'd like to just store the kernel image and initrd file as just BLOBs on MMC.
So as I understand, U-Boot looks for an extlinux.conf or boot.scr file, but as I said I'd rather not rely on the filesystem tables at all.
Would it be safe to just do everything in the main_loop function by just calling mmc read... to load in the kernel image, followed by the boot command? Do I need to do something with the initrd file too?

In short, yes, you would partition your MMC device such that you use mmc read ... to bring in the kernel, device tree, and if used by your system, initrd in to DDR and then use bootm to start the system. You'll also want to have the partition table on your device mark the area where you have the kernel, etc, as reserved in some manner.

Related

What are the building blocks to support a file system in an embedded system?

I am working on a raw/barebone embedded system, and I need to support some filesystem in it.
So I want to undestand the necessary interfaces between upper filesystem and lower block device.
Linux could be a reference, but its design is too complicated for an embedded system.
What I can think about is block_read() and block_write() interfaces which are called by filesystem to read/write data from/to block devices. Are they enough? And is there any other needed interface?
Thanks,
Most file systems targeted for embedded systems provide a porting interface that you need to change in-order to port the FS to your project.
The functions that you need to provide in the porting process are usually:
read from flash
write to flash
erase flash
lock flash
unlock flash
Once the porting is done the FS should be able to create and manipulate files.
Here are some open source file systems targeted for constrained systems:
FatFs
SPIFFS
littlefs

What file system to use for an embedded linux with a eMMC NAND Flash

I'm in charge of choosing a file system for an embedded Linux device.
The device is a Freescale iMX6 running with a eMMC NAND flash memory and a kernel v3.10.17.
I plan to partition the Flash as decribed below:
Partition #1: kernel - not mounted
Partition #2: rootfs - mounted at "/" in read-only mode
Partition #3: userdata - mounted at "/home" in read-write mode
"/var" and "/tmp" directories will be mounted as tmpfs.
In some previous embedded linux projects, I used to use UBIFS on NAND flashes that were not eMMC NAND flash.
Since eMMC NAND flashes include a wear leveling feature, UBIFS should not be used with them as UBIFS' wear leveling feature may interfere with the one used by the eMMC NAND flashes.
I was planning to use ext2 or ext3 for the Partition #2 (rootfs) and ext3 for the Partition #3. I was wondering if ext3 is robust enough so my data won't get corrupted easily after a power failure of a hardreset reboot.
Does anyone have a strong backgroung with all of this and could help me to figure out what file system would be the best ?
Thanks.
I use ext4 file-system on an eMMC device that contains user data in read/write mode on an embedded-linux system.
The system shuts down by hard-reset several times a day for months now. have not witnessed problems with data consistency yet.
cramfs and squashfs are popular for read-only embedded filesystems, because they are highly compressed in storage.
For read-write filesystems, the "normal" ones you might find on a standard Linux desktop install work well (ext3, ext4, etc.). Read about them and pick one that has a balance of overhead and error-correction, depending on what you need for your device.
For the most part the popularity of these filesystems is independent of the hardware you're using as storage -- drivers are used to actually write to the hardware; the filesystem is an abstraction layer above this.
Your comment about ubifs being inappropriate since the driver already does wear-levelling sounds correct to me. UBIFS is weird in that way. Other filesystems are pretty storage-agnostic.

How to mount ubifs filesystem on android emulator?

I want to test the functionality of a custom ubifs filesystem on an android emulator (avd- Nexus 5). I have compiled and deployed a goldfish kernel(3.4) with ubifs support. But not finding the correct steps to mount a ubifs onto the emulator. I have tried using adb's mount command but no use. Any ideas on how to proceed ? or if you have idea on mounting a ubifs onto a real Nexus 5 device, Please do share.
Thanks in advance..
UbiFs requires UBI to work. UBI in turn requires a flash device or MTD (memory technology device). In order to mount it, you can use the nand_sim driver. The following are some commands to setup a UbiFs filesystem,
# nandsim emulating Micron 3.3V 256MiB, 2048 bytes page.
modprobe nandsim first_id_byte=0x2c second_id_byte=0xda third_id_byte=0x90 \
fourth_id_byte=0x95
flash_erase /dev/mtd0 0 0
ubiformat /dev/mtd0
modprobe ubi mtd=0
ubiupdatevol /dev/ubi0_0 ubi.img
mount -t ubifs -o ro /dev/ubi0_0 /mnt/ubifs
This requires that nand_sim as a module; it is probably helpful to have ubi, ubifs, and mtd as modules. At least the above commands work on Debian/Ubuntu systems to verify UbiFs images as well as to diagnose corrupt images. There will probably be some Android simulator specific way to create modules. Alternatively, you can build nand_sim into the kernel and give it parameters to create a dummy flash device.
See the UBI Wiki entry for more information and resources. At least the concepts given should get you on the correct path.
Note: You ubi.img will have been created with some flash parameters such as erase block size. This is a property of the NAND device. You need to give nand_sim parameters for a device that matches those for your test image. The Linux kernel file nand_ids.c has tables with acceptable values for first_id_byte, second_id_byte, etc. There is a NAND hardware command to id flash which nand_sim will emulate to create the proper NAND geometry. The first byte is the manufacturer id.Ref: UbiFs on nand_sim.

Get current drive path from kernel

I'm writing a module that needs to read the MBR on the drive of the currently running kernel. But if I hard code /dev/sda it will read the wrong MBR if I install the module in /dev/sdb.
Is there a way to get the current drive path of the currently running kernel?
(I would use filp_open(), vfs_read() and filp_close() to read the first 512 bytes.)
There is no such thing. The kernel doesn't know where the bootloader that loaded it was itself loaded from. The bootloader might not have been loaded from a drive at all (eg. it could have been a PXE network boot, or loaded from ROM by coreboot), and the kernel might have been loaded by another kernel with kexec rather than from a bootloader.
You will need to have the user specify somehow what device to read the MBR from, perhaps with a module parameter.

Can I create a file system accessible from CE 6.0 and my bootloader?

I have a CE 6.0 project on a PXA310 where I need to be able to download OS updates (nk.bin) via Wi-Fi and safely flash the new OS to my device. I'm open to other suggestions about how to do this, but I'm considering saving the nk.bin to my file system in NAND flash, then restarting and have the bootloader locate the file in the file system and flash it to the BINFS partition. Is this possible, and if so, can you give me an outline of what I'd need to do?
One caveat is that this needs to be very robust since the devices are deployed in the field and are not field serviceable. I need to be sure that if the OS flash fails (due to power failure, etc.) that upon reboot the bootloader can try again. That is why I'd like to store the downloaded image in persistent flash and avoid having to re-download the image.
Technically just about anything is possible. For this strategy what you would need is code for your bootloader to mount the NAND flash as a drive and have a FAT driver so that it can traverse that file system and find the image. That is a lot of work if you don't already have it.
THe other option is to just store it in flash outside of the file system in a known address location. That's a lot easier from the bootloader perspective as all you have to do is map to the address and copy. Of course it makes the writes more challenging because then you're doing it from the OS and you have to disable any other flash accesses completely while you do your write to prevent corruption by two threads sending flash commands to the chip at the same time.
In either case, if you have the space it's a good idea to store a "known-good" image elsewhere too, so that if the new image has a problem (fails a checksum or x number of load attempts fails) then you have a working OS that the bootloader can fall back to.
Clearly a lot depends on your hardware setup, but we've done this without making the Bootloader support the Flash Filesystem.
In our product, the OS image is loaded from Flash to execute from RAM -- I think most WinCE devices work this way nowadays. So to update the OS we use a special Flash driver which lets an application, running under WinCE, update the OS blocks in the Flash -- then all you need is a hard reboot and the Bootloader loads the new flash image into RAM in order to execute it. We've found this pretty reliable in the field (with some not-very-technical end-users!).
A special Flash driver was needed because the MS Flash Filesystem drivers have no access to the OS image sectors of the Flash, in order to prevent trashing the OS by accident.
You do need to load the NK.BIN into some memory which the OS programming application can read, normally the NAND Flash, but if you had enough RAM it could just go into the root of the filestore. However either way you can delete it when you've finished programming the OS sectors before the reboot so it's only a temporary requirement.

Resources