Notes from building a minimum Linux Gentoo Kernel for a Raspberry Pi

Recently I have been working with more and more Raspberry Pi single board computers and as a person who likes the Linux Gentoo distribution I got the urge to make a bare minimum kernel.  These are basically some notes based on what I have learned trying to build a bare-bones custom kernel for the Raspberry Pi.

If you find issues with this kernel config, or find something I missed, please let me know in a comment so I can take a look into it and update information.

I am not going to go quite into detail how to build a kernel and such, this guide is just a reference to what drivers I found are necessary for a bare bones kernel, without any extra drivers.  The only extra things I think I added is for some USB-Serial drivers, since they are required for my application, they can be safely removed.

This is using the Raspberry Pi kernel sources sys-kernel/raspberrypi-sources-4.19.9999, emerge or update this before proceeding.  Also to note, this is for a 32-bit kernel.  I have not been able to get this to work on the new Raspberry Pi 4 yet, it just won’t boot… I will try to figure out why at a later date.

https://www.drassal.net/downloads/config_4.19.86_201912041613

The version that I have installed now is 4.19.86, and this configuration is for that version.  You should be able to use this with newer kernel versions, just use make oldconfig before using make menuconfig.

I started with a minimum kernel with almost no drivers included, and slowly added the drivers necessary to obtain the functionality required, trying to get drivers for all the hardware on the board.  This process of building, checking, rebuilding took several full days and I would like to document what I found out is the minimum install necessary.

I am not quite confident the sound drivers are correct yet, but will hopefully get a chance to test this in the future.

This kernel config posted here works with the following hardware, since it is what I had on hand to test with:
+ Raspberry Pi Zero W
+ Raspberry Pi Zero WH
+ Raspberry Pi 3 Model B
+ Raspberry Pi 3 Model B Plus

In order to get the display to work right on the Raspberry Pi Zero W I had to edit the config.txt file on the boot partition and uncomment this line at the bottom… not sure why yet… only the Raspberry Pi Zero W appears to need it.

[all]
dtoverlay=vc4-fkms-v3d

I started working with a Raspberry Pi 3 Model B, then after that was working moved onto testing on the Zero W and 3 Model B Plus.  Below is some detail of things I found to be specific to a specific platform…

Device Drivers – Network Device Support – USB Network Adapters – Multi-purpose USB Networking Framework – SMSC LAN95XX based USB 2.0 10/100 ethernet devices
+ Wired ethernet for Raspberry Pi 3B

Device Drivers – USB support – Synopsis DWC host support
+ USB for Raspberry Pi Zero W

Device Drivers – Network Device Support – USB Network Adapters – Microchip LAN78XX Based USB Ethernet Adapters
+ Wired ethernet for Raspberry Pi 3B Plus

Device Drivers – Network Device Support – Wireless LAN – Broadcom devices – Broadcom FullMAC WLAN driver
+ Wireless LAN driver

Device Drivers – Network Device Support – Wireless LAN – Broadcom devices – SDIO bus interface support for FullMAC driver
+ Wireless LAN driver support

Bringing a 6 year old DreamPlug (arm based) Gentoo installation up to date…

I am posting these notes on my blog hoping it is useful to someone in the future… and saves someone the 3 days it took me to come to these conclusions.

This is a post in progress so I will update this again a little later, it may have a few mistakes for the time being.

I had a very old (from the year 2013) Gentoo install on a ARM based GlobalScale DreamPlug and wanted to bring it up to date (as of 2019-08-23).

The first thing that needs to be done is to bring the package manager, portage (emerge), up to date which was a little tricky due to dependencies. The idea here is to install the absolute minimum required to get portage up to date, then use the new portage to bring the rest of the system up to date.

In order to update portage, an update to python is absolutely required, which means filling the requirements of python… some side stepping can be done to achieve this, which I had to do. One of the annoying roadblocks was the EAPI requirement, which this current setup was at ‘5’, but the latest python needs ‘6’ or ‘7’ to update… which in turn is needed by portage.

We have to solve this chicken and egg problem, so after a lot of trial and error I resorted to the very unconventional method of editing the portage tree of the packages I needed to update and decreased their EAPI to 5, hoping nothing would break… and for the required packages it worked nicely. Just make sure you resync your portage tree after to erase all these ‘hacks’ that are needed.

After each successful time consuming step I performed a complete tar backup of the system so I could recover to that step if I messed up the system, and I have done that multiple times already.

The following tar commands can be used to create an archive in that case…
Be careful with copy paste… it might miss some of the dots or double hyphons.

Backup command

sudo tar -jcvpf ~/dev_dreamplug/dreamplug_rootfs_2019-08-21.tar.bz2 --directory=/media/dreamplug-000/ --exclude=/proc/* --exclude=/dev/pt --exclude=/tmp/* --exclude=/.Trash* --exclude=/original .

Format command (to clean the partition and prep it for a restore, I don’t remind everyone that this will delete everything on it… do I?)

sudo mkfs -t ext3 -L dreamplug-000 /dev/sdb2

Restore command

sudo tar -xjpf ~/dev_dreamplug/dreamplug_rootfs_2019-08-21.tar.bz2 --directory=/media/dreamplug-000

 

After these are updated, install new portage (emerge) and the rest of the updates will be easier to resolve once portage is up to date.
Most of the trouble arises from the EAPI flag, which this old version of portage is a ‘5’ but all the new emerges require a ‘6’ or ‘7’, this blocks the emerge on several packages, although the necessary packages emerge just fine with this old version of portage.

Since portage will attempt to rebuild the manifest with our changes, if we want to edit ta single .ebuild file, we have to edit all in the folder since it will attempt to rebuild the manifest… and it won’t recognize a EAPI greater than 5 when it does this. This means all .ebuilds in a single folder will have to have their EAPI changed to 5. Don’t worry it will all revert when we do an emerge –sync to erase all our nasty hacks.

One downside to editing the portage tree is that the digest CRC check will fail since the package has been edited. We can bypass the digest check by adding the –digest flag to the emerge command.

This change to the portage tree is only temporary and as soon as portage is up to date, it is recommended to revert or resync the portage tree to reset everything back. Once the new portage is installed the EAPI changes will not be required as the new portage is EAPI 7 compatible.

Go ahead and sync the portage tree now, my portage tree was mounted to /usr/portage from a squash filesystem (read only) to save space, so I had to copy out the contents, unmount the /usr/portage, and move contents into the new empty /usr/portage directory.

emerge –sync

You will have to reselect the profile, in my case I chose 1
eselect profile set 1

Below, change EAPI to 5 in all the .ebuilds in the below folders…
We should all know this is not the best way of doing things, but I was left with no other choice, and it worked in my situation. Changing the EAPI can run you into issues if some feature not available in EAPI 5 is required. I was lucky. nCurses, however, requires eapply, implemented in EAPI6, luckily I could hold off on this as I had 5.9 currently installed, and it was enough to get through the portage update.

The following below packages need to be changed to EAPI ‘5’.
This is located at the top of each .ebuild file.
These can all be found in /usr/portage.

/usr/portage/???/automake/
/usr/portage/???/automake-wrapper/
/usr/portage/dev-lang/python/
/usr/portage/app-portage/elt-pathes/
/usr/portage/dev-lang/python-exec/

Next, with the above changes, we need to get python updated, I was using a system with python 2.7, I did not have python3 installed at all. This may have complicated things for be, but, this is the process I followed. I did this all without installing python3. Simply I have a minimum build system where space is a luxury, and wanted to avoid all I could, so python3 is not included in the build.

Begin by taking care of the prerequisite s.

emerge -av –digest –oneshot =sys-devel/automake-1.15.1-r2

emerge -av –digest –oneshot elt-patches

Finally we can emerge the new python, in my case 2.7.15.
emerge -av –digest –oneshot –nodeps =dev-lang/python-2.7.15

We need to take care of a few more depends required my the new portage (version 2.3.69).
emerge -C python-exec
emerge -C eselect-python
***we unmerged select-python, the python link is now broken, we need to fix it***
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python2 /usr/bin/python
***emerge should now be working so continue with the emerge***

emerge -av –digest –oneshot python-exec

At last portage can be emerged, ignoring dependencies.
sudo emerge -av –oneshot –nodeps portage

sudo mkdir /usr/local/portage/metadata
echo ‘masters = gentoo’ >> /usr/local/portage/metadata/layout.conf

***this should get portage up to date***

***below is what my portage information looked like after bringing portage up to date***

Performing a emerge –version resulted in the following output…
This should give you an idea of minimum requirements to get this version of portage working enough continue with the process.

emerge --version
Portage 2.3.69 (python 2.7.15-final-0, default/linux/arm/17.0, gcc-4.6.3, glibc-2.15-r3, 3.2.5-dreamplug armv5tel)

emerge --info
Portage 2.3.69 (python 2.7.15-final-0, default/linux/arm/17.0, gcc-4.6.3, glibc-2.15-r3, 3.2.5-dreamplug armv5tel)
=================================================================
System uname: Linux-3.2.5-dreamplug-armv5tel-Feroceon_88FR131_rev_1_-v5l-with-gentoo-2.2
KiB Mem: 513668 total, 19280 free
KiB Swap: 0 total, 0 free
Timestamp of repository gentoo: Wed, 21 Aug 2019 15:30:01 +0000
Head commit of repository gentoo: cdda9adf72b626d020a063419c1f376755d1b456
sh bash 4.2_p45
ld GNU ld (GNU Binutils) 2.22
distcc 3.1 armv5tel-softfloat-linux-gnueabi [disabled]
app-shells/bash: 4.2_p45::gentoo
dev-lang/perl: 5.12.4-r1::gentoo
dev-lang/python: 2.7.15::gentoo
dev-util/pkgconfig: 0.28::gentoo
sys-apps/baselayout: 2.2::gentoo
sys-apps/openrc: 0.11.8::gentoo
sys-apps/sandbox: 2.5::gentoo
sys-devel/autoconf: 2.69::gentoo
sys-devel/automake: 1.12.6::gentoo, 1.15.1-r2::gentoo
sys-devel/binutils: 2.22-r1::gentoo
sys-devel/gcc: 4.6.3::gentoo
sys-devel/gcc-config: 1.7.3::gentoo
sys-devel/libtool: 2.4-r1::gentoo
sys-devel/make: 3.82-r4::gentoo
sys-kernel/linux-headers: 3.7::gentoo (virtual/os-headers)
sys-libs/glibc: 2.15-r3::gentoo
Repositories:

gentoo
location: /usr/portage
sync-type: rsync
sync-uri: rsync://rsync.gentoo.org/gentoo-portage
priority: -1000
sync-rsync-verify-jobs: 1
sync-rsync-verify-metamanifest: yes
sync-rsync-extra-opts:
sync-rsync-verify-max-age: 24

x-portage
location: /usr/local/portage
masters: gentoo
priority: 0

ACCEPT_KEYWORDS="arm"
ACCEPT_LICENSE="@FREE"
CBUILD="armv5tel-softfloat-linux-gnueabi"
CFLAGS="-Os -march=armv5te -pipe"
CHOST="armv5tel-softfloat-linux-gnueabi"
CONFIG_PROTECT="/etc"
CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/gconf /etc/gentoo-release /etc/revdep-rebuild /etc/sandbox.d"
CXXFLAGS="-Os -march=armv5te -pipe"
DISTDIR="/tmp"
ENV_UNSET="DBUS_SESSION_BUS_ADDRESS DISPLAY GOBIN PERL5LIB PERL5OPT PERLPREFIX PERL_CORE PERL_MB_OPT PERL_MM_OPT XAUTHORITY XDG_CACHE_HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_RUNTIME_DIR"
FCFLAGS="-O2"
FEATURES="assume-digests binpkg-docompress binpkg-dostrip binpkg-logs config-protect-if-modified distlocks ebuild-locks fixlafiles ipc-sandbox merge-sync multilib-strict network-sandbox news parallel-fetch pid-sandbox preserve-libs protect-owned sandbox sfperms strict unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersandbox usersync xattr"
FFLAGS="-O2"
GENTOO_MIRRORS="http://distfiles.gentoo.org"
LDFLAGS="-Wl,-O1 -Wl,--as-needed"
MAKEOPTS="-j3"
PKGDIR="/var/cache/binpkgs"
PORTAGE_CONFIGROOT="/"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages --exclude=/.git"
PORTAGE_TMPDIR="/tmp"
USE="acl arm bash-completion berkdb bzip2 cli crypt cxx dri fortran fuse gdbm iconv ipv6 ncurses nls nptl openmp pam pcre readline seccomp split-usr ssl svg tcpd unicode usb vim-syntax xattr zlib" APACHE2_MODULES="authn_core authz_core socache_shmcb unixd actions alias auth_basic authn_alias authn_anon authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache cgi cgid dav dav_fs dav_lock deflate dir disk_cache env expires ext_filter file_cache filter headers include info log_config logio mem_cache mime mime_magic negotiation rewrite setenvif speling status unique_id userdir usertrack vhost_alias" CALLIGRA_FEATURES="karbon sheets words" COLLECTD_PLUGINS="df interface irq load memory rrdtool swap syslog" ELIBC="glibc" GPSD_PROTOCOLS="ashtech aivdm earthmate evermore fv18 garmin garmintxt gpsclock isync itrax mtk3301 nmea ntrip navcom oceanserver oldstyle oncore rtcm104v2 rtcm104v3 sirf skytraq superstar2 timing tsip tripmate tnt ublox ubx" INPUT_DEVICES="libinput keyboard mouse" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LIBREOFFICE_EXTENSIONS="presenter-console presenter-minimizer" NETBEANS_MODULES="apisupport cnd groovy gsf harness ide identity j2ee java mobility nb php profiler soa visualweb webcommon websvccommon xml" OFFICE_IMPLEMENTATION="libreoffice" PHP_TARGETS="php7-2" POSTGRES_TARGETS="postgres10 postgres11" PYTHON_SINGLE_TARGET="python3_6" PYTHON_TARGETS="python2_7" RUBY_TARGETS="ruby24" USERLAND="GNU" VIDEO_CARDS="exynos fbdev omap dummy v4l" XTABLES_ADDONS="quota2 psd pknock lscan length2 ipv4options ipset ipp2p iface geoip fuzzy condition tee tarpit sysrq steal rawnat logmark ipmark dhcpmac delude chaos account"
Unset: CC, CPPFLAGS, CTARGET, CXX, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LANG, LC_ALL, LINGUAS, PORTAGE_BINHOST, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS

Next is to fix (resync) the portage tree, this will wipe out all of our EAPI hacks (changes) that we made to the portage tree.
emerge –sync
At this point you should have a working portage system capable of bringing the rest of the system up to date.
Some other useful information, since the DreamPlug has only 512MB RAM it may be necessary to create a swap file to emerge large things like gcc. The below commands will create and activate a swap file.

***temporary swap file***
***this creates a 512MB sized swap file***
osaka screen # dd if=/dev/zero of=/swapfile count=1M
1048576+0 records in
1048576+0 records out
536870912 bytes (537 MB) copied, 47.2674 s, 11.4 MB/s

***if you want a 1024MB swap file, execute the below command instead
osaka screen # dd if=/dev/zero of=/swapfile count=2M

***next format the swap file with the below command***
osaka screen # mkswap /swapfile
Setting up swapspace version 1, size = 524284 KiB
no label, UUID=e62f5859-f995-45a6-86ce-d60246a7cd69

***finally activate the swap file***
osaka screen # swapon /swapfile

***verify memory usage***
osaka screen # cat /proc/meminfo
***you should see the swap file showing up now***

***command to add to /etc/fstab***
***if you want to make this swap file permanent***
***otherwise just delete the above created file after you are done and either disabled swap or restarted
/swapfile none swap sw,loop 0 0

Another note, you may not want to do this in a SD card, especially the swap file, I recommend a USB hard disk for this.
The SD card will get hammered not only by the swap file, but by all the compiling.

A note about installing Perl that I ran into,
Please see the reference here for the bug information, this is still present in version 5.30.0
https://rt.perl.org/Public/Bug/Display.html?id=133803

Basically when installing perl you will need to use this command…
EXTRA_ECONF=”-Dd_u32align” emerge -av —oneshot perl

The EXTRA_ECONF will append -Dd_u32align onto the configure command to force 32-bit alignment, which is not being detected properly for some reason or another right now.