Requesting help with two issues: cloning a custom image and installing a fresh image

Hello there,

I was hoping to get your input on two issues. I’m working with a dragonboard 410c (Inforce 6309).

1. I want to install all required libraries/software, my application/files, configuration settings for various stuff etc on one board.
Now I want to be able to clone this board to, let’s say, 50 other boards. (And possibly more in the future).
What is the best way to achieve this? I have checked out two topics about this (and posted my doubt in there previously):
- Clone a dragonboard to other dragonboard units
- Extracting eMMC content of Dragonboard 410c

Through my research and these topics, I came to the solution that once I have setup the board as I like, I use dd to write an image file. And using a bootable micro sd card (live session), I write this image to the emmc storage.

This method has worked, but it seems inelegant and prone to breaking in the future.

Is there any other way I can achieve this? There are instructions to build the kernel and flash using fastboot. Two subquestions:

a. Can I somehow include my libraries and dependencies and my application and configuration preferences and then follow the instructions to build the kernel? How would I do that?
b. Can I use fastboot for linaro based boards? (the manufacturer provides linaro and android options, are the instructions applicable to android?)
c. In addition to writing the image to mmcblk0, should I be doing anything with the other paritions (mmcblk0boot0, mmcblk0boot1, mmcblk0rpmb)

2. Let’s say I wanted to install a fresh image of linaro (as in, without my software) onto these boards (similar to, say, a fresh install of Debian on your desktop).

Then:

a. What would I need to do? Using dd (or fastboot, if that works), do I need to copy emmc_boot.mbn to aboot, boot_xx.img to boot and linaro-jessie-alip-qcom-snapdragon-arm64-xx-xx-ifc.img to rootfs?
b. Are these the correct files? (I know these are specific to the manufacturer, but in general, do they look like the right files to copy?)
c. There are two boot paritions on the original (factory) install (mmcblk0boot0 and mmcblk0boot1), is this correct?

To try this out, I dd’ed just the linaro-jessie-alip-qcom-snapdragon-arm64-xx-xx-ifc.img to the mmcblk0 from a ‘booted from sdcard’ session. Unfortunately, after removing the sdcard and rebooting, it boots to a blank screen. Could someone comment on whether I’m using the right file and/or any additional steps I’m missing to achieve this?

I would really appreciate your help with this. Thank you!

Firstly, we don’t really recommend setting a golden board and then
cloning it. There are two main problems:

  1. When the time comes to upgrade, reproducing exactly the same set
    of changes for your next gold image it tricky.

  2. It is hard to scour the image and remove the unique values
    (ssh server ID, MAC address, etc). This causes a headache
    later.

It is better to find a way to generate a rootfs from scripts and/or CI.

At the really simple end this can be a matter of taking our image,
unpacking it, loopback mounting it and chroot’ing (with the help of
qemu) to update things. Then you can repack and install it as normal.

At the more complex end you could try to clone much of our CI
infrastructure (its all publicly accessible… although its also
fairly complex and can be hard to navigate) and generate your own
images from scratch.

Finally, if you are trying to make an appliance-like system you would
probably be better off looking at Yocto/OpenEmbedded rather than Debian
anyway.

Regarding installation, you want either the fastboot method, or the SD
installer (updated with your image rather then the default):

You can also use Qualcomm’s factory provisioning methods (QFIL). This is
not documented for Dragonboard 410C so you should talk to your board
vendor if you want to use that.

1 Like

I agree with @danielt on most things, except that I think it should be relatively easy to generate your own rootfs. We rely on a tool called FAI, from Debian. This tool takes as input a few config files, where we specify the list of packages to install. So making your own image should be easy.

If you need to make more changes like adding files, modifying content, it’s also doable with FAI. It’s a comprehensive tool used by lots of people.

Our config scripts are here:

https://git.linaro.org/ci/fai.git/

You can browse through our overall Debian build job for DB410c here:

https://git.linaro.org/ci/job/configs.git/tree/lt-qcom-debian-images-dragonboard410c.yaml

most especially here:

https://git.linaro.org/ci/job/configs.git/tree/lt-qcom-debian-images/builders-fai.sh

The rootfs is created with a single command:

sudo fai-diskimage -v --cspace $(pwd) \
     --hostname linaro-${rootfs} \
     -S ${rootfs_sz} \
     --class $(echo SAVECACHE,${OS_FLAVOUR},DEBIAN,LINARO,QCOM,${rootfs},${FAI_BOARD_CLASS},RAW | tr '[:lower:]' '[:upper:]') \
     /tmp/${VENDOR}-${OS_FLAVOUR}-${rootfs}-${PLATFORM_NAME}-${BUILD_NUMBER}.img.raw

The main concern with FAI right now, is that we run it natively, e.g. on arm64. I recommend you start like that. I think the latest FAI release should work in cross environment, but I haven’t tried. It might be a good excuse to try it…

Customizing your very own images like that, is by far the much recommended method. I know some people have been able to do it. I agree it might not be very well documented, but that’s something we need anyways, so we can do that along the lines, and create proper documentation.

thanks!

1 Like

Thanks @anon91830841.

For sure, I would not like to discourage anyone from using FAI. Its the “right thing to do” and probably what I would do myself except for super tiny (<10) short term production runs (e.g. a demo for a trade show).

It does involve accepting that, like most distro related work, it can gets knowledge intensive if you are trying to build a turn-key image (rather than a raw installed OS) since it requires a relatively deep understanding of debian packaging, debconf and scripting (and which one to use for what). In terms of complexity its similar to creating a docker container. This shouldn’t be surprising then you think what a docker container actually is.

1 Like

Thank you all for your help. I’ll report back on how it goes. FAI was something I was aware of but didn’t know whether there was an easier way.

Thanks again.

Another question: If I want to silence all the text on boot and shutdown, what do I need to do?

I know how to achieve this on the desktop, but I haven’t had luck on the DragonBoard. I tried editing the rc.local and adding dmesg --console-off, but that didn’t help.

Would creating a /boot/cmdline.txt file and including args in it work?

Do I need to add a commandline args and build the kernel? Something like : quiet console=tty12?

Is there a simpler approach?

Thank you!

You don’t have to rebuild the kernel just to change the kernel command line…

The boot partition is simply an Android boot image (abootimg). You can use the abootimg command line tool on the DB410C to unpack it, update the kernel command line and repacks it. Just point the tool at /dev/disk/by-partlabel/boot instead of a file image.

1 Like

Hi Daniel, I am now attempting to add tweak the kernel boot parameters.

I have unpacked the boot.img using abootimg -x ../dev/disk/by-partlabel/boot
Then I edited the bootimg.cfg file by adding console=quiet

Now I’m about to pack it up and I had two questions.

  1. Is the following command the right way to do this?
    In-place:
    abootimg -u …/dev/disk/by-partlabel/boot -f bootimg.cfg
    Create an image:
    abootimg --create some_boot.img -f bootimg.cfg -k zImage -z initrd.img

  2. If the above command is used to create an image, what’s the easiest (least effort) way to apply it to:
    a) The current board.
    b) Multiple boards.

Thank you, I really appreciate your help so far!

To be honest I haven’t tried this for a long time so I suggest you just try it! I can’t see anything wrong with updating via a hacked bootimg.cfg but personally I would probably try to update the cmdline parameter directly:

abootimg \
    -u /dev/disk/by-partlabel/boot \
    -c cmdline="root=/dev/disk/by-partlabel/rootfs rw rootwait console=tty0 console=ttyMSM0,115200n8 quiet"

IMHO either of the update approachs is the easiest way to apply it to the current board.

For deployment to other boards basically all you are doing is creating a custom boot image. If you decompress the existing boot image you’ll find out that it is simply a abootimg:
http://releases.linaro.org/96boards/dragonboard410c/linaro/debian/18.01/boot-linaro-buster-dragonboard-410c-359.img.gz

So you can do with your custom image everything you can with a normal one, including using dd to copy it to/from /dev/disk/by-partlabel/boot and writing it via USB+fastboot from the host.

1 Like

Happy to report that the inline update command worked fine.

The console parameter to suppress any text at boot/shutdown/reboot didn’t seem to work, but I did achieve what I needed by setting the loglevel=1 in boot parameters.

I did a quick check and found that the dev/disk/by-partlabel/boot is pointing to mmcblk0p8. Assuming my cloned image includes this partition, this change should be reflected on any other board with this image.

Thanks for your help @danielt.

The console parameter to suppress any text at boot/shutdown/reboot
didn’t seem to work, but I did achieve what I needed by setting the
loglevel=1 in boot parameters.

Indeed. quiet isn’t intended to suppress all text. It leaves
error messages fully enabled but conceals informational messages.
Under the covers I believe quiet sets the log level to 4 (from the
default of 7).

Thanks for your help @danielt.

My pleasure!

1 Like

Ah another, issue I’m noticing as a side effect of cloning is that the MAC address of the ethernet adapter is showing up as the same on all the boards.

I know I can manually set the mac address to be something else (preferably the one on the sticker), but I was wondering, is there a way to do it cleanly?

  1. Is there a file(s) it’s temporarily stored in that I can delete before making an image. Then, after cloning the image onto a board, the OS can pull whatever mac address it detects on that hardware.
  2. There are some heavy handed approaches that I would not prefer such as :

i) Recording mac address before cloning an image on to the board.
After cloning the image set the mac address to this value.

ii) Removing and reinstalling the module and letting the OS detect the mac address again.

Any help would be appreciated! Thank you.

hi,

the DB410c does not have on board Ethernet, so you probably need to check with Inforce how they configure the MAC address for the on board Ethernet device they put on the 6309… From what you are saying, it looks like the MAC address might be hardcoded in a file in rootfs, but that’s just a guess.

For WLAN and BT MAC addresses , at least on DB410c, and with the Linaro builds, the MAC address are generated by the bootloader (LK) and dynamically added into the DTB which is given to the kernel, so they are not hardcoded anywhere. The downside , since they are generated, is that they do not correspond to the MAC address that is ‘printed’ on the board. However they are generated from a UID read on the eMMC controller, so they are unique for each board (and always the same for a given board, after each boot).

1 Like

Thank you.

I believe the file in question is /lib/firmware/smsc75xx/ethmacaddr0
(And wlan equivalent : /lib/firmware/wlan/macaddr0).

I’m still making sure it does work as I’m expecting it to, but I think this might be it.

EDIT: Deleting the file and rebooting did end up in another mac address being generated, but it does not match what it shipped with.

I’m going to try deleting the file a few times to see if it is consistent.

Interesting, so without anything in the file, a new one is generated on each boot.

Is the file is deleted, a new one is generated on each boot, but the file isn’t recreated.

Funnily, the lack of a dedicated mac address seems to force predictable interface naming to select ‘eth0’ as the ethernet adapter name.