SD card damage protection

That is really tough stuff and I didn’t get half of it. You asked me several times for a confirmation for this and that.

So this is what I did:

  1. I purchased a Jetson Nano dev kit
  2. I took a 32 GB SD card out of the shelf
  3. I downloaded the latest image you can get if you start with “Nvidia getting started”.
  4. I flashed this using Etcher on a Mac
  5. I started the thing with a keyboard and a monitor attached, configured it so that it came up
  6. I cloned the SD on my Linux laptop and sent it to you.

I never burned any fuse nor did use a productive Nano. I never compiled a kernel and so God will I will never do :)

I also have no intention to deep dive as far as you did, because this is far beyond my intention and interest in this matter. I was “just” looking for a cheap way to

a) prevent any extra costs for an eMMC variant of all this, which is praised as THE solution to achieve a power-fail-stable Nano
b) achieve something similar to what I have done 1000 times with RPI and stuff: Make that damned SD write protected.

I really appreciate your efforts, but I don’t want to force you to do things, which I at least will never be able to follow.

I was more after a “lehni” script, which does the stuff once and forever and forget about.

Thanks nevertheless. I will try to re-read your great elaboration in order to find something to do :)

I was trying to follow your novel, but I have to say: This is way more than I wanted to know :)

I thank you very much for your effort, but now I will move on and consider this “make SD read/only” as somehow not a low hanging fruit. And this is then the end of the story for me.


It is possible any third party OverlayFS script for automatic setup of the Jetson would install a custom kernel. It would not necessarily have to be you that compiled or installed a new kernel, but it is still useful to have it confirmed that you did not add anything new.

Comments on fuse burning are mainly for other people reading this. Dev kit Jetson’s don’t have the ability to burn a security fuse, so you can ignore this.

FYI, though you don’t need to do this, building a kernel or kernel module is not nearly as complicated as it seems. The part which can get complicated is installing a new kernel. If you are only installing a new kernel module, then it is quite simple. In fact, for your case, there is an OverlayFS module installed to your SD card. Copying that module to the initrd is essentially the same as installing a module, but it is to the “miniature” initrd filesystem instead of to the main rootfs. Just stay away from using flashing to install kernels or modules…it is better to do this with file copies, and much of the documentation related to using flash to install kernels and/or modules is for production eMMC releases with the security fuse burned (and as mentioned, SD card models don’t have a way to burn a security fuse, so you can ignore flash methods for installing kernels or modules). Whenever you want to install a new kernel or module, just ask here in the forums. Avoid using or flashing in general for kernel additions (modules are kernel additions, but they are only small pieces and can live in a separate file and be inserted or removed while the kernel runs).

The eMMC variants can set up backup bootloader content to remain bootable even if something happened to the original boot content. Actually setting this up takes a learning curve. Ignore it for SD card variants.

I suspect the script failed because it does not understand the initrd. You don’t really need to understand the initrd, but if you go through the steps to unpack your initrd and copy the kernel modules to it, then repack the initrd, you are more or less done. However, if a package were to update the initrd without knowing this, then it would fail and you’d need to do it again. The actual unpack of initrd, copy, and repack is quite simple (my long explanation is for people wanting to learn this, but you could simply go through the steps and it should work…about 2 minutes if you’ve done it before, about 5 or 10 minutes if you’ve not done it before).

The “lehni” script will need to be updated every time the kernel changes or the initrd changes. It isn’t a “build one and you are done”; the script simply does not have the ability to know the future.

As a last thought: The mechanism of using an initrd and kernel modules is 100% entirely a Linux mechanism, and is itself the same on all Linux computers. The real issue is that PCs all have a BIOS, and that provides a uniform boot method to program for…that method will go unchanged for years. Embedded systems do not have a BIOS, and so the actual method for implementing “how to boot” is custom on every embedded device. Scripts for embedded system updates are simply too custom for a script to just work right on boot content which is a changing target.

but you could simply go through the steps and it should work…about 2 minutes if you’ve done it before, about 5 or 10 minutes if you’ve not done it before).

I’m sorry. If there was any followable instruction which in the end lead to a bootable RO system I have not understand it.

Find your file “/boot/initrdon the Jetson. Copy it somewhere else which is an empty directory (possibly on your PC). I will prefix file path names with “NANO” if a file copy is from the Nano, and you will have to adjust. If this is an SD card mounted on your host at “/somewhere”, then you could just prepend the copy command with “/somewhere”. Example:

  1. mkdir -p ~/scratch/initrd
  2. cd ~/scratch
  3. cp NANO/boot/initrd.img-4.9.201-tegra . # Note the command ends with a space and a period.
  4. sudo -s
  5. gunzip < ../initrd.img-4.9.201-tegra > initrd-4.9.201-tegra.cpio
    gunzip < ./initrd.img-4.9.201-tegra > initrd-4.9.201-tegra.cpio
  6. cd initrd
  7. cpio -vid < ../initrd-4.9.201-tegra.cpio
  8. cd lib/modules/4.9.201-tegra/kernel
  9. cd fs
  10. mkdir overlayfs
  11. cd overlayfs
  12. cp NANO/lib/modules/4.9.201-tegra/kernel/fs/overlayfs/overlay.ko .
  13. cd ~/scratch/initrd
  14. find . -print | cpio -ov > ../initrd-4.9.201-fixed-tegra.cpio
  15. cd ..
  16. gzip initrd-4.9.201-fixed-tegra.cpio
  17. mv initrd-4.9.201-fixed-tegra.cpio.gz initrd-4.9.201-fixed-tegra.img
  18. cp initrd-4.9.201-fixed-tegra.img NANO/boot
  19. Edit “`NANO/boot/extlinux/extlinux.conf”. Details below.

You default file “/boot/extlinux/extlinux.conf” will look approximately like this (probably slightly different since I’m looking at an NX and not a Nano):

DEFAULT primary

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

You will copy the “LABEL primary...APPEND...” to a new block, and edit it slightly. Then you will set the default boot device to the new LABEL. The only changes in that new block will be forLABEL”, “MENU LABEL”, and “INITRD”. Like this:

DEFAULT overlayfs

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

LABEL overlayfs
      MENU LABEL overlayfs
      LINUX /boot/Image
      INITRD /boot/initrd-4.9.201-fixed-tegra.img
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

Then you can reboot and it should load the new initrd. If it fails, then serial console can be used to pick the original kernel.

1 Like

Hmm. Are you sure with 5) and 6)? I think 6 first then 5, or?

I mean because of this:

root@ubuntu:~/scratch# gunzip < …/initrd.img-4.9.201-tegra > initrd-4.9.201-tegra.cpio
bash: …/initrd.img-4.9

Sorry, I mean because of this:

File not found
root@ubuntu:~/scratch# gunzip < …/initrd.img-4.9.201-tegra > initrd-4.9.201-tegra.cpio
bash: …/initrd.img-4.9.201-tegra: Datei oder Verzeichnis nicht gefunden

No, this doesn’t work after step 5… Checking…

OK, at least it boots now. But it is not read only. I touched a file after it was up (touch test) and power cycled the box (really off/on). The file was there.

And there is some confusion with the paths in your gist.

However, promising.

Going to bed now.

CU and many thanks. You are my hero :) But I recall I had this state already (with an earlier version and the lehni repo). All OK but not read only

Stop wait. I realized I made a couple of errors yesterday. In the end I did all the manipulations on my /loop/devXX, not on the real SD. So nothing really happened to the SD

However, applied the gist to my SD while doing it all on the Jetson Nano.

First I would like to point out some mistakes in 5, 6 and 7:

  1. After step 4 I’m still in ~/scratch and there is no …/initrd.img-4.9.201-tegra to gunzip, so I did this in step 5 instead

cd initrd

  1. Then the gunzip works in the new step 6 but step 7 needs to be changed to

cpio -vid < ./initrd-4.9.201-tegra.cpio

Is that correct?

At least I came through.

The boot behaviour now is exactly as like with the “lehni” script: Endless reboots.

Nothing won after all :(

Bootlog attached. You will notice the several rounds. Looks pretty much exactly as before

out.txt (71.6 KB)

When you are unpacking you first gunzip and redirect to a “.cpio” file name. When you actually unpack the .cpio file you want to be in a completely empty directory. Step 5 takes the initrd and simply decompresses it: The .cpio file is the same file, but without compression.

In steps 6 and 7 you will go to a completely empty location with no files in it, and then convert the .cpio archive into actual files.

This is actually two commands entered on a single command line:
gunzip < /initrd.img-4.9.201-tegra > initrd-4.9.201-tegra.cpio

This will first redirect the initrd through gunzip to decompress the initrd (the “<” redirects from the file to to gunzip, and after gunzip does its thing, that output goes to a new file with a “.cpio” filename suffix via the right “>”).

A single “.” in a file path is “the current directory”. Two periods “..” are “the parent directory of where you are now”. Note that if you have three decimal points, “...”, that this is a typographic error, and would be treated as a bad file name. Make sure to use exactly one or exactly two “.”. Three “...” is why it could not find the file in the parent directory.

If you are not using a clone, but have the entire SD available directly, then loopback can be skipped…I used loopback because I was working from a clone. Some people will be working with a clone, so it is useful to add that information.

Note that I performed the cpio unpack in an empty directory, with the source of the unpack being in the parent directory (two “..”, not one “.”). The reason for this is that unpack goes straight to your current directory. You’d end up repacking it with other content not intended to be part of the new initrd.

I see this in your log:

L4T boot options
1:e[6Cprimary kernel
2:e[6Cprimary kernel
Enter choice: 
Script done on Tue Mar 23 10:10:31 2021

This tells me the extlinux.conf was not fully edited. You have “primary kernel” twice. Can you post your current “/boot/extlinux/extlinux.conf”?

Well I know what … an . means, sorry.

But your receipt is simply wrong in that place:

I always start with a new scratch dir, so I do:

  1. mkdir -p ~/scratch/initrd

Then I cd to scratch.

  1. cd ~/scratch

I’m in scratch. Line 5) as outlined CANNOT work in no OS, since there is no “initrd.img-4.9.201-tegra” one directory up.

Otherwise I don’t know what I know. At least MY linux didn’t find it. Maybe yours…

Sorry, I saw the three “...” (versus “..”) in some of your file not found notes. I was typing from memory so I may have had something wrong in that set of instructions.

You are right, if you are in “~/scratch”, and the initrd.img-4.9.201-tegra is there, then you have to use “.” instead of “..”. I’ll correct that by editing the above. The important thing is that when you run the “initrd-4.9.201-tegra.cpio” through the “cpio” application you need to be in a completely empty directory.

Yes, I am usually in a completely empty directory.

Regarding the two “Primary”: I think I didn’t rename the MENU LABEL entry. War deciding? The proper section was loaded.

  1. cpio -vid < ../initrd-4.9.201-tegra.cpio

The two points also need to be removed, I guess

EDIT: Ah, no. OK

The three dots are created by this forum if you type 2. :)

I changed the label. Same endless boot loop