jasonwryan.com

Miscellaneous ephemera…

Automating Kernel Builds

I posted a couple of weeks ago about compiling a custom kernel using modprobed_db and at the time I talked about automating the process, essentially so that every kernel update, be it the standard Arch kernel or the stripped down custom one, would be a simple, streamlined process. I updated that post with a PKGBUILD, which was the first step. This completes that process.

There is not a lot to it. A short bash wrapper that sets up the required files, updates the aforementioned PKGBUILD and then triggers makepkg (providing nothing else fails). All it requires is that you have the necessary files in a separate directory for the script to reference and you are set. If anything does go wrong with the new kernel, you still have the previous working custom kernel .tar.xz you can reinstall, or you can of course just boot into the vanilla Arch kernel.

new_kernel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env bash
# install new kernel

vers=$1
cyn=$'\e[1;36m'
ylw=$'\e[1;33m'
red=$'\e[1;31m'
end=$'\e[0m'

if [[ $# != 1 ]]; then
  printf '%s\n' "Usage: "${0##*/}" 3.10.8"
  exit 1
fi

# back up last dir
cd ~/Build
rm -rf linux-jwr/{pkg,src}
mv linux-jwr linux-${vers%.*}.$((${vers##*.} - 1))

# set up clean files
cp -r kernel_files linux-jwr && cd "$_"

sed -i "s:pkgver=[0-9].*:pkgver=${vers}:" PKGBUILD
newvers=$(awk -F= '/pkgver=/ {print $2}' PKGBUILD)
printf '%s\n' "Package version updated to ${ylw}$newvers${end}"

printf '%s\n' "${cyn}Updating checksums…${end}"
/usr/bin/updpkgsums

if [[ $? -eq 0 ]]; then
  printf '%s\n' "${cyn}Starting build…${end}"
  /usr/bin/time /usr/bin/makepkg -i
else
  printf '%s\n' "${red}Checksum failed${end}"
  exit 1
fi
cd

That’s all there is to it. I see in my RSS reader that a new stable kernel is available, open a terminal and run the script specifying which version to use, for example, new_kernel 3.10.9. Approximately 10 minutes later, my new kernel is compiled and installed and I can reboot into it. Simple.

Undoubtedly, there is probably a cleaner way to do this, but it has worked well for the last couple of kernels. It will probably also require tweaking for the next series, but until that time, I am quite happy with it.

Notes

Flickr creative commons image My robot by fringley.

Terminal Conditions

One of the almost inevitable consequences of using Arch Linux for any length of time is that you will find yourself, if you weren’t already, sucked into the gravitational vortex of the command line. The drive to continually understand, refine and customize your setup, your workflow and the tools you use on a daily basis will surely lead you to the point where you go from having one of those dinky terminal emulators that scrolls down when you hit F12, to waking up one day after yet another sleepless night trying to get your head around C or Haskell—so that you can hack your tiling window manager to manage the dozen or so terminals you constantly have open to your increasingly exacting specifications…

Once you resign yourself to this inevitability, it is a natural progression to invest some time in setting up your terminal so that it is a pleasant, productive environment. The first step is to choose your terminal emulator. After playing with a few, I have settled on rxvt-unicode. Urxvt has a number of nice features, principally the ability to run in daemon mode and, when combined with Bert Münnich’s urxvt-perls extension, to be able to interact with text and URLs with the keyboard.

I have also, over the last two or three months, been intermittently using termite; the VTE-based terminal developed by Daniel Micay and Simon Gomizelj.

The next step is to select a colour scheme that, after long hours of peering at the screen, won’t leave you with the eyesight of a mediæval monk. I have settled on a dark scheme that is relatively low contrast, so works well in natural and artificial light.1 Combine this with a custom Vim colourscheme for syntax highlighting, and you have the base for a consistent aesthetic experience in your terms.

The cornucopia of choice that is GNU/Linux means that in addition to choosing your font, you also can choose how it is rendered. I use the infinality patchset, but if you are looking for a pre-rolled version I can highly recommend bohoomil’s infinality bundle.

The final element—and probably the most important—is the actual shell that you will run in your terminals. Bash is installed everywhere (or, more correctly, everywhere that matters), so that is a solid choice. If you are looking for a lot more power and flexibility, then you want Zsh (with the syntax highlights plugin).

If, on the other hand, you are the sort of person with tribal piercings and a fixie, you might want to look at tcsh, or even csh2.

Customizing your shell can, in this context, be extended to practically Escheresque extremes. The prompt, particularly in Zsh, can print relevant information, helpfully colour coded; but it can also metastasize into a bloated ratmangle of unicode, complete with git branches, the weather in four different timezones and random fortunes. If, through some inexplicable turn of events, you find yourself staring at something like this, it is time to seek help. Urgently.

For Zsh, I have the hostname (to avoid confusion when SSH'ing between machines, the current working directory and, if the exit status is anything other than 0 for the last command, that status is appended.

There is one other important choice to make in your shell: to run it in emacs mode (the default) or vi-mode. This decision says as much about your competence as it does about your overall contribution to the gene pool, so consider it carefully. I have previously expressed my preference for vi-mode, and using Zsh (which doesn’t use readline) has just entrenched that view for me.

Putting it all together, you end up with an interface that is as attractive to work with as it is powerful. You have syntax highlighting, command completion (and with Zsh, impressive correction), coloured URLs that can be activated with the keyboard, the ability to copy and paste between terminals and into documents or browsers, configurable keybinds, aliases and functions limited only by your imagination and the threshold of your indolence.

One final recommendation: consider using a terminal multiplexer like tmux to manage your terminal sessions. I have posted quite a bit about it in the past and it continues to be a mainstay of my working environment. The Arch Wiki, naturally, has some very detailed pages on each and every aspect of using the terminal. All of my configs are available in my bitbucket repositories: bitbucket.jasonwryan.com.

Notes

  1. My dark colour scheme is in my bitbucket repo.
  2. Then again…

Compiling Kernels

While chasing edits on the Arch Wiki a couple of weeks ago, I stumbled upon this page: Kernels/Compilation/Traditional; fortuitously, it transpired. For it piqued my interest sufficiently for me to try my hand at compiling my own kernel, and—after half a dozen attempts at getting it right—I had no sooner switched to my custom built kernel as the default in my boot manager when 3.10.2 landed in [testing] and would not boot. At all.

I still have no idea why 3.10.2 would do nothing other than fail silently, but the convenience of having another kernel to switch to without needing a rescue image or any other panicked interventions immediately won me over. In the years that I have used Arch, this was my first near brush with an unbootable system1 and the small amount of effort required to mitigate this risk with a custom or alternate kernel seems a smart investment to me at this point.2

The documentation on the wiki is both comprehensive and easy to follow. The lessons I learned between kernels zero and three or four were mostly around ensuring the correct modules were configured into the build. One surefire way to make this a tedious and laborious process, should you be so inclined, is to blindly enable and disable settings in menuconfig.

Around about the time of the fourth failed build (well, the builds were working but the kernel wasn’t booting or was booting with missing functionality), I decided to switch approaches and go down the localmodconfig route. This, for someone with my limited experience with this aspect of GNU/Linux, was in retrospect a decision I should have made sooner.

First, I started with streamline_config.pl, a helpful script that allows you to create a .config file containing only those modules necessary to your currently running kernel3. This yielded a booting kernel at the first attempt. It turns out, though, that you still need to ensure that all of the modules you are going to need, at any time in the future, are loaded. I missed a couple.

Then I discovered this script by graysky, modprobed_db. For a newbie to kernel compilation, this is simply invaluable. It allows you to create a record of your used modules over time, compare it with those that are currently loaded and then—right before you make localmodconfig—load the remaining necessary ones. Foolproof kernel compilation. Just like that. Brilliant. And, naturally enough, it is in the AUR.

Run the script, create your .conf file and database in $XDG_CONFIG_HOME/modprobed_db{,.conf} and then either call it from a cron job or, if you are impatient like me, spend a frenzied 10 minutes plugging ALL the devices you own into your machine, and you are good to go. Running sudo modprobed_db recall will load all of the required modules, you generate your kernel .config, check it to make sure it is complete and then run make.

On my laptop, I have 115 modules activated for a build, 10 of which need to be recalled prior to creating the .config. When I was trying to debug 3.10.2, I compiled the vanilla Arch kernel using ABS and it took almost exactly 60 minutes using all four threads on my i5. Building my own kernel is done and installed in under 10.

I susbcribed to the RSS feed for kernel versions and now, whenever a new stable kernel is posted, I wget it, compile it and boot from it. As new Arch versions appear in the repositories, they are updated by pacman and happily coexist on my /boot; thereby ensuring that the likelihood of me being unable to boot my machine (other than through PEBKAC) has hopefully been staved off for another five years.

The next step would be to write a script that completely automates the process…

Update 7/8/13

After poring over PKGBUILDS in the AUR, principally graysky’s linux-ck PKGBUILD, and the official ABS PKGBUILD, I decide to write my own to automate the above. It works well enough for me, but hasn’t been tested more widely. You will need to ensure that you have an up-to-date modprobed_db database with all of your required modules listed and that you have configured sudoers to have this run from the PKGBUILD.

The PKGBUILD and the attendant files are in my bitbucket repo: let me know if there are any issues with this approach.

See also the follow up post on automating this process: Automating Kernel Builds

Notes

  1. Other than those occassions for which I bear complete responsibility…
  2. There are, of course, other benefits such as the self-satisfied glow of geek accomplishment.
  3. This is located in scripts/kconfig/.

Creative Commons image of kernels on Flickr by Nadia Prigoda-Lee.