Wikipedia:Reference desk/Archives/Computing/2024 June 10

Computing desk
< June 9 << May | June | Jul >> June 11 >
Welcome to the Wikipedia Computing Reference Desk Archives
The page you are currently viewing is a transcluded archive page. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages.


June 10

edit

Convenient way to use dd to flash a new firmware image

edit

Hi. In embedded system development, it is common to use the dd (Unix) command to flash a new firmware onto a disk:

xzcat /media/ubuntu/ubuntu-core-24-amd64.img.xz | \
sudo dd of=/dev/<target disk device> bs=32M status=progress; sync[1]

Currently I am doing the following:

1. Create a bootable live Ubuntu USB drive

2. Plug this drive onto the system I want to flash, and wait for it to boot up (~3 minutes)

3. After it's fully booted up, I am now in a full Ubuntu desktop environment. Now I launch the terminal and run the above dd (Unix) command

Is there a more convenient way to do this?

It occurred to me that most of step #2 and #3 are not necessary. I don't need a full desktop environment. All that really needs to happen is for the Linux kernel to load, then the command is ran (every component of the command is known before hand).

I am guessing that there is already some open source solution for this on Github, but I tried various different search terms and couldn't find it. 99% of what I found was for the use case where you have a Linux distribution ISO (Ubuntu 24.04 LTS.iso, let's say), and you want to write that image onto a blank USB drive. This use case is extremely frequent so many projects and sites are dedicated to it, eclipsing the niche use-case that I am looking for. 17:32, 10 June 2024 (UTC) OptoFidelty (talk) 17:32, 10 June 2024 (UTC)[reply]

Why don't you dd from the machine that you're developing the software on? Why is the Linux livecd step necessary? -- Finlay McWalter··–·Talk 20:37, 10 June 2024 (UTC)[reply]
The development machine is a desktop workstation with sufficient RAM and storage space for development work.
The target machine is a development board with 2GB RAM and 8GB eMMC storage, making it not suitable for development work.
Since these are two separate computers, I cannot think of an easier way to perform the flashing with my very limited linux knowledge. OptoFidelty (talk) 23:13, 10 June 2024 (UTC)[reply]
I'm beginning to understand. So you want to flash the internal disk on the target board. You've not said, but I guess the target board is x86 and runs a conventional UEFI bootrom. And you're flashing a normal x86 ubuntu image onto it. So it seems you'd want the target machine to flash itself and then reboot. If that's all the case, then I think you can have the target machine itself read the image to flash over the network and dd its own disk. Normally this is a rather fragile process, but netcat and dd are tiny programs that will fit in ram easily (as will the kernel and the relevant network and disk drivefs), and so won't be upset when the underlying storage is being messed with. Things will break (necessitating a boot from a usb) if the process is interrupted (so this is a fragile hack that obviously isn't suitable for field or production use). To do this, on the development machine:
      dd bs=16M if=image.iso | bzip2 -c | nc targetmachineip 19000
and on the target machine, a suid-root script does:
      nc -l 19000 | bzip2 -d | dd bs=16M of=/dev/THEDISK
      reboot
And that should do it. I've done this before without issue. To refresh my brain, I cribbed the command lines from this posting (when I did it, I didn't think to zip the stream, but that's probably a smart idea. -- Finlay McWalter··–·Talk 08:14, 11 June 2024 (UTC)[reply]
Simpler yet - on the target machine:
         nc -v -l 19000 > /dev/THEDISK
         reboot
and then on the dev machine:
         nc -v -q 0 targetmachineip 19000 < image.iso
That -q 0 makes the sending party close the socket and exit once it's done (otherwise you have to ctrl-c it). That's for traditional/openBSD netcat; if you're using gnu netcat, I believe you replace -q 0 with -c
You don't need dd at all, and I've omitted bzip2 for clarity (it might help, depending on the speed of the network vs that of the disk). -- Finlay McWalter··–·Talk 15:34, 11 June 2024 (UTC)[reply]
Thank you very much!
(Yes, it's x86 and runs a conventional UEFI. It's not the usual platform so I can see why most guides don't cover it.) OptoFidelty (talk) 18:15, 11 June 2024 (UTC)[reply]
If you want something safer, you could instead:
  1. Partition the target machine's disk in two, with a small partition and a bigger one.
  2. In the small partition, install a minimal linux like Tiny Core Linux's no-gui version
  3. In the larger, place in your actual test product (as you would with dd, before)
  4. Configure GNU GRUB to offer to boot either partition
  5. When you need to update the software under test, you book into tinycore and do the same netcat procedure as above, sending the iso to the large partition (e.g. /dev/sda2)
But I'm no expert at GRUB. Other than that, it should be straightforward. -- Finlay McWalter··–·Talk 12:58, 12 June 2024 (UTC)[reply]