Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rm: linux: add linux-nfs-boot information #646

Merged
merged 3 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 266 additions & 0 deletions source/reference-manual/linux/linux-nfs-boot.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
.. _howto-linux-nfs-boot:

LmP Root File-System Over NFS
=============================

Introduction
------------

LmP uses OSTree to pack the device root filesystem. In early boot,
initramfs manipulates OSTree storage to layout the target root
filesystem for Linux® kernel mounting.

Yocto enables modular initramfs configuration, allowing selective
support for udev, rootfs, ostree, or network filesystem in the
ramdisk. Adding NFS and OSTree ramdisk support permits switch root
scripts to prepare shared network filesystem for mounting on the target.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to understand the goal of this sentence.

Would this order be ok?

Suggested change
Yocto enables modular initramfs configuration, allowing selective
support for udev, rootfs, ostree, or network filesystem in the
ramdisk. Adding NFS and OSTree ramdisk support permits switch root
scripts to prepare shared network filesystem for mounting on the target.
Adding NFS and OSTree ramdisk support permits switch root
scripts to prepare shared network filesystem for mounting on the target
because there are modular initramfs configuration, allowing selective
support for udev, rootfs, ostree, or network filesystem in the
ramdisk.

Why is it important to mention that "Adding NFS and OSTree ramdisk support permits switch root
scripts to prepare shared network filesystem for mounting on the target."? It looks loose to me...

But if you want to mention this, use The Yocto Project instead of yocto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it wss important to mention just because I didnt know about it :) but it could very well be that is common knowledge and it is just me that wasnt aware of it...but yeah, I'd rather keep it.


Generally, NFS booting any LmP system requires configuring NFS support
in the ramdisk, along with a TFTP server and an NFS server.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be the first sentence in this intruduction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right!


NFS Use Case: Validation of eMMC Card
-------------------------------------

During product development, validating the eMMC card for system boot
might be needed. The Linux kernel eMMC subsystem offers an extensive set
of tests. Unfortunately, many tests require unbinding the eMMC card from
the kernel. In such cases, you can boot the system over NFS, unbind the
eMMC, and run the tests. Here's an example executing eMMC tuning tests:

.. prompt:: text

$ echo 'mmc0:0001' > /sys/bus/mmc/drivers/mmcblk/unbind
$ echo 'mmc0:0001' > /sys/bus/mmc/drivers/mmc_test/bind
$ echo 52 > /sys/kernel/debug/mmc0/mmc0\:0001/test


Enabling NFS Support on initramfs
---------------------------------

To configure the ramdisk for NFS boot using Yocto requires enabling the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To configure the ramdisk for NFS boot using Yocto requires enabling the
To configure the ramdisk for NFS boot using LmP requires enabling the

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lmp uses Yocto and Yocto uses the module. I'd rather point to the last element in the chain (ie Yocto)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case, use "the Yocto Project" instead of only yocto

``initramfs-module-nfsrootfs`` package.

A reference snippet can be seen below:

.. prompt:: text

diff --git a/meta-lmp-base/recipes-core/images/initramfs-ostree-lmp-image.bb b/meta-lmp-base/recipes-core/images/initramfs-ostree-lmp-image.bb
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not supposed to be built on a factory?

Copy link
Contributor Author

@ldts ldts Jan 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes, but it is not enabled by default so someone will have to take action in their override...should I provide a meta-subscriber-override patch instead? I always build locally on my box hence why I didnt bother with the override and just used the patch that @rsalveti shared with me

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main point here is what is needed to make the NFS work is only available via local build?

One argument to keep the local build only is to make sure people will not start using NFS for things other than testing/dev

Copy link
Contributor Author

@ldts ldts Jan 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should cover both cases.I'll add the subscribers patch as well. @angolini I think a more generic - less restrictive - doc is a better doc. What do you think?

index f4f2e505..99b801ca 100644
--- a/meta-lmp-base/recipes-core/images/initramfs-ostree-lmp-image.bb
+++ b/meta-lmp-base/recipes-core/images/initramfs-ostree-lmp-image.bb
@@ -4,6 +4,7 @@ PACKAGE_INSTALL = "initramfs-framework-base \
initramfs-module-udev \
initramfs-module-rootfs \
initramfs-module-ostree \
+ initramfs-module-nfsrootfs \
initramfs-module-ostree-factory-reset \
${VIRTUAL-RUNTIME_base-utils} \
${@bb.utils.contains('DISTRO_FEATURES', 'ima', 'initramfs-framework-ima', '', d)} \

Then rebuild LmP as usual.

Access to the LmP released WIC file, the kernel Image for booting, the

Check warning on line 62 in source/reference-manual/linux/linux-nfs-boot.rst

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Fio-docs.sentence-length] Aim for sentences no longer than 25 words Raw Output: {"message": "[Fio-docs.sentence-length] Aim for sentences no longer than 25 words", "location": {"path": "source/reference-manual/linux/linux-nfs-boot.rst", "range": {"start": {"line": 62, "column": 1}}}, "severity": "INFO"}
board's device tree blob, and the generated ramdisk is necessary for the
following sections.

Preparing the NFS Server
------------------------

Copy the WIC image created during the build step to the NFS shared
folder and mount it for simplicity. Alternatively, you can extract and
copy all its contents based on your use case.

To mount the WIC, use ``fdisk`` to determine the start sector
and length of the rootfs image in the file (i.e., the number of
sectors).

.. prompt:: text

$ fdisk -l lmp-base-console-image-${platform-name}.wic

Then create the ``rootfs`` directory and mount it:

.. prompt:: text

#!/bin/bash
mkdir rootfs
read -p "Enter linux start sector: " lsector
read -p "Enter linux number of sectors: " lnsectors
let "offset=`expr ${lsector}*512`"
let "sizelimit=`expr ${lnsectors}*512`"
mount -o loop,offset=$offset,sizelimit=$sizelimit -tauto lmp-base-console-image.wic rootfs/


It is this ``rootfs`` mount-point - which shall contain ``boot/`` and ``ostree/``
directories - what you should export via NFS.

Check warning on line 95 in source/reference-manual/linux/linux-nfs-boot.rst

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Fio-docs.em-dash] Did you mean to you use an em dash '—'? Raw Output: {"message": "[Fio-docs.em-dash] Did you mean to you use an em dash '—'?", "location": {"path": "source/reference-manual/linux/linux-nfs-boot.rst", "range": {"start": {"line": 95, "column": 12}}}, "severity": "WARNING"}

Inspecting the ``ostree/`` directory and in this particular case, you should
expect something as follows:

.. prompt:: text

ostree/boot.1/lmp/180c0adc612a144a262f15e6c124cc3ac22260b7b2897832a1228da2d3e359a5/0


Preparing the TFTP Server
-------------------------

LmP employs U-boot as both the primary and secondary bootloader on ARM
platforms. The secondary bootloader's role is to boot the Linux kernel.

U-boot can be configured to fetch the Linux image, device tree, and
ramdisk from a TFTP server. For successful booting, the ramdisk must be
in a format that U-boot can parse.

During LmP building, the CI service deploys all the build artifacts. The

Check warning on line 115 in source/reference-manual/linux/linux-nfs-boot.rst

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Fio-docs.sentence-length] Aim for sentences no longer than 25 words Raw Output: {"message": "[Fio-docs.sentence-length] Aim for sentences no longer than 25 words", "location": {"path": "source/reference-manual/linux/linux-nfs-boot.rst", "range": {"start": {"line": 115, "column": 70}}}, "severity": "INFO"}
kernel and device tree are published in a FIT file (Flattened Image
Tree), while the initial RAM file system is deployed as a
gzip-compressed cpio archive.

To extract the kernel and device tree blob, start by listing the
contents of the FIT file.

The file should be named ``fitImage-${platform-name}.bin``

.. prompt:: text

$ dumpimage -l fitImage-uz3cg-dwg-sec.bin
FIT description: Kernel fitImage for Linux-microPlatform/5.15.64+gitAUTOINC+0d5ce62585_35bc6145aa/uz3cg-dwg-sec
Created: Thu Sep 1 04:40:19 2022
Image 0 (kernel-1)
Description: Linux kernel
Created: Thu Sep 1 04:40:19 2022
Type: Kernel Image
Compression: gzip compressed
Data Size: 9831595 Bytes = 9601.17 KiB = 9.38 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x18000000
Entry Point: 0x18000000
Hash algo: sha256
Hash value: 4087645d7b85479e76824652aaf764cb5248ffb07572186553a7cc74a80c7a06
Image 1 (fdt-system-top.dtb)
Description: Flattened Device Tree blob
Created: Thu Sep 1 04:40:19 2022
Type: Flat Device Tree
Compression: uncompressed
Data Size: 45983 Bytes = 44.91 KiB = 0.04 MiB
Architecture: AArch64
Load Address: 0x40000000
Hash algo: sha256
Hash value: 5270804486f9aeed060da21a2879ce21c60b5cb45ffef7b35b1fac3171c6ee81
Default Configuration: 'conf-system-top.dtb'
Configuration 0 (conf-system-top.dtb)
Description: 1 Linux kernel, FDT blob
Kernel: kernel-1
FDT: fdt-system-top.dtb
Hash algo: sha256
Hash value: unavailable
Sign algo: sha256,rsa2048:ubootdev
Sign value: c07a5cd7408836c2e03fb9dce22c7670e87e8a8e2e32676e1d91c853848324fab28fb3fb1e3fda6ea8f6b93c73dd63bbc8877ddcca186cfef1b051d54ddb26a303eea2d66bebe1c1471bd1018b4fc1ef2a53d1d00b540de3c0b15eab3fba4a3767a72a4131f1dd74115e5fd3a79e71acdcee8decd75ca469c97a6713753dcb90dfe114ccc8abb03a84db7ec818123326b0639c85f79379f4d3d63ba495ab1568e62ea2f779bea011a44ce152df286e9039f6ba6a0199632dfa7bfb8794fd5dffed14678a0e5ae009cf07598772178e783930eceee6b48a05c424ac252bd25a6151825d1f3d1747a4bc17847d27e1465590a0dc6b75d8f545b44df1b7407e8b70
Timestamp: Thu Sep 1 04:40:19 2022

Then to extract the bootable kernel image (position 0 in the FIT) to a
file named ``Image`` use the dumpimage utility

.. prompt:: text

$ dumpimage -T flat_dt -p 0 -o Image fitImage-uz3cg-dwg-sec.bin
Extracted:
Image 0 (kernel-1)
Description: Linux kernel
Created: Thu Sep 1 04:40:19 2022
Type: Kernel Image
Compression: gzip compressed
Data Size: 9831595 Bytes = 9601.17 KiB = 9.38 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x18000000
Entry Point: 0x18000000
Hash algo: sha256
Hash value: 4087645d7b85479e76824652aaf764cb5248ffb07572186553a7cc74a80c7a06


And to extract the device tree blob (position 1 in the FIT) to a file named ``system.dtb``:

.. prompt:: text

$ dumpimage -T flat_dt -p 1 -o system.dtb fitImage-uz3cg-dwg-sec.bin
Extracted:
Image 1 (fdt-system-top.dtb)
Description: Flattened Device Tree blob
Created: Thu Sep 1 04:40:19 2022
Type: Flat Device Tree
Compression: uncompressed
Data Size: 45983 Bytes = 44.91 KiB = 0.04 MiB
Architecture: AArch64
Load Address: 0x40000000
Hash algo: sha256
Hash value: 5270804486f9aeed060da21a2879ce21c60b5cb45ffef7b35b1fac3171c6ee81


The ramdisk is deployed as
``initramfs-ostree-lmp-image-${platform-name}.cpio.gz``. In order for
U-boot to consume it we need to convert the archive to a ramdisk
image. For that, U-boot provides the mkimage Linux utility.

Run the following command to generate the ``ramdisk`` file:

.. prompt:: text

$ mkimage -A arm -O linux -T ramdisk -d initramfs-ostree-lmp-image-uz3cg-dwg-sec.cpio.gz ramdisk

At this point, we have all the components to boot over NFS. The TFTP
server shall export ``Image``, ``system.dtb`` and ``ramdisk``.


Using U-boot to Boot the NFS

Check failure on line 217 in source/reference-manual/linux/linux-nfs-boot.rst

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Fio-docs.Header-cap] 'Using U-boot to Boot the NFS': Use APA title case: https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case Raw Output: {"message": "[Fio-docs.Header-cap] 'Using U-boot to Boot the NFS': Use APA title case: https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case", "location": {"path": "source/reference-manual/linux/linux-nfs-boot.rst", "range": {"start": {"line": 217, "column": 1}}}, "severity": "ERROR"}
-----------------------------

For the first boot you will have to flash the WIC image as per the LmP
instructions. Then boot the system and dump the command line:

.. prompt:: text

root@uz3cg-dwg-sec:~# cat /proc/cmdline
earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/mmcblk0p2 rootfstype=ext4 ostree=/ostree/boot.1/lmp/180c0adc612a144a262f15e6c124cc3ac22260b7b2897832a1228da2d3e359a5/0


Since we will need to halt the boot sequence at the U-boot prompt, you
might have to set the ``bootdelay`` U-boot variable. This could be done
either in your build or at this time from the LmP linux shell.

Check failure on line 231 in source/reference-manual/linux/linux-nfs-boot.rst

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [Fio-docs.Branding-and-names] Use 'Linux' instead of 'linux' Raw Output: {"message": "[Fio-docs.Branding-and-names] Use 'Linux' instead of 'linux'", "location": {"path": "source/reference-manual/linux/linux-nfs-boot.rst", "range": {"start": {"line": 231, "column": 51}}}, "severity": "ERROR"}

To do this from the Linux shell, use the ``fw_setenv`` utility.

After re-booting to the U-boot prompt, modify the ``bootargs``
environment variable with the NFS enabled command line. Also use the
``tftpboot`` u-boot shell command to pull ``Image``, ``system.dtb`` and
``ramdisk`` from the TFTP server into memory.


1. bootargs for NFS server at 192.168.1.8

Replace the pointers to persistent storage in the previous command line with the NFS information.
``root=/dev/nfs nfsroot=192.168.1.8:/srv/nfs/rootfs rootwait rw ip=dhcp``

.. prompt:: text

uboot> setenv bootargs "earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/nfs rootfstype=ext4 ostree=/ostree/boot.1/lmp/180c0adc612a144a262f15e6c124cc3ac22260b7b2897832a1228da2d3e359a5/0 nfsroot=192.168.1.99:/srv/nfs/rootfs rootwait rw ip=dhcp"

2. tftp server at 192.168.1.7 and various memory addresses for the
different files to download.

.. prompt:: text

uboot> setenv tftpserverip 192.168.1.7; setenv ipaddr=dhcp;
uboot> setenv initrd 0x10A00000; setenv imgaddr 0x800000000; setenv dtaddr 0x10000000;
uboot> tftpboot ${dtaddr} ${tftpserverip}:system.dtb
uboot> tftpboot ${initrd} ${tftpserverip}:ramdisk
uboot> tftpboot ${imgaddr} ${tftpserverip}:Image;


3. Finally boot the image:

.. prompt:: text

uboot> booti ${imgaddr} ${initrd} ${dtaddr}
1 change: 1 addition & 0 deletions source/reference-manual/linux/linux.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The LmP is open source software, and maintained by Foundries.io on `GitHub`_.
linux-net-debug
linux-disk-encryption
linux-update
linux-nfs-boot
linux-dev-mode
linux-oss-compliance
factory-device-reset
Expand Down