| 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 | }}} |