How to Overwrite Linux System Files into The Yocto Filesystem

Yocto - How do I change the rootfs file system type

Look for the configuration file of the wic command: if you search in the yocto tree or look at the logs (use bitbake -D ... to get more logs), you will probably find a file name suffixed by .wks. This is the file of directives passed to wic.

In yocto environment, wic can be used on the command line. For example, to get the manual overview:

$ wic help overview

NAME
wic overview - General overview of wic

DESCRIPTION
The 'wic' command generates partitioned images from existing
OpenEmbedded build artifacts. Image generation is driven by
partitioning commands contained in an 'Openembedded kickstart'
[...]

The --source option triggers a plugin. The manual is probably not up to date and you may need to go into the source code of the plugins (wic is written in python) which is located in something like: ...poky/scripts/lib/wic. There you will see, the code managing the "rootfs" plugin in partition.py. You will see that only a reduced set of file system types are supported. Hopefully, squashfs is part of them. Here is the code snippet managing it:

    def prepare_rootfs_squashfs(self, rootfs, oe_builddir, rootfs_dir,
native_sysroot, pseudo):
"""
Prepare content for a squashfs rootfs partition.
"""
extraopts = self.mkfs_extraopts or '-noappend'
squashfs_cmd = "mksquashfs %s %s %s" % \
(rootfs_dir, rootfs, extraopts)
exec_native_cmd(squashfs_cmd, native_sysroot, pseudo=pseudo)

The preceding shows that wic calls mksquashfs tool to build the file system.

Example of howto.

Overwriting Yocto Classes through meta-layer

Generally in Yocto there is no way to override .bbclass files like with .bb files (using .bbappend), to archive that it is needed to copy whole class file and move to another layer, I was able to manage that with this configuration:

layer structure:

$ tree ../meta-test/
../meta-test/
├── classes
│   └── image-live.bbclass
├── conf
│   └── layer.conf
├── COPYING.MIT
├── README
└── recipes-example
└── example.bb

3 directories, 5 files

content of example.bb recipe:

$ cat ../meta-test/recipes-example/example/example.bb 
LICENSE = "CLOSED"
inherit image-live

and finally really important thing*, the configuration file conf/bblayers.conf needs to be configured with this order meta-test/ above meta/ layer:

$ tail -n6 conf/bblayers.conf 
BBLAYERS ?= " \
/home/user/poky/meta-test \
/home/user/poky/meta \
/home/user/poky/meta-poky \
/home/user/poky/meta-yocto-bsp \
"

$ bitbake -e example -D | grep ^DEBUG:\\sInheriting\\s.*image-live.bbclass\\s\(from
DEBUG: Inheriting /home/user/poky/meta-test/classes/image-live.bbclass (from /home/user/poky/meta-test/recipes-example/example/example.bb:3)

*I don't know why bitbake layer priority doesn't work here, only modifying layers order in conf/bblayers.conf allows me to achieve the main goal:

$ bitbake-layers show-layers
NOTE: Starting bitbake server...
layer path priority
==========================================================================
meta /home/user/poky/meta 5
meta-test /home/user/poky/meta-test 10
meta-poky /home/user/poky/meta-poky 5
meta-yocto-bsp /home/user/poky/meta-yocto-bsp 5

layer meta-test/ below meta/ in conf/bblayers.conf:

$ tail -n6 conf/bblayers.conf 
BBLAYERS ?= " \
/home/user/poky/meta \
/home/user/poky/meta-test \
/home/user/poky/meta-poky \
/home/user/poky/meta-yocto-bsp \
"

$ bitbake -e example -D | grep ^DEBUG:\\sInheriting\\s.*image-live.bbclass\\s\(from
DEBUG: Inheriting /home/user/poky/meta/classes/image-live.bbclass (from /home/user/poky/meta-test/recipes-example/example/example.bb:3)

How do I modify a rootfs configuration file with Yocto?

I believe ROOTFS_POSTPROCESS_COMMAND is what you want, but you can't call it from a package recipe like that. In our application, we created a new .inc file with some common functions in the same directory as our .bb image creation recipes and included it in the recipes that build our target images. This is where we put these directives and functions (I have 4 to make symlinks and reset the root password). The challenge is that the postprocess can't call your recipe again, and I'm not sure how it might work to try to predeclare a function like this to be called later. Note the syntax is exactly right by the looks of it, just not in the right location to run when needed.

image-base.inc

ROOTFS_POSTPROCESS_COMMAND += "clear_dropbear_default_configuration;"

clear_dropbear_default_configuration() {
rm ${D}/etc/default/dropbear
touch ${D}/etc/default/dropbear
echo "Hello" > hello.txt
}

image-name.bb

require image-base.inc

You could also just add this to the .bb which is your bitbake directly if you wanted. I like the .inc files though as they make it easier to share among similar entries. Note this example ignores the other content, but you can freeform where it belongs.

If you don't want to change the existing target, you can create your own and then require the image.bb in your new image recipe.

Correct handling of persistent files for readonly rootfs

Simply symlinking /etc/passwd to writable storage does not work because of the checks made by passwd and other tools. There are a couple of things that would work, which I will mention below. But before that, using passwd implies that you are using passwords for authentication, which is not the most secure way of doing it. Maybe you could use a certificate of some sort (as with ssh keys) or some kind of web authentication

Anyhow, here are two ways to get passwd to work...

  1. Use a bind mount

Copy /etc to a directory in a writable partition, named /data in the example. Note that you have to copy the whole of /etc because passwd needs to create several files in there during the update

Do this once (at build time)

cp -a /etc /data

Do this at boot time

mount --bind /data/etc /etc

  1. Use overlayfs

Build your kernel with CONFIG_OVERLAY_FS. Then you can do something like
this:

Do this once (at build time)

mkdir -p /data/etc/work /data/etc/upper

Do this at boot time

mount -t overlay \
-o lowerdir=/etc,upperdir=/data/etc/upper,workdir=/data/etc/work \
overlay /etc

Any changes to /etc are actually recorded in /data/etc/upper, but will
appear to be in /etc.

I am not giving OpenEmbedded recipes to implement either of these solutions here because the changes are pretty trivial but dependent on the exact configuration you are building

Adding random files into root directoy of yocto image?

Can't you just create a simple recipe to do this? That way you could manage dependencies or change whether they are installed or not by just adding/removing the recipe. This is how Yocto should work.

DESCRIPTION = "File Installer"
LICENSE = "CLOSED"

SRC_URI = " \
file://filea \
file://fileb \
file://filec \
file://filed \
"

S = "${WORKDIR}"

do_install() {
install -d ${D}/path
install ${S}/filea ${D}/path
install ${S}/fileb ${D}/path
install ${S}/filec ${D}/path
install ${S}/filed ${D}/path
}

FILES_${PN} += "/path"

How can I add a folder or file to the root in a recipe with bitbake?

In the cases were you get the error "Error: example not found in the base feeds [...]" it's quite likely that you actually have succeeded in building your recipe example.bb. Assuming of course, that you get that error when building your image, which has IMAGE_INSTALL += "example" in it.

If you install your files into /rootfolder, there's nothing in OE itself that knows how to package those files into an rpm, ipk, or deb package. You need to add that yourself to your recipe by adding a line like:

FILES_${PN} += "/rootfolder"

Doing that, your example above should work.

Depending on what files you install, you might want to add some of them to other packages like ${PN}-dbg, ${PN}-dev, etc.



Related Topics



Leave a reply



Submit