Use separate rootfs sources with A/B mechanism

When I flash the system with RootFS A/B it writes:

Making system.img…
Setting “FDT /boot/dtb/kernel_tegra234-p3701-0005-p3737-0000.dtb” successfully in the extlinux.conf…done.
populating rootfs from /home/bsp/Desktop/Workspace_5_1_3/Linux_for_Tegra/rootfs … populating /boot/extlinux/extlinux.conf … done.
Sync’ing system.img … done.
Converting RAW image to Sparse image… done.
system.img built successfully.
Making system.img_b…
Setting “FDT /boot/dtb/kernel_tegra234-p3701-0005-p3737-0000.dtb” successfully in the extlinux.conf…done.
populating rootfs from /home/bsp/Desktop/Workspace_5_1_3/Linux_for_Tegra/rootfs … populating /boot/extlinux/extlinux.conf … done.

My question is if its possible to indicate two separate rootfs folders, one for each partition, instead of flashing twice, one for each partition.


Hi BSP_User,

Are you using the devkit or custom board for AGX Orin?
What’s your Jetpack version in use?

Are you trying to flash internal eMMC or external NVMe?
Do you mean that you want to use different image for rootfs in slot A and slot B?

Hi Kevin,

  • I’m using devkit but need the solution to work for custom carrier board as well.
  • Currently JP 5.1.3
  • Currently internal eMMC but need the solution to work for external NVMe as well
  • Yes, I want to create additional rootfs folder (for example Linux_for_Tegra/rootfs_b) and that APP_b will be build from it.

I can achieve the same goal by flashing the devkit twice, each time another partition (first APP and then APP_b) and replacing the rootfs dir. This is not a good solution for production environment and I need a faster way.

I looked at and saw it uses rootdir_source variable for both rootfs images (APP and APP_b). One could modify the script for it to use two separate sources - one for APP and one for APP_b partitions. The problem is that this variable is being used in other parts of the script as well and I don’t know how to modify it without risking of breaking something else (maybe signature logic, etc…)

  • By the way, its not my original question but same solution is needed for different kernel images as well. (the ability to indicate two kernel images and one will be flashed on A_kernel and the other on B_kernel)

That way we get the full customization ability for each slot.

You can focus/verify on the devkit with internal eMMC first.

It seems you want A/B slot for rootfs and kernel using different images.
Actually, it is not the mechanism how our redundant rootfs/bootloader works.
We haven’t verified this use case, you have to customize the flash script and also the partition layout file first.

can you guide me? as I said I found hints in the where exactly is the “problem”. The thing is I don’t want to break other logics. These may serve others as well

The “problem” is in the create_fsimg() function. it uses the same ${source_folder} variable (5th arg to build_fsimg func) for both partitions:

function create_fsimg {
local do_sign=“${2}”;

if [ “${disk_enc_enable}” -eq 0 ]; then
local source_folder=“${1}”
APP_TAG+="-e s/APPFILE/${localsysfile}/ ";
# this is set at a setval function
if [ “${target_partname}” = “” ] || [ “${target_partname}” = “APP” ] || [ -n “${with_systemimg}” ]; then
build_fsimg “${localsysfile}” “${fillpat}”
“${rootfssize}” “${rootfs_type}”
“${source_folder}” “${cmdline}” “${do_sign}”;

  if [[ "${rootfs_ab}" == 1 ]]; then
  	# build fsimage for APP_b
  	local sysfile=""

  	# check if APP_b exist in layout file
  	get_value_from_PT_table "APP_b" "filename" "${cfgfile}" sysfile
  	if [ "${sysfile}" != "" ]; then
  		if [ "${target_partname}" = "" ] || \
  		   [ "${target_partname}" = "APP_b" ] || [ -n "${with_systemimg}" ]; then
  			build_fsimg "${localsysfile}_b" "${fillpat}" \
  				    "${rootfssize}" "${rootfs_type}" \
  				    "${source_folder}" "${cmdline_b}" "${do_sign}";

if [ “${target_partname}” = “” ] || [ “${target_partname}” = “APP” ] || [ -n “${with_systemimg}” ]; then
build_boot_fsimg “${localsysbootfile}” “${fillpat}”
“${bootfssize}” “${rootfs_type}”
“${rootfs_dir}/boot” “${cmdline}” “${do_sign}”;
if [ “${target_partname}” = “” ] || [ “${target_partname}” = “APP_ENC” ] || [ -n “${with_systemimg}” ]; then
build_enc_root_fsimg “${localsysencrootfile}” “${fillpat}”
“${encrootfssize}” “${rootfs_type}”
“${rootfs_dir}” “${rootfsuuid_enc}”
“${bootpartuuid}” “${ECID}” “${rootfsuuid_b_enc}”
“${rootfsuuid}” “${partition_app_enc_enable}”;

  if [[ "${rootfs_ab}" == 1 ]]; then
  	if [ "${target_partname}" = "" ] || [ "${target_partname}" = "APP_b" ] || [ -n "${with_systemimg}" ]; then
  		echo -e -n "\tpopulating initrd_b to rootfs... ";
  		cp -f initrd_b "${rootfs_dir}/boot/initrd"; chkerr;
  		build_boot_fsimg "${localsysbootfile_b}" "${fillpat}" \
  				 "${bootfssize}" "${rootfs_type}" \
  				 "${rootfs_dir}/boot" "${cmdline_b}" "${do_sign}";
  	if [ "${target_partname}" = "" ] || [ "${target_partname}" = "APP_ENC_b" ] || [ -n "${with_systemimg}" ]; then
  		build_enc_root_fsimg "${localsysencrootfile_b}" "${fillpat}" \
  				     "${encrootfssize}" "${rootfs_type}" \
  				     "${rootfs_dir}" "${rootfsuuid_b_enc}" \
  				     "${bootpartuuid_b}" "${ECID}" "${rootfsuuid_enc}" \
  				     "${rootfsuuid_b}" "${partition_app_enc_b_enable}";


the ${source_dir} variable is actually ${rootfs_dir} variable. So we need to add ${rootfs_dir_b} variable. The problem is that ${rootfs_dir} is being used ~45 times in the script so one has to add it carefully

As I said that we haven’t verify this before so that I can’t give you step-by-step instruction to implement for your specific case. You have to try it and even debug by yourself.

Is there any issue if you separate rootfs_dir to rootfs_dir_a and rootfs_dir_b?

I didn’t try

I’ll try and update here if I won’t find another bypass.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.