July 11, 2019

MacMini (Late 2009) + Gentoo

MacMini (Late 2009) + Gentoo

Well, this was going to be a HOWTO guide on the steps I followed to install Gentoo on my 2009 MacMini. But, as it turns out, there were WAY too many rabbit holes to go down that it just wouldn't make sense. I will, however, talk about the process I did.

For starters, as of a few releases ago, MacOS X just became unusable on the lil square. I am still very fond of the form factor and the look (so much so, that I am contemplating a System76 Meerkat). But hanging onto something that is unusable just doesn't 'spark joy' for me.

At first, I tried to see if there were things within MacOS X that I could enable/disable to make it more useful. During that fruitless effort, I did notice some odd disk warnings. And my aplogies, I don't remember what they were.

My first thought was to simply buy an SSD, slap it in the box, and re-install OS X. Yeah, somewhere over the past 10 years I seem to have misplaced the install media. I did read a little about being able to bootstrap from the internet, but along with my internet research I heard of many others who simply said that no matter what they attempted recent versions of OS X just really isn't a good experience on the hardware.

That's fair.

But what to do? Install Linux. I found a reasonably priced SSD so decided that, just to be safe, let's install it and put Linux on it and retain the older Mac OS X drive in the hardware vault. My next step was to choose a Linux distro.

Typically, I'm a install and forget type person. It doesn't matter (well, it does matter for the use case) to me about using Ubuntu, Fedora, RHEL, CentOS, etc. But, since this is what I would call 'non-standard' hardware, I wanted some extreme influence in kernel + software selection.

I'm a former Gentoo user. It's been a LONG time. After I reset my password for the Gentoo forums, it said I registered that account circa 2005. I can't recall what I was doing then (probably another hair brained idea) but I don't recall using it for anything "real" since 2000-ish.

So, I decided to dust off the brain and see if I could read those brain cells.

As it turns out, I was pretty unsuccessful in remembering, but there is a LOT of documentation out there and the forum members is still very active and even more helpful.

The first thing I did was snag the latest Minimal Installation CD and latest Stage 3 Archive. This much I do remember (the stage1/stage2/stage3 install process). Stage 3 essentially gives you binaries to start from rather than compiling GCC to compile everything from scratch. Maybe I'm less paranoid these days, who knows.

After the installation of the SSD and a quick flash of the install CD to a 4GB USB key, I popped the USB key into the back and booted up the system (while holding the right ALT key). To my surprise, it booted up with ease. and dropped me to a somewhat familiar 'red' root prompt.

Now, a little bit about the 2009 MacMini (at least mine). It's an Intel Core 2 Duo, operating at 2.53Ghz. It has 4GB of memory (minus the shared video memory I suppose). It's got Broadcom BCM4321 wifi adapter along with gigabit ethernet. Driving the display is a Nvidia GeForce 9400. And yes, it now has a 250GB SSD drive.

It also boots via UEFI. I forgot to mention, I know squat about UEFI. For the past 10-ish years, I've really not had to deal with new ways to boot stuff. Sure, I've installed new Linux's. But click next, next,next and voilia most things just "work" these days.

So, while on a shopping trip with the wife, I decided to spend some time reading up. UEFI is a labeled as a standardized way to boot computers. No more bootloaders, or so they say.

Well, UEFI is my only option so the first thing to do is to partition the disk like I wanted it and setting the right UEFI params on the disk. I ended up piece-mealing several different guides together because none of them seemed to give me a direct recipe on what to follow. My implementation, is less than ideal, but still a very tolerable solution.

I created four partitions on the drive, with a gpt partition table. The gpt partition table is required for UEFI booting.

Model: ATA KINGSTON SA400S3 (scsi)
Disk /dev/sda: 240GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system     Name    Flags
 1      1049kB  3146kB  2097kB                  grub    bios_grub
 2      3146kB  137MB   134MB   fat32           boot    boot, esp
 3      137MB   674MB   537MB   linux-swap(v1)  swap
 4      674MB   240GB   239GB   ext4            rootfs

The first partition is a 2MB boot loader partition, this is the part that is less than 'ideal' to me. I think it's a waste of space and was a waste of my time. But it's 2MB. I'm not going to lose sleep over it.

The second partition is my /boot volume. You need to make sure the correct flags are set (boot, esp) so that the UEFI firmware can identify the correct partition. Also per the spec it needs to be a FAT filesystem. I think this is because Microsoft is on the committee, but again, I'm not going to lose any sleep here.

I went ahead and created a 512MB swap partition (holy crap, 512MB? well, that's what the guide suggested....) and the rest of the disk is my rootfs. I'd like to turn this into a small "part time development" workstation and I honestly don't want to deal with separate partitions while I develop.

I also made the choice about this time to skip any LVM setups. Many of the guides are assuming you have an LVM disk setup, but in the Mac? I know I won't ever be adding physical drives or resizing volumes so I chose not to implement it.

The next few steps were pretty much straight out of the Gentoo handbook. Make filesystems on the new partitions, enable the swap partition.

The next step is to install the stage3. Make sure your time is correct (thank you NTP). In case you didn't download it earlier (I did, from a location that has more bandwidth than I do):

root$ cd /mnt/gentoo
root$ wget http://distfiles.gentoo.org/releases/amd64/autobuilds/20190703T214502Z/stage3-amd64-20190703T214502Z.tar.xz
root$ tar xpvf stage3-20190703T214502Z.tar.xz --xattrs-include='*.*' --numeric-owner

You should follow the Gentoo handbook and verify the hashes/signatures from your download.

Once the stage3 environment was extracted, I wanted to set a few compile options to CFLAGS/CXXFLAGS. This was done through the COMMON_FLAGS variable in /etc/portage/make.conf.

COMMON_FLAGS="-march=native -O2 -pipe"

If you don't know what they mean, a quick google search will give a better explanation that I would.

Again, for most of the steps, following along with the Gentoo handbook is easy enough to follow up to the 'chroot' step and I don't want to duplicate efforts. The one thing I will mention is that during the selection of the Gentoo mirror, I initially selected the GATech's mirrors (both https and http) and they seem to be broken. causing very long timeouts before trying a different mirror. If you're going to attempt this, I'd just skip the Yellow Jacket's mirror.

After doing the chroot and mounting the appropriate filesystems, reading and purging the news, it was time to select a profile. This is done via the eselect tool.

(~) -> eselect profile list
Available profile symlink targets:
  [1]   default/linux/amd64/17.0 (stable)
  [2]   default/linux/amd64/17.0/selinux (stable)
  [3]   default/linux/amd64/17.0/hardened (stable)
  [4]   default/linux/amd64/17.0/hardened/selinux (stable)
  [5]   default/linux/amd64/17.0/desktop (stable)
  [6]   default/linux/amd64/17.0/desktop/gnome (stable)
  [7]   default/linux/amd64/17.0/desktop/gnome/systemd (stable) *
  [8]   default/linux/amd64/17.0/desktop/plasma (stable)
  [9]   default/linux/amd64/17.0/desktop/plasma/systemd (stable)
  [10]  default/linux/amd64/17.0/developer (stable)
  [11]  default/linux/amd64/17.0/no-multilib (stable)
  [12]  default/linux/amd64/17.0/no-multilib/hardened (stable)
  [13]  default/linux/amd64/17.0/no-multilib/hardened/selinux (stable)
  [14]  default/linux/amd64/17.0/systemd (stable)
  [15]  default/linux/amd64/17.0/x32 (dev)
  [16]  default/linux/amd64/17.1 (stable)
  [17]  default/linux/amd64/17.1/selinux (stable)
  [18]  default/linux/amd64/17.1/hardened (stable)
  [19]  default/linux/amd64/17.1/hardened/selinux (stable)
  [20]  default/linux/amd64/17.1/desktop (stable)
  [21]  default/linux/amd64/17.1/desktop/gnome (stable)
  [22]  default/linux/amd64/17.1/desktop/gnome/systemd (stable)
  [23]  default/linux/amd64/17.1/desktop/plasma (stable)
  [24]  default/linux/amd64/17.1/desktop/plasma/systemd (stable)
  [25]  default/linux/amd64/17.1/developer (stable)
  [26]  default/linux/amd64/17.1/no-multilib (stable)
  [27]  default/linux/amd64/17.1/no-multilib/hardened (stable)
  [28]  default/linux/amd64/17.1/no-multilib/hardened/selinux (stable)
  [29]  default/linux/amd64/17.1/systemd (stable)
  [30]  default/linux/amd64/17.0/musl (exp)
  [31]  default/linux/amd64/17.0/musl/hardened (exp)
  [32]  default/linux/amd64/17.0/musl/hardened/selinux (exp)
  [33]  default/linux/amd64/17.0/uclibc (exp)
  [34]  default/linux/amd64/17.0/uclibc/hardened (exp)

Looks like a lot of options, but they mostly self-explanatory. I chose the default/linux/amd64/17.0/desktop/gnome/systemd profile. The Gentoo handbook has notes that the 17.1 profiles needed special considerations, so I hung back at 17.0. I later found out (via eselect news) that it looks like 17.1 is ready for prime time. Just my luck. I'm not going to sweat it though, it'll be a topic for a new blog post.

You'll notice I also selected Gnome and Systemd. There has been some work, I read, to remove the systemd requirement from Gnome 3.30, but to be honest. I'm not really a systemd hater like some. In fact, I would prefer it. It would bring at least a little bit of consistency to Fedora and Ubuntu desktops.

The first big time sink has come.

emerge --ask --verbose --update --deep --newuse @world

As I said earlier, this system has a Intel Core 2 Duo at 2.53Ghz. This emerge command is essentially updating the world... all of the installed packages the system knows about. Since Gentoo is a source distro so it is downloading source code from the Gentoo mirrors and compiling the packages on your personal system.

I have no idea how long this took. I went to bed and had compilied and installed updates when I rose.

After this step, things to get non-standard from handbook, which I felt was very OpenRC focused rather than systemd.

I setup my timezone, and updated /etc/locale.gen for the locale's I use. I also started following the Saski tutorial for an EFI system. When I initially started that guide, I started from the middle. Don't be like me. I like to fail. You'll want to start from the beginning. Especially about setting up the Saski repo :).

Following the guide it was time to configure the kernel. I ran into issues using the 'buildkernel' scripts from the Saski tutorials. I'm 99% sure its because I jumped to it mid-way through my install. That's fine though, I can emerge the gentoo-sources and do a 'make menuconfig'. For the most part, I used the config from the kernel running on the LiveUSB key I created. I did enable some specific UEFI options, set my kernel architecture to the Intel Core 2 Duo platform and made sure there was kernel support for a few things I care about (file systems, device driver stuff). I probably could have created them as modules, but honestly I'm not too worried about kernel size.

During the guide there is a bootstrap.sh step. As I semi-mindlessly followed the steps, I realized this bootstrap step (which I think is totally necessary) is essentially doing a old stage1 install. Hooray - recompiling GCC. Once the bootstrap was done, it was time for the next steps. Wait a minute, I need to boostrap again? Fine. They want to make sure GCC (and a few other pieces) are recompilied with latest GCC.

By this time it is tomorrow, again.

GCC re-re-compiled? Check.

locale.gen re-configured? Check.

Re-emerge the @world again? Wait.. WHAT? AGAIN?!

emerge --ask --verbose --emptytree --with-bdeps=y @world

Yes. Time to reinstall @world again, this time to compile with the GCC. In case you are wondering, "Total: 432 packages (432 reinstalls), Size of downloads: 214581 KiB", fml.

Of course... it's also recompiling GCC... why? BECAUSE. that's why....

Once that fun was done (I don't even know what day it anymore :-)) I have a working base console system! There was much rejoicing.

Now that I have a workable console, I want to get my desktop environment up. Still following Saski's guide, the first step is to compile the x.org desktop and twm prior to a full-on GNome 3.30/Wayland system.

That's cool, I like baby steps.

It was at this point, I wish they would have told me about the kernel DRM video modules that needed to be compiled into the kernel. So, in true Gentoo fashion, let's recompile the kernel. Again. This time with all (at least I hope, all) the correct support.

For me, on this Mac, I chose CONFIG_DRM and CONFIG_DRM_NOUVEAU. One day I'll work on the lastest NVidia driver non-open-source drivers that supports the GeForce 9400. Today - I'm fine with the trying out Nouveau. I'm not going to be playing games on this thing after all. (Hmmm, maybe some light CUDA dev... hmmm).

With the kernel re-compiled I issued by reboot. Ugh, I can't log in anymore. I proceeded to head downstairs to my office, where the Mac physically lives and looked at the screen. I fully expected to see "KERNEL PANIC". But instead, I saw a login getty.

"That's wierd."

Logged in, and found no sshd process listening. "Doubly, weird. I know I did a systemctl enable sshd". So, step one was to issue a systemctl start sshd command. I'm pretty sure I said in a loud boom voice, "What on earth do you mean I'm not running systemd?!"

During the last emerge (or it could have been the kernel build, I honestly don't know for sure), it apparently got my system boot back with openrc.

After some googling and forum searching, the fix was easy enough. I had to edit my grub.conf file to appent the systemd line to the kernel boot parameters. Once edited, a grub-mkconfig > /boot/grub/grub.cfg was issued and I was able to reboot into a working systemd environment.

And there was much rejoicing. Again.

Now, with the kernel DRM support enabled I could create a basic ~/.xinitrc and issue a startx.

I was amazed. It worked. Like, wow.

Crappy Image of twm running!

With twm/x.org working and verifying the Nouveau driver loaded and all was well, the next step was to remove all of that crap and and get Gnome 3.30 + Wayland installed.

I did choose to disable the 'tracker' USE flag for Gnome. From what I read it can be a CPU hog and with an older dual core, I'd like to crank out any performance I can. After that was configured, it was a matter of

emerge --ask --verbose --keep-going gnome-base/gnome && echo "GNOME emerged OK" || echo "GNOME emerge not yet completed"

With that kicked off. Back to bed. #NotJoking

This leads me to today. It was an early morning for me, having to take my daughter to work (leaving the house at 4:30). So I was up tinkering around 3AM. Walked into the office to check on things and was my "GNOME emerged OK" message.

Even more rejoicing!

startx brought up the Gnome 3.30 desktop as I expected (after modifing ~/.xinitrc of course).

Slightly better image of Gnome 3.30 running!

After disabling dhcpcd, and enabling (and starting NetworkManager). the last step is for me to systemctl enable gdm and reboot.

With that there is peace on Earth. Well, at least the first step to an operational desktop running Gentoo on a 2009 MacMini.