1

I'm trying to conceive a firmware update mechanism for a Linux-based embedded system without an additional initrd/initramfs/whatever. From within the running system, which has a read-only mounted root, I use dd to copy the new root image (residing on a secondary data partition).

The problem is that half of the times I end up with a corrupted root filesystem. I don't get why this is happening, knowing that the partition is read-only and that I do a sync right before rebooting (I reboot by writing 'b' to /proc/sysrq-trigger). Someone please enlighten me.

1

You're overwriting a mounted filesystem. As soon as the file system driver attempts to read anything from it, you're bound to end up in trouble.

You'll need to make sure that as soon as you're writing the new firmware, nothing else must read or write that partition.

What people usually seem to be doing to circumvent that problem is to use the boot loader to flash new firmware. It usually resides completely in RAM and therefore doesn't need to access your partitions.

EDIT: Another way would be to install another minimal system on your second partition whose sole purpose it is to flash an image file to the first partition. when an update is due, you'd just need to copy the image to the right location, update the bootloader (to boot from the second partition) and reboot. Once the image is written, reset the boot loader and reboot again.

2
  • There's shouldn't be any write to that partition at all since it's mounted r/o. Reads on the other hand I expect to happen within the following few seconds, resulting in errors of course, but the sysrq reboot succeeds anyways. I just don't get what process writes something to that partition at some point, screwing the newly "flashed" filesystem. Or could it be the sync is ineffective?
    – ccrisan
    May 26 '14 at 20:30
  • I think the fs driver might mess up the kernel's state enough for your sync fail. So unless you can guarantee that there's no I/O on that partition you're pretty much in uncertain terretory.
    – mreithub
    May 26 '14 at 22:12
0

You can't overwrite the root filesystem while it is mounted, even readonly.

What you can do is mount a tmpfs containing all the files from the root filesystem, then call pivot_root to switch to the tmpfs and unmount the old root.

This is probably impossible for a system that have already been booted, since umounting the old root filesystem means that all programs running from it must either exit or exec a program.

The most viable way to use this approach would probably to have a /sbin/tmpfs-init program that did all this stuff and then exec's the new init. Even this is rather difficult to do.

2
  • Could you develop a bit this /sbin/tmpfs-init idea? I have tried the pivot_root/switch_root/"mount --move" methods and everything was fine until trying to unmount the old root which indeed failed because of being used by running processes.
    – ccrisan
    May 27 '14 at 6:46
  • You have to make the currently running process die. This is easiest if the only process running is init, which then execs an inferior init to actually do the unmount step.
    – o11c
    May 27 '14 at 19:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.