First version 2016.09.13
Rev 2016.09.18
Background
I started this page as a guide for others who wanted to build the 64-bit kernel for Fedora 24. However, the page had a short lifetime of usefulness -- some problems that prompted me to recompile were corrected by Kraxel in bringing the update to kernel 4.7.3-2-main of 64-bit Fedora 24. But other problems continue even with the corrected updates and in recompiled kernels. So I'll leave the page around (and try to keep it updated) for those who might need to build the kernel on the RPi-3 in the future.I installed 64-bit Fedora 24 on a Raspberry Pi-3B using Will Foster's guide for the 32-bit version as a procedural outline [ https://hobo.house/2016/03/13/installing-fedora-linux-on-the-raspberry-pi-3/ ]. The FC24 distribution repository version at kraxel.org, dated 20160623, installs 4.6.2 of the kernel. After installing FC24 on a Raspberry Pi-3B, with a resulting system that was reasonably functional, I did a "dnf update" that brought the system to kernel 4.7.1 (initially -- now 4.7.4) and resulted in at least one key component (polkit) not functioning. SirSpudd identified the problem as a change in a kernel configuration parameter (VA_BITS set to 48 rather than 39) and reported that by recompiling the kernel with the original value (39), the polkit (and other) errors were resolved. He also noted that it might be some time before that correction migrated into the mainstream distribution.
And he provided instructions for compiling (cross-compiling in his case) and installing the corrected kernel. It looked fairly straightforward, so I thought I'd try it to see if the corrected kernel would eliminate some of my problems.
It has been a while since I'd compiled a Fedora kernel, and compiling for the Raspberry Pi booting environment (in which the graphical coprocessors actually load the ARM OS code) makes this installation a bit more complicated.
The result was a painful (re-)learning experience, but I did eventually compile and install a kernel that would actually boot and run Fedora 24. And it eliminated the polkit memory addressing crashes that had made some of the Fedora services inaccessible. It did not eliminate all my problems, but they may be caused by other issues: the obvious problems were resolved.
So, in case others get to the point where they need to compile and install the 64-bit Fedora kernel, here is an expanded version of SirSpudd's instructions, modified slightly since I compiled on the RPi3 itself rather than cross-compiled.
My Pi-3 Configuration
In case my documentation below is confusing, it might help to know the environment in which my Pi-3B operates:- RPi-3B running 64-bit Fedora 24 (see part 2 of this blog to set that up)
- Boot to a Samsung 32GB µSD with FC24 and three partitions: /boot, /swap, and /
- Logitech K400r wireless single-unit keyboard+trackpad -- uses a USB port of the Pi-3 (the only device on the USB system)
- Samsung HDMI TV as display -- also supplies the power to the Pi-3 through its 1A USB port
- Wired Ethernet connection to Cisco Powerline adapter (when needed)
- Mac Mini as remote computer when needed (used to access RPi-3 via ssh/sftp)
- WiFi connection to Cisco Powerline adapter (once it is configured)
Context
I installed 64-bit Fedora 24 on the Pi-3 (part 2 of this blog). I worked in multi-user mode (terminal) rather than graphical mode.I followed SirSpudd's guide (reference hobo.house link above) except that I did a native compile on the RPi-3 rather than a cross-compile. The RPi-3 is fast enough that with a quad-core system the compilation of the kernel requires about 50 minutes (wall clock). I decided it would be more efficient (in my time) to build it on the RPi-3 than to install, configure, and then learn about cross-compiling on my Mac.
The process is mostly automated and quite straightforward, except at the final installation, where the make file misses some steps that are likely unique to the Raspberry Pi booting environment. I haven't tried to amend the make file -- I just handle the steps manually (since I don't expect to do this often!).
Preparation
To start this process, you'll download a .rpm file with the source code for the kernel. You'll need to then unpack and apply any patches before configuring and compiling the kernel. To unpack, you can use "bsdtar" (which is not the same as "tar"; "tar" doesn't know how to read .rpm files). And you'll need "patch". You'll also need to have installed compilers and development headers, if you haven't done so. So here are the steps you'll need to do in preparation for the real work:- Connect your Pi-3B to the Internet (Ethernet or WiFi).
- Log into your own account.
cd
(to connect to your home directory)sudo dnf install bsdtar patch ncurses-devel
sudo dnf groupinstall "system tools" "C development tools and libraries"
Procedure
You'll need root access for a few of the steps, but most of this process is done in non-privileged mode from your own account. Don't put your system at risk by doing this as root.- Log into your own account.
Don't su. You may want to do this from a remote computer via ssh into your RPi-3. The kernel source download is about 140MB and may take a while to download. The kernel compile itself takes about 50 minutes. So you may want to be doing something else while waiting for those tasks to complete. - Make a directory for the build and connect into it.
cd; mkdir FC24; cd FC24
- Get a copy of the source repository.
dnf download --source kernel-main
kernel-main-4.7.4-2.src.rpm
. Next you'll unpack that .rpm distribution file, then unzip and unpack the .tar file that contains the source code. - Unpack the .rpm file and extract its contents:
bsdtar -xvf kernel-main-x.x.x-x.src.rpm
gunzip linux-x.x.x.tar.gz
tar -xf linux-x.x.x.tar - Next apply the patches to that source code (in the linux-x.x.x directory):
cd linux-x.x.x
cat ../*.patch | patch -p 1 - Make sure to start with a cleaned-up source tree:
make mrproper
- Get a copy of the .config file that generated your running OS:
zcat /proc/config.gz > .config
- Make/remake the
.config
file
I believe thatmake
wants to validate the configuration and write its own copy before you can actually start building the kernel. If you just do amake
, it'll run the configuration program and then start the build. But you might want to double-check the.config
file before starting the hour-long build, so I've divided this into steps. The simplest approach is to simply validate the.config
file, verify it visually, and then do themake
. If you want to usemake menuconfig
here instead so you get an item-by-item check-box-style menu for selecting configuration parameters, you'll needncurses-devel
to have been installed, and we already did that under Preparation. So this step is simply:make oldconfig
make menuconfig
. At the end of this step, the configuration program will tell you that it has written the configuration to.config
. - Label your kernel and verify the
.config
file.
You'll want to give your kernel a local version number that identifies it as yours rather than from the repositories, and you may want to verify some of the parameter settings. I went through this exercise because VA_BITS was set to 48 rather than 39, so I check the.config
file to verify that the parameter is set correctly before proceeding with the build. At the very least, edit the file, locate the stringCONFIG_LOCALVERSION=
, and change the distribution value (something like"-2-main"
) to an identifying string in place of "main" that will be unique to you (something like"-2-yih3"
-- using Your Initials Here and a sequence number). While you're in the file, you might check around to confirm that other parameters are set as you intended, but don't arbitrarily change parameters: Go throughmake menuconfig
if you want to make other changes as there may be inter-dependencies of which you're unaware. - Build the kernel
I like to track the time it takes to build the kernel, so Itime
the build. Omit it if you don't care. Since the RPi-3 has 4 cores and I don't do any other work during the build, I tellmake
to keep 4 streams running (the-j 4
part).time make -j 4
- Make the modules
make modules
- Install the kernel and modules (most of it)
This part has to be done as root, hence thesudo
's.sudo make modules_install
sudo make installls /boot
, you'll see some files there identified with your unique identifier (e.g.,"-2-yih3"
). Ditto if you check /lib/modules.
But unfortunately themakefile
misses a couple of steps for the RPi, and we need to finish up manually. The key parts are:- Copy the device tree directory from the build tree to /boot
- Copy the
bcm2837
device tree file to a place bootcode will find it - Edit
/boot/extlinux/extlinux.conf
to have bootcode let you choose your new kernel when doing the boot
Kraxel pointed out that there are a couple of lines we can add to/boot/extlinux/extlinux.conf
that will allow you to choose at boot time the kernel you want to run. We'll install two lines at the beginning of that file, just once, and then we can choose whether to boot our new kernel or revert back to the older, distribution version -- always a helpful feature in case your new version doesn't boot correctly. With yourLOCALVERSION
identifier that you edited into the.config
file, the build process created a boot image and related files with a corresponding unique image identifier, something like4.7.3-2-yih3
, that includes the kernel version from the distribution appended with your unique identifier. Key files and directories will use that identifier in their names. In the steps below, we'll use the string"<imageid>"
. Use your unique image identifier,4.7.3-2-yih3
or whatever, wherever you see"<imageid>"
below. - Copy the device tree and bcm2837 .dtb file to expected locations
cd /boot/dtbs
sudo mkdir <imageid>
cd <imageid>
sudo cp -rL <your home>/FC24/linux-x.x.x/arch/arm64/boot/dts/* .
sudo cp broadcom/bcm2837-rpi-3-b.dtb . - Tell bootcode about the new kernel
sudo edit /boot/extlinux/extlinux.conf
label kernel-4.7.3-2-main
kernel /vmlinux-4.7.3-2-main
initrd /initramfs-4.7.3-2-main.img
fdtdir /dtbs/4.7.3-2-main/
append dwc_otg.lpm_enable=0 console=ttyAMA0,115200 \
console=tty1 elevator=deadline root=/dev/mmcblk0p3 \
rootfstype=ext4 rootwait
menu title pick kernel
timeout 100
Now go to the bottom of the file and insert the description of your new kernel with your unique identifier (something like 4.7.3-2-yih3) in place of <imageid>:
label kernel-<imageid>
kernel /vmlinuz-<imageid>
initrd /initramfs-<imageid>.img
fdtdir /dtbs/<imageid>/
append dwc_otg.lpm_enable=0 console=ttyAMA0,115200 \
console=tty1 elevator=deadline root=/dev/mmcblk0p3 \
rootfstype=ext4 rootwait
NOTE that the last line ("append ...") should all be on one line of the file (no continuation "\").
ALSO NOTE that the kernel file is named vmlinuz rather than vmlinux: themake install
gets the compressed boot file and names it as a compressed image when it copies it to /boot. -
- Double check
cat /boot/extlinux/extlinux.conf
and make sure that each of the files or directories mentioned in the section for your kernel is actually in place in /boot, and make sure that the kernel module directory is in place as /lib/modules/<imageid>. uname -a
and make sure the name string has your <imageid> in it.- If it booted up but didn't boot into your kernel, repeat the double-check in 16: typographical errors are easy to make but fatal to the boot process.
- If it appears that everything is in place but your kernel isn't coming up, watch the beginning of the boot process carefully to see if you can determine which step is failing, then correct it.
- If the boot process is hanging completely when you specify your kernel, reboot by power cycling and select a distribution kernel (rather than the one you just built). Again, do the double-check in 16. If there are no typos, review your configuration (make menuconfig) to make sure you have a valid configuration. Compare your .config with /proc/config.gz to identify inadvertent changes. And, finally, go back to "make mrproper" and start again.