基础安装
SD卡的准备
首先准备SD card 一张。在SD 卡上至少创建两个分区。 SD的/ boot分区应该是FAT32。根(/分区可以是任何首选的 Linux文件系统,但是由于 SD 卡是基于闪存的介质,使用F2FS有很多好处。 大致情况可以如下:
Disk /dev/sdb: 16.6 GB, 16574840832 bytes
255 heads, 63 sectors/track, 2015 cylinders, total 32372736 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x1db42224
Device Boot Start End Blocks Id System
/dev/sdb1 * 2048 835379 416666 c W95 FAT32 (LBA)
/dev/sdb2 835380 31889024 15526822+ 83 Linux
/dev/sdb3 31889025 32372735 241855+ 5 Extended
/dev/sdb5 31889088 32372735 241824 82 Linux swap / Solaris
发行版的选择
树莓派使用的是ARM架构的linux系统。对于发行版,我们可以选择Debian系下的产品(如Ubuntu的server版本,也可以选择树莓派的官方镜像) 而我这次选择的是Gentoo Linux,因为它支持arm架构,同时支持32位,同时Gentoo Linux 支持编译整个系统,把原来官方提供的stage3 tarball里的所有组件替换成自己编译的(包括GCC编译器和所有基本系统组件),这样一来整个系统的所有程序和组件都是针对树莓派CPU架构优化编译的了,争取性能最大化。
启动分区
正确的/boot分区的最低设置需要以下由 Raspberry Pi 基金会提供的专有固件文件 bootcode.bin fixup.dat start.elf kernel image(s)
DTB (Device Tree Blob) files
要使用config.txt 中的gpu_mem=16设置启动树莓派,需要以下文件: ge3-armv7a_hardfp-YYYYMMDD.tar.bz2 -C /mnt/raspberrypiroot/ fixup_cd.dat start_cd.elf
Pi 有两个视频驱动程序。较旧的使用固定的保留 GPU 内存空间。开源 VC4 驱动程序使用内核连续内存分配器。使用vc4驱动时设置gpu_mem=16,避免浪费RAM。 我们可以merge一个sys-boot/raspberrypi-firmware来是它运行。
root #emerge --ask sys-boot/raspberrypi-firmware
固件文件安装在/boot 中。在出现sys-boot/raspberrypi-firmware包之前,应将 SD 卡的引导分区挂载在/boot上。 或者我们可以选择安装预编译好的树莓派内核以及模块:
root #emerge --ask sys-kernel/raspberrypi-image
下载并解压stage3
wget http://distfiles.gentoo.org/releases/arm/autobuilds/current-stage3-armv7a_hardfp/stage3-armv7a_hardfp-YYYYMMDD.tar.bz2 #国内的镜像源可能并未同步该镜像
tar xpjf stage3-armv7a_hardfp-YYYYMMDD.tar.bz2 -C /mnt/raspberrypiroot/
修改make.conf
nano -w /mnt/raspberrypiroot/etc/portage/make.conf
# Raspberry Pi 2, or Raspberry Pi 3 running in 32 bit mode:
CFLAGS="-O2 -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard"
CXXFLAGS="${CFLAGS}"
修改fstab
我们使用lsblk以及blkid命令来查找分区。 SD卡一般被识别为/dev/mmcblk0 ge3-armv7a_hardfp-YYYYMMDD.tar.bz2 -C /mnt/raspberrypiroot/
生成root密码的hash,并添加至/etc/shadow
root #openssl passwd -1
(可选)stage4文件
每日NOOBS image会更新 解压时解压在/os/Gentoo
Portage树
下载最新的 Portage 树:
root #wget http://distfiles.gentoo.org/snapshots/portage-latest.tar.bz2
确保根分区上有足够的空闲 inode 块。Portage 占用大约 181K 的 inode。
root #df -ih | grep -E 'Mounted|mmc'
将 Portage 解压到 SD 卡:
root #tar xjvpf portage-latest.tar.bz2 -C /mnt/raspberrypiroot/usr
交叉编译
由于树莓派处理器相比现代处理器差了很多,为了加快Gentoo的安装过程,我们可以选择使用另一台机子进行编译作业。 使用crossdev:
root #emerge --ask sys-devel/crossdev
对于 64 位模式的 Raspberry :
root #crossdev -S -t aarch64-unknown-linux-gnu --genv 'USE="cxx multilib fortran -mudflap nls openmp -sanitize"' #USE变量一定要配置!!!
root #cd /usr/aarch64-unknown-linux-gnu/etc/portage && rm make.profile && ln -s /usr/portage/profiles/default/linux/arm64/13.0/desktop make.profile
在另一主机上:
gentoo_pc ~ # emerge --ask --verbose sys-devel/crossdev
修改/etc/portage/repos.conf/crossdev.conf:
[crossdev]
location = /usr/local/portage-crossdev
priority = 10
masters = gentoo
auto-sync = no
准备USE变量:
gentoo_pc ~ # mkdir -pv /usr/local/portage-crossdev
gentoo_pc ~ # crossdev --stable -t aarch64-unknown-linux-gnu -oO /usr/local/portage-crossdev
跑完之后,我们的交叉编译工具链已经配置好了: 我们进入到portage:
gentoo_pc ~ # cd /usr/aarch64-unknown-linux-gnu/etc/portage
gentoo_pc portage # rm -f make.profile
gentoo_pc portage # ln -s /usr/portage/profiles/default/linux/arm64/17.0/desktop make.profile
检查toolchain:
gentoo_pc ~ # aarch64-unknown-linux-gnu-gcc --version
gentoo_pc ~ # aarch64-unknown-linux-gnu-c++ --version
gentoo_pc ~ # aarch64-unknown-linux-gnu-g++ --version
如果架构的选择没正确,我们就需要重新选择config,再source新的profile,示例如下:
gentoo_pc ~ # gcc-config -l
[1] aarch64-unknown-linux-gnu-5.4.0
[2] x86_64-pc-linux-gnu-4.9.4
[3] x86_64-pc-linux-gnu-5.4.0 * #选择了错误的架构
gentoo_pc ~ # gcc-config aarch64-unknown-linux-gnu-5.4.0
gentoo_pc ~ # source /etc/profile
在chroot里编译
可以使用通用的 x86_64 或 i386 PC 来 chroot 到带有 Raspberry Pi 系统的现有 SD 卡。这种方法比在 Raspberry Pi 上编译要快得多。 为此,需要静态安装app-emulation/qemu:
root #echo app-emulation/qemu static-user qemu_user_targets_aarch64 qemu_user_targets_arm >> /etc/portage/package.use/qemu #写入USE变量
root #emerge qemu
root #quickpkg qemu
在创建带有 static-user USE 标志的 QEMU 之后,需要将qemu-arm可执行文件复制到 chrooting 系统中:
root #cd /mnt/rpi
root #ROOT=$PWD/ emerge --usepkgonly --oneshot --nodeps qemu
完成后,需要在运行内核中用 ARM 可执行解释器:
root #echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
root #echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register
挂载文件系统
root #mount /dev/mmcblk0p1 /mnt/rpi/boot
root #mount -o bind /dev /mnt/rpi/dev
root #mount -o bind /proc /mnt/rpi/proc
root #mount -o bind /sys /mnt/rpi/sys
root #mount -o rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 devpts /mnt/rpi/dev/pts -t devpts
复制DNS信息
root #cp /etc/resolv.conf /mnt/rpi/etc/
最后chroot进入树莓派系统:
root #chroot /mnt/rpi
编译内核
Linux内核是所有发行版的核心。它位于用户程序和系统硬件之间。
root #emerge --ask sys-kernel/raspberrypi-sources
同样,我们可以选择手动配置内核或者使用genkernel来自动配置并编译内核: 这里我们选择使用genkernel来自动配置: 修改一下配置:
/etc/genkernel-rpi.conf
# install kernel manually
INSTALL="no"
# Set arch to arm
ARCH_OVERRIDE="arm"
# No need to mount BOOTDIR and make symlink as the kernel is
# installed manually
MOUNTBOOT="no"
SYMLINK="no"
# Adjust this as needed for the machine.
MAKEOPTS="-j3"
# For Raspberry Pi 3 B in 32/64-bit mode
UTILS_CROSS_COMPILE="armv7a-unknown-linux-gnueabihf-"
KERNEL_CROSS_COMPILE="armv7a-unknown-linux-gnueabihf-"
KERNEL_CC="armv7a-unknown-linux-gnueabihf-gcc"
KERNEL_AS="armv7a-unknown-linux-gnueabihf-as"
KERNEL_LD="armv7a-unknown-linux-gnueabihf-ld"
# Change this to the path of raspberrypi linux kernel sources.
# It is possible to make this a symlink pointing to the
# /usr/src/linux-rpi like it's done with a normal kernel.
# For example: ln -s /usr/src/linux-3.6.11-raspberrypi /usr/src/linux-rpi
DEFAULT_KERNEL_SOURCE="/usr/src/linux-rpi"
# Point this variable to the directory where the SD card is mounted.
# Note that the location needs to be mounted manually before running genkernel.
INSTALL_MOD_PATH="/mnt/raspberrypiroot"
# Genkernel needs access so /usr/share/genkernel (This folder contains default
# environment variables, scripts and source tarballs that enable genkernel to
# work).
GK_SHARE="${GK_SHARE:-/usr/share/genkernel}"
DISTDIR="${GK_SHARE}/distfiles"
# Genkernel also needs to have a logfile to write to. Without this present,
# you'll see "ambiguous redirect" printed out many times between legitimate
# messages.
LOGFILE="/var/log/genkernel.log"
保存配置文件。 挂载树莓派SD卡(假设树莓派的根分区设备是/dev/sdd3):
root #mount /dev/sdd3 /mnt/raspberrypiroot
genkernel配置:
root #ARCH=arm genkernel --config=/etc/genkernel-rpi2.conf --kernel-config=/usr/src/linux-rpi/arch/arm/configs/bcm2709_defconfig kernel
保存配置/usr/local/bin/genkernel-rpi.sh:
#!/bin/sh ARCH=arm genkernel --config=/etc/genkernel-rpi2.conf --kernel-config=/usr/src/linux-rpi/arch/arm/configs/bcm2709_defconfig kernel
root #chmod +x /usr/local/bin/genkernel-rpi.sh
以上步骤是在完善genkernel的一些基本配置,现在我们就可以为我们的树莓派去跑genkernel命令了。
root #genkernel-rpi.sh
安装kernel image
这个步骤在实操过程中是比较棘手的,对于生成在/mnt/raspberrypiroot/boot/kernel.img可能无法正确引导kernel,这时候我们可能要使用到就一些版本的固件:
root #emerge --ask sys-boot/raspberrypi-mkimage
root #imagetool-uncompressed.py arch/arm/boot/Image /mnt/raspberrypiroot/boot/kernel.img
安装WiFi 蓝牙固件
root #emerge sys-kernel/linux-firmware
对于树莓派内置的 Wi-Fi 驱动程序brcmfmac会需要二进制固件 blob brcmfmac434*-sdio.bin。因此我们可能要配置一下brcmfmac434*-sdio.txt才能正常运行。
对于蓝牙,我们需要BCM43430A1.hcd 这个文件来支持运行。我们可以在树莓派官网蓝牙固件处找到,最后只需要将其配置到/lib/firmware/brcm处
root #mkdir -p /lib/firmware/brcm
root #wget -P /lib/firmware/brcm https://raw.githubusercontent.com/RPi-Distro/bluez-firmware/master/broadcom/BCM4345C0.hcd
VideoCore4
要在 RPi 设备上启用 VideoCore4 GPU 加速,请将以下内容添加到/boot/config.txt:
/boot/config.txt
dtoverlay = vc4-kms-v3d,cma-128
最后还要在我们的make.conf添加:
VIDEO_CARDS = "vc4"

Leave a comment