# Compiling kernel on tmpfs

## niick

Hey guys, I want to compile the kernel on tmpfs (in memory) to avoid disk writes.  Motivation is that I just had an ssd die, presumably from too many writes and I just upgraded to 32GB of RAM  :Smile: 

I have portage on tmpfs but obviously the kernel is built in;

```
/usr/src/linux
```

.

I don't want to lose the kernel on a reboot.  Is anyone doing this or can suggest a method that would work?

----------

## eccerr0r

Likely your SSD did not die from too many writes, you got a dud drive unless you were *really* abusing it, or bought an abused drive.

If you truly want to save the data you'll need to rsync it back and forth.  However you might well just run it on SSD, don't worry about it, all my kernels are compiled on SSD directly.

----------

## niick

Yeah, it's probably paranoia but I'd had it a long time and just put it down to writes.  Ignoring that I was looking for a method of building the kernel on tmpfs for the same rational as putting portage on tmpfs.

----------

## niick

Having done some googling I found this; https://stackoverflow.com/questions/15969694/make-o-files-in-separate-folder-in-linux-kernel-compilation.

I guess this would work for me, I'd just end up compiling the entire kernel again even if I just made small changes to included modules and such.

Anyone got any experience of this??

----------

## Anon-E-moose

I've built the kernel on tmpfs, but I run a script after installing modules

For example, I copy /usr/src/linux-5.0 to /tmp/linux-5.0, I go to /tmp/linux-5.0 build everything, install everything then run this script

```
kdir=`basename "$PWD"`

lmdir=`cat include/config/kernel.release`

cd /lib/modules/$lmdir

rm build source

ln -s /usr/src/$kdir build

ln -s /usr/src/$kdir source
```

Edit to add: it's not that I worry about too many writes (/usr/src is on an ssd) but it's faster to compile from tmpfs.

ETA2: before I do the copy to tmpfs I do all my configuring on the disk based kernel sources, I just use the tmpfs for compiling.

----------

## Hu

I do out of tree builds so that I don't need to build as root.  It works fine.

----------

## Anon-E-moose

 *Hu wrote:*   

> I do out of tree builds so that I don't need to build as root.  It works fine.

 

I don't use portage for kernels, I prefer to do it myself.

I do the building/compiling kernel and modules as my user, but become root/sudo for installation of kernel and modules.

----------

## DaggyStyle

here is my script that does this exactly, feel free to try

```

#!/bin/bash -x

function exe() {

        local cmd="$1"

        eval "${cmd}"

        if [ $? -ne 0 ]; then

                echo "run failed on cmd: ${cmd}"

                exit 1

        fi

}

KERNEL_SRC_PATH="/usr/src/linux"

KERNEL_TARGET=$(eselect kernel list | tail -1 | awk '{print $1}' | sed 's/[][]//g')

exe "eselect kernel set ${KERNEL_TARGET}"

FULL_KERNEL_LABEL="$(basename $(eselect kernel show | tail -1))"

KERNEL_VERSION="$(echo ${FULL_KERNEL_LABEL} | sed "s/-gentoo$//g;s/^linux-//g")"

MNT_POINT="/tmp/kernel"

exe "mkdir -p ${MNT_POINT}"

exe "mount -t tmpfs -o size=1G tmpfs ${MNT_POINT}"

exe "zcat /proc/config.gz > ${MNT_POINT}/.config"

exe "make -C ${KERNEL_SRC_PATH} O=${MNT_POINT} oldconfig"

exe "make -C ${KERNEL_SRC_PATH} ${MAKEOPTS} O=${MNT_POINT}"

exe "make -C ${KERNEL_SRC_PATH} ${MAKEOPTS} O=${MNT_POINT} modules_install"

exe "mount /boot/"

exe "cp ${MNT_POINT}/arch/x86/boot/bzImage /boot/kernel64-${KERNEL_VERSION}.img"

exe "GRUB_USE_LINUX_LABEL=true grub-mkconfig -o /boot/grub/grub.cfg"

exe "umount /boot"

exe "emerge @module-rebuild"

exe "cp -v ${MNT_POINT}/.config /usr/src//linux/config"

exe "umount -l ${MNT_POINT}"

exe "rm -rf ${MNT_POINT}"

exit 0
```

----------

## Hu

 *DaggyStyle wrote:*   

> 
> 
> ```
> #!/bin/bash -x
> 
> ...

 Why not just use set -e and let it handle aborting?  This would also get you out of using eval, which is wrong here since it causes double expansion of variables.  If you want to keep the wrapper, you could remove the double expansion by writing it as:

```
function exe() {

   "$@" || { local rc=$?; echo "run failed on cmd: $@" >&2; exit $rc; }

}
```

If you make such a change, remove the double quotes in the caller and let the word splitting happen there.  As an alternative, which is needed to support the lines where redirection is used, switch to single quotes in the caller and retain your definition of exe.  Personally, I like letting set -e handle the early exit.

 *DaggyStyle wrote:*   

> 
> 
> ```
> KERNEL_TARGET=$(eselect kernel list | tail -1 | awk '{print $1}' | sed 's/[][]//g')
> ```
> ...

 This will return the string (none if there are no valid kernels available.  You can simplify the existing expression to use just sed:

```
eselect kernel list | sed -n -e '${s/^\s*//;s/\s.*$//;s/[][]//g;p}'
```

 *DaggyStyle wrote:*   

> 
> 
> ```
> KERNEL_VERSION="$(echo ${FULL_KERNEL_LABEL} | sed "s/-gentoo$//g;s/^linux-//g")"
> ```
> ...

 This could be done using bash variable expansions.

```
KERNEL_VERSION="${FULL_KERNEL_LABEL%-gentoo}"

KERNEL_VERSION="${KERNEL_VERSION#linux-}"
```

 *DaggyStyle wrote:*   

> 
> 
> ```
> exe "mkdir -p ${MNT_POINT}"
> ```
> ...

 mkdir -p does not fail when the target exists.  This may produce surprising results if the directory /tmp/kernel already exists and has content you would like to keep.

 *DaggyStyle wrote:*   

> 
> 
> ```
> exe "mount -t tmpfs -o size=1G tmpfs ${MNT_POINT}"
> ```
> ...

 By default, tmpfs is world writable and sticky.  This is probably not what you want here.

 *DaggyStyle wrote:*   

> 
> 
> ```
> exe "make -C ${KERNEL_SRC_PATH} O=${MNT_POINT} oldconfig"
> 
> ...

 These steps will run as root, but that permission is not necessary. *DaggyStyle wrote:*   

> 
> 
> ```
> exe "cp -v ${MNT_POINT}/.config /usr/src//linux/config"
> ```
> ...

 Why not use $KERNEL_SRC_PATH here?

Note that if the script exits early, the user must manually apply any remaining cleanups that would have happened on a successful exit.

----------

## pjp

 *niick wrote:*   

> Having done some googling I found this; https://stackoverflow.com/questions/15969694/make-o-files-in-separate-folder-in-linux-kernel-compilation.
> 
> I guess this would work for me, I'd just end up compiling the entire kernel again even if I just made small changes to included modules and such.
> 
> Anyone got any experience of this??

  I combine tmpfs (writing) with squashfs (saving). The squashfs also helps for programs that expect kernel files to be available. Although I sometimes just let the buld process make assumptions about the running kernel. I need to get back to making my script more complete.

----------

## DaggyStyle

 *Hu wrote:*   

>  *DaggyStyle wrote:*   
> 
> ```
> #!/bin/bash -x
> 
> ...

 

well, it was a script I wrote in 5 minutes which is working well, writing a proper one is on my todo list

----------

