MacbookPro上基于ZFS的Gentoo双系统安装

  实在没想到,买了Macbook Pro还是避免不了折腾的命,原本很大程度买Macbook Pro就是不想折腾滴。
  或许上层开发程序员无所谓,但无奈对于对做Linux底层开发者来说,涉及到macOS和Linux操作系统的差异性太大了;即使macOS命令行程序无比丰富,但是BSD风格和Linux那一套相比有时候差异还挺大的;8G内存用虚拟机太吃力了——总之,这种情况唯有双系统可解~
  至于发行版,自从遇到Gentoo之后,就对其他发行版无爱了,而文件系统也一直坚持着ZFS装系统,XFS保存数据。这次是macOS+Gentoo了,原理和步骤差异不大,这里总结一下,给需要的人做个参考吧!
gentoo

  1. EFI启动引导rEFInd
      因为macOS系统使用GPT分区和EFI引导模式,所以要安装的Gentoo也必须使用这种引导模式。rEFInd是一个优秀的EFI引导器,支持Windows/macOS/Linux平台,所以这里需要使用rEFInd来接管,然后用来引导macOS和Gentoo。
      安装rEFInd的方式十分简单,按照教程几步就可以了。从EI Capitan开始,macOS启用了SIP特性,所以必须在恢复模式下安装rEFInd。
  2. Linux引导盘准备
      Gentoo的安装和其他系统很不一样,必须先用一个LiveCD/DVD首先启动,然后通过chroot模式安装。
      之前自己都是使用带有zfs支持的system-rescue-cd来安装的,但这次funtoo的示例教程用了Ubuntu。我也采用了Ubuntu LiveCD的方式,主要是考虑到Ubuntu一直对各种硬件支持良好(主要是考虑到MacbookPro没有有线网络支持)。通过dd if=ubuntu-16.04.1-desktop-amd64.iso of=/dev/sdb bs=4K写入U盘后,就可以用rEFInd来引导它了。

    1
    2
    3
    4
    5
    6
    ubuntu@ubuntu:~$ sudo -i
    root@ubuntu:~# apt-add-repository universe
    root@ubuntu:~# apt update
    root@ubuntu:~# apt install --yes debootstrap zfs-initramfs
    root@ubuntu:~# dmesg | grep ZFS
    [ 377.595348] ZFS: Loaded module v0.6.5.6-0ubuntu10, ZFS pool version 5000, ZFS filesystem version 5
  3. 系统分区
      幸亏当时买了个次乞丐版的256GB的硬盘,把160GB留给了macOS,剩下的就丢给了Gentoo。
      因为采用了EFI引导方式且ESP分区已经存在,所以只需要创建root、swap和数据分区就可以了。大家都是在macOS下使用磁盘工具释放了部分的空闲空间的,而macOS默认已经把硬盘的空闲部分创建了一个分区了,所以在parted中需要首先rm 4那个分区。
      至于分区的大小,首先交换分区需要大于物理内存8G的大小,因为休眠suspend to disk需要使用它;rootfs需要大一些,主要是zfs后面快照备份的时候也会占用空间;这里对于数据是创建了store不是创建home分区,主要是考虑到后面很多软件和系统的设置都会保留在用户的home分区,如果把home放到rootfs备份会方便些,而真正的数据放到store分区,软连接到home目录下面就可以。最终的分区结果如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    root@ubuntu:~# parted -a optimal /dev/sda
    GNU Parted 3.2
    Using /dev/sda
    Welcome to GNU Parted! Type 'help' to view a list of commands.
    (parted) print
    Model: ATA APPLE SSD SM0256 (scsi)
    Disk /dev/sda: 251GB
    Sector size (logical/physical): 512B/4096B
    Partition Table: gpt
    Disk Flags:

    Number Start End Size File system Name Flags
    1 20.5kB 210MB 210MB fat32 EFI System Partition boot, esp
    2 210MB 161GB 160GB hfs+ Customer
    3 161GB 161GB 650MB hfs+ Recovery HD
    4 161GB 172GB 10.7GB linux-swap(v1) swap
    5 172GB 220GB 48.3GB zfs rootfs
    6 220GB 250GB 29.6GB xfs store
  4. 创建zfs分区
      以前自己都是这么做的,主要是参考Richard Yao的zfs-install操作,他是gentoo中zfs部分的开发和维护者。关注他之前有段时间沉寂了,gentoo的zfs好久没更新,但最近又再次活跃起来了。
      Richard Yao的那篇文章引导和启动使用的是grub和openrc,而本文用的是EFI和systemd,所以会有一些细微的差异。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@ubuntu:~# mkdir /mnt/gentoo
    root@ubuntu:~# zpool create -f -o ashift=12 -o cachefile=/tmp/zpool.cache -O normalization=formD -O atime=off -m none -R /mnt/gentoo zroot /dev/sda5
    root@ubuntu:~# zpool status
    root@ubuntu:~# zfs create -o mountpoint=none -o canmount=off zroot/ROOT
    root@ubuntu:~# zfs create -o mountpoint=/ zroot/ROOT/gentoo
    root@ubuntu:~# zfs create -o mountpoint=/usr/portage -o atime=off zroot/ROOT/portage
    root@ubuntu:~# zfs create -o mountpoint=/usr/portage/distfiles zroot/ROOT/distfiles
    root@ubuntu:~# zfs create -o mountpoint=/var/tmp/portage -o sync=disabled -o compression=lz4 zroot/ROOT/build-dir
    root@ubuntu:~# zfs list -t all
    root@ubuntu:~# zpool set bootfs=zroot/ROOT/gentoo zroot
  5. 系统安装准备
      上面的步骤已经为新系统创建好了rootfs,并且挂在了/mnt/gentoo的目录下面。下面就是将基系统stage解压到这个分区上面去,并做出一些配置更新后,chroot到这个新系统中去。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    root@ubuntu:~# wget http://mirrors.ustc.edu.cn/gentoo/releases/amd64/autobuilds/current-stage3-amd64/stage3-amd64-20161215.tar.bz2
    root@ubuntu:~# tar -xvjpf stage3-amd64-*.tar.bz2 -C /mnt/gentoo
    root@ubuntu:~# mkdir -p /mnt/gentoo/etc/zfs
    root@ubuntu:~# cp /tmp/zpool.cache /mnt/gentoo/etc/zfs/zpool.cache
    root@ubuntu:~# cp -L /etc/resolv.conf /mnt/gentoo/etc/resolv.conf
    root@ubuntu:~# mount -t proc none /mnt/gentoo/proc
    root@ubuntu:~# mount --rbind /dev /mnt/gentoo/dev && mount --rbind /sys /mnt/gentoo/sys
    root@ubuntu:~# mount --make-rslave /mnt/gentoo/dev && mount --make-rslave /mnt/gentoo/sys
    root@ubuntu:~# chroot /mnt/gentoo /bin/bash
    root@ubuntu:~# env-update; source /etc/profile; export PS1="(chroot) $PS1"; cd
    (chroot) ubuntu ~ #
  6. 系统基础安装
      到了这里已经chroot到目标系统中了,所做的任何操作都会保留在新系统中。不过基本系统组件,很多都没有,包含内核。
      首先需要更新portage,设置profile,更新make.conf。敝人用的make.conf已经共享了,大家可以借鉴使用,酌情修改相关USE。

    1
    2
    3
    4
    5
    6
    7
    (chroot) ubuntu ~ # emerge-webrsync
    (chroot) ubuntu ~ # emerge --sync
    (chroot) ubuntu ~ # eselect profile list
    (chroot) ubuntu ~ # eselect profile set 12 #default/linux/amd64/13.0/systemd
    (chroot) ubuntu ~ # emerge --info | grep ^USE
    (chroot) ubuntu ~ # nano -w /etc/portage/make.conf
    (chroot) ubuntu ~ # emerge -auDN @world
  7. 编译kernel和zfs模块
      到这里,系统关键的kernel还没有产生,一般来说gentoo-sources都是比较稳定的,可以安心开启~amd64。
      虽然自4.9内核发布后,各位基佬吵扰着要升级内核尝试TCP BBR拥塞控制算法,但是看了zfs目前只支持4.8的内核分支,所以这里就只用了4.8.15版本内核。内核配置是个细心活,既要支持硬件的驱动,又要删除不必要的部分精简内核(尤其对有洁癖的人来说),还需要根据使用情况调测相应地参数。个人的内核配置也贴出来了,虽然还没细调,但是可以工作使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (chroot) ubuntu ~ # emerge sys-kernel/genkernel-next
    (chroot) ubuntu ~ # emerge sys-kernel/gentoo-sources:4.8.15
    (chroot) ubuntu ~ # genkernel kernel --no-clean --no-mountboot --makeopts=-j4 --menuconfig
    (chroot) ubuntu ~ # echo "sys-kernel/spl ~amd64" >> /etc/portage/package.accept_keywords
    (chroot) ubuntu ~ # echo "sys-fs/zfs-kmod ~amd64" >> /etc/portage/package.accept_keywords
    (chroot) ubuntu ~ # echo "sys-fs/zfs ~amd64" >> /etc/portage/package.accept_keywords
    (chroot) ubuntu ~ # emerge sys-fs/zfs
    (chroot) ubuntu ~ # systemctl preset zfs-import-cache zfs-import-scan zfs-mount zfs-share zfs-zed zfs.target
    (chroot) ubuntu ~ # echo 1 > /proc/sys/vm/drop_caches
    (chroot) ubuntu ~ # genkernel all --no-clean --no-mountboot --makeopts=-j4 --zfs --callback="emerge @module-rebuild" --menuconfig
  8. 配置rEFInd引导
      由于使用EFI引导,这里就不需要安装grub类似的软件了。由于macOS已经有了ESP分区了,这里就只需要将内核和initramfs拷贝到ESP分区中新建的gentoo目录就可以了,不过要注意内核名字的修改,否则可能不能被识别。而且后面有其他版本的内核,也可以用相同的方式拷贝进多个内核和initramfs,rEFInd会自动识别并在引导的时候给出启动内核的选项。
      此外,还需要增加refind_linux.conf文件,设置如下参数以供内核启动的生活使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    (chroot) ubuntu ~ # mkdir tmp
    (chroot) ubuntu ~ # mount /dev/sda1 tmp
    (chroot) ubuntu ~ # cp /boot/kernel-genkernel-x86_64-4.8.15-gentoonicol tmp/EFI/gentoo/vmlinuz-genkernel-x86_64-4.8.15-gentoonicol
    (chroot) ubuntu ~ # cp /boot/initramfs-genkernel-x86_64-4.8.15-gentoonicol /tmp/EFI/gentoo/initramfs-genkernel-x86_64-4.8.15-gentoonicol
    (chroot) ubuntu ~ # cat /mnt/EFI/gentoo/refind_linux.conf
    "Default" "dozfs root=ZFS=zroot/ROOT/gentoo init=/usr/lib/systemd/systemd ro quiet"
    "Console" "dozfs root=ZFS=zroot/ROOT/gentoo init=/usr/lib/systemd/systemd ro quiet nox"
    "Emergency" "dozfs root=ZFS=zroot/ROOT/gentoo init=/usr/lib/systemd/systemd ro 1"
    (chroot) ubuntu ~ #
  9. 安装gnome桌面环境
      如果直接使用emerge gnome会安装上gnome全家桶,这里可以使用gnome-light安装简洁的gnome环境,然后再根据自己的需要安装其他的gnome应用程序和组件。
      重启之后就可以看见gdm的登录窗口了,而且对于retina高清屏gnome本身适配的很好,这确实超过了我的预期啊。
      人家在苹果本上安装Linux后,据说调测好了,电池的续航是能够和macOS不相上下的。

    1
    2
    3
    4
    5
    6
    7
    8
    (chroot) ubuntu ~ # useradd -m -G users,wheel,audio -s /bin/bash taozj
    (chroot) ubuntu ~ # passwd taozj
    (chroot) ubuntu ~ # eselect profile set 5 #default/linux/amd64/13.0/desktop/gnome/systemd
    (chroot) ubuntu ~ # emerge -auDN @world
    (chroot) ubuntu ~ # emerge --ask x11-base/xorg-drivers
    (chroot) ubuntu ~ # emerge --ask gnome-light
    (chroot) ubuntu ~ # systemctl enable gdm.service
    (chroot) ubuntu ~ # systemctl enable NetworkManager
  10. 备份和优化
      这里主要是ZFS的一些参数调优、备份、迁移、挂载等操作,作为记录后续查找方便的目的,请不要操作之!!!

    1
    2
    3
    4
    5
    6
    7
    8
    root@ubuntu:~# echo "options zfs zfs_arc_max=536870912" >> /etc/modprobe.d/zfs.conf
    root@ubuntu:~# echo PORTAGE_NICENESS=19 >> /etc/make.conf
    root@ubuntu:~# zfs set compression=lz4 zroot/GENTOO/build-dir
    root@ubuntu:~# zfs snapshot -r zroot@20161223_install
    root@ubuntu:~# zfs list -t snapshot
    root@ubuntu:~# zfs send -Rv zroot@20161223_install | gzip > /mnt/20161223_install.snap.gz
    root@ubuntu:~# gzcat /mnt/20161223_install.snap.gz | zfs receive -Fv zroot
    root@ubuntu:~# zpool import -f -o cachefile= -R /mnt/gentoo zroot

  MacbookPro是Retina高清屏,默认在Gentoo安装后dpi自动翻倍成96*2=192,整体的Gnome显示效果不很理想,而且还有很多的程序不兼容(比如wiznote),字体显示的十分小。最简单的方式是放弃retina,将显示分辨率降低:

1
2
3
4
5
6
➜  ~ cat /etc/X11/xorg.conf.d/40-monitor.conf  
Section "Monitor"
Identifier "eDP1"
Option "PreferredMode" "1680x1050"
EndSection
➜ ~

  经过上面的设定,再加上之前的文章中使用infinitely进行字体显示和优化设置,最终的效果还是十分的清晰可人的。安装后还有一个问题就是键盘的~键无法使用,fn键默认是功能键盘,对此的纠正方法是对hd_apple模块参数:

1
2
echo 0 > /sys/module/hid_apple/parameters/iso_layout
echo 2 > /sys/module/hid_apple/parameters/fnmode

  为了避免每次这么操作麻烦,可以将其写成一个systemd service,每次开机自动设置就可以了。

  1. 其他软件安装
      关于其他软件、插件的推荐,请参考之前整理的文档《我的Gentoo Overlay和Linux软件推荐》。因为gentoo是滚动更新版,而又有ZFS保驾护航,希望这个系统能战上几年!!!
    系统桌面

本文完!

参考