How to build your own Ubuntu Concept X Elite kernel

How to build your own Ubuntu Concept X Elite kernel packages

This is intended as a reference for people who want to test their own kernel package builds based on the qcom-x1e Ubuntu kernel we use in the concept image. There are multiple and possibly faster ways to build kernel binaries from our source tree. The one documented here is how the packages we ship in our images are built on launchpad.

Getting the source

The kernel source code is available via git on launchpad under the ~ubuntu-concept team.
To clone the source you can run:

$ git clone https://git.launchpad.net/~ubuntu-concept/ubuntu/+source/linux/+git/oracular \
  -b qcom-x1e linux-qcom-x1e
$ cd linux-qcom-x1e

Dependencies

Kernel build dependencies can be installed via the apt-get(8) build-dep command.
In the source code directory, run:

$ apt build-dep .

Configuration

The kernel configuration in Ubuntu kernel packages is managed using a custom mechanism called annotations. In our case it is stored in debian.qcom-x1e/config/annotations.

The easiest way to modify it is exporting it to .config with:

$ ./debian/scripts/misc/annotations \
    --arch arm64 --flavour qcom-x1e --export > .config

and then editing it locally using the usual commands like make nconfig.

The modified config can be imported back into the annotations file with:

$ ./debian/scripts/misc/annotations \
    --arch arm64 --flavour qcom-x1e --import .config
$ fakeroot debian/rules clean updateconfigs

For more information, see the kernel teams post on Ubuntu kernel configs.

Update the changelog

It is recommended to bump the package version for new builds to make apt happy when
trying to install the new packages.
The easiest way to do this is using dch(1):

$ dch -i -Doracular --upstream --changelog debian.qcom-x1e/changelog

Building

Before starting a build the annotations need to be cleaned up and the actual packaging
metadata files in debian/ need to be generated from our flavour specific templates in
debian.qcom-x1e/:

$ fakeroot ./debian/rules clean
$ ./debian/rules updateconfigs

After this the qcom-x1e kernel can be built locally using:

$ fakeroot ./debian/rules binary-qcom-x1e

Since this kernel supports arm64 only it needs to be build in an arm64 environment.

Installation

If everything goes well the binary packages end up in the parent directory.
They can be installed with apt or dpkg:

$ apt install \
    ../linux-image-unsigned-6.11.0-51-qcom-x1e_6.11.0-51.51_arm64.deb \
    ../linux-modules-6.11.0-51-qcom-x1e_6.11.0-51.51_arm64.deb \
    ../linux-modules-extra-6.11.0-51-qcom-x1e_6.11.0-51.51_arm64.deb
1 Like

Thanks for this write-up, helped quite a bit. Building a custom kernel is not well documented for newer Ubuntu versions. Did you build this on a Thinkpad t14s gen6? If I run the build on my t14s it always shuts down after some minutes under load. I guess it has something to do with power management or fan control.
Do you know, if I can also cross-compile the kernel? I tried setting ARCH=arm64 and CROSS_COMPILE=aarch64-linux-gnu-, but I can’t get it running.

@mlasch For cross compiling I would probably use something like sbuild(1). It manages temporary build chroots independent from your host system and can even create cross-arch chroots. There is a relatively simple guide to set that up in the Ubuntu wiki.

For cross building you would essentially mk-sbuild --target arm64 orcular and then follow the guide above and replace the build step with:

$ fakeroot ./debian/rules clean
$ sbuild --host=arm64
1 Like