6 | | To build a kernel with an initramfs configure the following kernel items: |
7 | | * CONFIG_INITRAMFS_SOURCE="/path/to/rootfs.cpio" |
| 8 | Note that the Linux kernel runs {{{/init}}}, {{{/sbin/init}}}, or {{{/bin/sh}}} (searched in that order) as PID1 from the initramfs (if it exists). If you want to run a different executable as PID1 you can use the {{{init=}}} kernel parameter. The init application must be executable and statically linked or it will move on to the next item in the search path. |
| 9 | |
| 10 | see also: |
| 11 | - https://docs.kernel.org/admin-guide/initrd.html |
| 12 | |
| 13 | == external initramfs |
| 14 | This is a ramdisk image (cpio, or compressed cpio if you have enabled ramdisk compression in your kernel) that you pass to the kernel when booting. If doing this with U-Boot its the 2nd (middle) arg to bootm/booti/bootz. |
| 15 | |
| 16 | To support this you need the following kernel config: |
| 17 | * CONFIG_INITRAMFS_SOURCE="" (No source defined!) |
29 | | == Building an initramfs == |
30 | | Here is a simple example of building an initramfs with a stand-alone application and some basic dev nodes as the only components in the rootfs: |
| 45 | To build a kernel with an initramfs configure the following kernel items: |
| 46 | * CONFIG_INITRAMFS_SOURCE="/path/to/rootfs.cpio" |
| 47 | * CONFIG_INITRAMFS_COMPRESSION_GZIP=y (optional) - or some other compression algorithm |
| 48 | * CONFIG_DEVTMPFS=y (optional) - to get devtmpfs support and provide a dynamic /dev |
| 49 | |
| 50 | |
| 51 | == Building an initramfs |
| 52 | There are several ways to create an initramfs |
| 53 | |
| 54 | === Using an initramfs_list config file |
| 55 | Here is a simple example of building an initramfs with a stand-alone application and some basic dev nodes as the only components in the rootfs using an initramfs_list conifg file and the Linux kernels {{{gen_initramfs_list.sh}}} script. This assumes you have a CROSS_COMPILE environment setup and a built linux kernel: |
| 56 | 1. cd to your built Linux directory (where the gen_initramfs.sh script needs to run from as it uses some built objects): |
| 57 | {{{#!bash |
| 58 | cd venice/bsp |
| 59 | . ./setup-environment # setup your cross toolchain |
| 60 | cd linux |
| 61 | }}} |
| 62 | 1. create a simple application that is statically linked such that it has no dependencies: |
62 | | For a more complete root filesystem take a look at [wiki:buildroot buildroot] |
| 96 | Take a look at the Linux [https://github.com/torvalds/linux/blob/master/usr/gen_initramfs.sh gen_initramfs.sh] script to see how it works for more info |
| 97 | |
| 98 | === Creating from scratch using a script and pre-built static busybox |
| 99 | You can create an initramfs from scratch fairly easy using a prebuilt status busybox as your base |
| 100 | {{{#!bash |
| 101 | # specify a location for our rootfs |
| 102 | ROOTFS=./rootfs |
| 103 | # create rootfs dir |
| 104 | mkdir -p $ROOTFS |
| 105 | for i in bin dev etc lib mnt proc sbin sys tmp var; do \ |
| 106 | mkdir $ROOTFS/$i; |
| 107 | done |
| 108 | # download a prebuilt static aarch64 binary of busybox and make it executable |
| 109 | wget http://mirror.archlinuxarm.org/aarch64/extra/busybox-1.36.1-1-aarch64.pkg.tar.xz |
| 110 | tar xvf busybox*.tar.xz usr/bin/busybox |
| 111 | mv usr/bin/busybox $ROOTFS/bin |
| 112 | # busybox takes the role of a large list of standard linux tools so anything we want or need here that it provides can by symlinked; note we use 'mount' below |
| 113 | ln -sf busybox $ROOTFS/bin/mount |
| 114 | # create a /init that mounts basic pseudo filesystems then executes a shell |
| 115 | cat <<\EOF > $ROOTFS/init |
| 116 | #!/bin/busybox sh |
| 117 | mount -t devtmpfs devtmpfs /dev |
| 118 | mount -t proc proc /proc |
| 119 | mount -t sysfs sysfs /sys |
| 120 | mount -t tmpfs tmpfs /tmp |
| 121 | |
| 122 | echo "Hello busybox!" |
| 123 | sh |
| 124 | EOF |
| 125 | chmod +x $ROOTFS/init |
| 126 | # create a compressed cpio archive |
| 127 | (cd $ROOTFS; find . | cpio -ov --format=newc) | gzip -9 > cpio |
| 128 | }}} |
| 129 | |
| 130 | Note that we use gzip compression here (which is completely unnecessary for such a small cpio) so your kernel must have CONFIG_INITRAMFS_COMPRESSION_GZIP=y |
| 131 | |
| 132 | === buildroot |
| 133 | For a more complete and easy to build root filesystem take a look at [wiki:buildroot buildroot]. |
| 134 | |
| 135 | Example: |
| 136 | {{{#!bash |
| 137 | # clone buildroot |
| 138 | git clone http://github.com/buildroot/buildroot.git |
| 139 | cd buildroot |
| 140 | # create the most basic ARM64 rootfs with a gzip cpio filesystem |
| 141 | cat << EOF > configs/minimal_arm64_ramdisk_defconfig |
| 142 | # arm64 arch |
| 143 | BR2_aarch64=y |
| 144 | # filesystem options |
| 145 | BR2_TARGET_ROOTFS_CPIO=y |
| 146 | BR2_TARGET_ROOTFS_CPIO_GZIP=y |
| 147 | EOF |
| 148 | # build it |
| 149 | make minimal_arm64_ramdisk_defconfig |
| 150 | make |
| 151 | ls -l output/images/rootfs.cpio.gz |
| 152 | }}} |
| 153 | |
| 154 | While the above creates a full features Linux if you want to add your own bootstraping script in front you can simply override /sbin/init or add your own /init (as its looked for first) to the buildroot output/target directory and rebuild the image: |
| 155 | {{{#!bash |
| 156 | # add a simple /init script |
| 157 | cat <<EOF >output/target/init |
| 158 | #!/bin/busybox sh |
| 159 | mount -t devtmpfs devtmpfs /dev |
| 160 | mount -t proc proc /proc |
| 161 | mount -t sysfs sysfs /sys |
| 162 | mount -t tmpfs tmpfs /tmp |
| 163 | |
| 164 | echo "Hello buildroot!" |
| 165 | sh |
| 166 | EOF |
| 167 | chmod +x output/target/init |
| 168 | # build again to regenerate the rootfs |
| 169 | make |
| 170 | ls -l output/images/rootfs.cpio.gz |
| 171 | }}} |