为树莓派3B交叉编译安装Gentoo

本文章随时可能停止更新或未及时更新,仅作参考

参考文章:

Raspberry Pi 3 64 bit Install

Embedded Handbook/General/Compiling with qemu user chroot

准备:

开始:

环境

Crossdev

先安装好交叉编译环境:

emerge --ask sys-devel/crossdev
crossdev -t aarch64-unknown-linux-gnu

如果提示:error: please convert /etc/portage/package.env to a directory则运行如下命令并重新运行crossdev -t aarch64-unknown-linux-gnu

mv /etc/portage/package.env /etc/portage/package.env_file
mkdir /etc/portage/package.env
mv /etc/portage/package.env_file /etc/portage/package.env

运行gcc-config -l显示aarch64-unknown-linux-gun-x.x.x确认安装成功

Qemu

更改配置:

echo app-emulation/qemu static-user >> /etc/portage/package.use
echo 'QEMU_SOFTMMU_TARGETS="alpha aarch64 arm i386 mips mips64 mips64el mipsel ppc ppc64 s390x sh4 sh4eb sparc sparc64 x86_64"' >> /etc/portage/make.conf
echo 'QEMU_USER_TARGETS="alpha aarch64 arm armeb i386 mips mipsel ppc ppc64 ppc64abi32 s390x sh4 sh4eb sparc sparc32plus sparc64"' >> /etc/portage/make.conf

安装:emerge --ask app-emulation/qemu

创建二进制包(重要):quickpkg app-emulation/qemu

假设你已正确配置好qemu相关的内核选项且已启用CONFIG_BINFMT_MISC

[ -d /proc/sys/fs/binfmt_misc ] || modprobe binfmt_misc
[ -f /proc/sys/fs/binfmt_misc/register ] || mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc

注册:

echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register

启用并启动binfmt服务(如果不常用可以只启动):

# openRC:
rc-update add qemu-binfmt
rc-service qemu-binfmt start
# systemd:
systemctl enable systemd-binfmt
systemctl restart systemd-binfmt

编译内核&驱动

安装git(如果你没安装的话):emerge --ask dev-vcs/git

创建工作目录:mkdir raspberrypi

克隆rpi的firmware:

cd raspberrypi
git clone https://github.com/raspberrypi/firmware

PS:如果你的clone速度捉急。。。可以加上--depth=1参数

克隆rpi的内核源码:git clone https://github.com/raspberrypi/linux

进入内核源码目录选择版本:

cd linux
git branch -a #查看最新的版本
git checkout XXX # 这里的XXX换成最新版本的内核,比如:rpi-4.14.y

生成rpi3内核的默认配置并打开配置界面:

ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- make bcmrpi3_defconfig
ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- make menuconfig

在内核选项中:CPU Power Management ---> CPU Frequency scaling ---> Default CPUFreq governor (powersave) --->
选择为performance

这里你也可以自己更改内核配置(如果你了解的话)

开始编译内核:
ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- make -jX #X换成你的核心数

分区&安装stage3

sd卡插读卡器插电脑

使用你喜欢的分区工具调整为如下:

/dev/sdX1    boot    vfat    128M
/dev/sdX2    swap    >=2G
/dev/sdX3    ext4    free space

格式化:

mkfs -t vfat -F 32 /dev/sdX1
mkswap /dev/sdX2
mkfs -i 8192 -t ext4 /dev/sdX3 # wiki说这个-i 8192挺重要的

挂载分区:

mkdir /mnt/gentoo
mount /dev/sdX3 /mnt/gentoo
cd /mnt/gentoo

这里下载最新的stage3并解压:

wget http://distfiles.gentoo.org/experimental/arm64/`wget -q http://distfiles.gentoo.org/experimental/arm64/ && grep -o stage3-arm64-.........tar.bz2 index.html | head -1`
tar vxpf stage3-*.tar.bz2 --xattrs-include='*.*' --numeric-owner .

安装内核

挂载boot分区:mount /dev/sdX1 /mnt/gentoo/boot

将raspberrypi目录中的/firmware/boot/*复制到/mnt/gentoo/boot
cp -r path/to/raspberrypi/firmware/boot/* /mnt/gentoo/boot

安装内核:cp /path/to/raspberrypi/linux/arch/arm64/boot/Image /mnt/gentoo/boot/kernel8.img

更换原32bit的设备树为64bit:

mv /mnt/gentoo/boot/bcm2710-rpi-3-b.dtb /mnt/gentoo/boot/bcm2710-rpi-3-b.dtb_32
cp /path/to/raspberrypi/linux/arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /mnt/gentoo/boot

安装内核模块:

cd /path/to/raspberrypi/linux
ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- make modules_install INSTALL_MOD_PATH=/mnt/gentoo

这时候应该确认下boot目录是否正确复制了文件

Chroot进入系统

为树莓派安装qemu:ROOT="/mnt/gentoo" emerge --usepkgonly --oneshot --nodeps qemu

创建并挂载必要目录:

mkdir -p /mnt/gentoo/usr/portage
mkdir -p /mnt/gentoo/var/tmp/portage
mount --bind /usr/portage /mnt/gentoo/usr/portage
mount --bind /var/tmp/portage /mnt/gentoo/var/tmp/portage

mount --bind /proc /mnt/gentoo/proc
mount --bind /sys /mnt/gentoo/sys
mount --bind /dev /mnt/gentoo/dev
mount --bind /dev/pts /mnt/gentoo/pts

Chroot进入系统:chroot /mnt/gentoo/ /bin/bash --login

配置系统

串口配置:nano -w /etc/inittab
注释掉f0:12345:respawn:/sbin/agetty 9600 ttyAMA0 vt100并保存

添加udev规则:nano -w /etc/udev/rules.d/99-com.rules
写入:

SUBSYSTEM=="input", GROUP="input", MODE="0660"
SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660"
SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"
SUBSYSTEM=="bcm2835-gpiomem", GROUP="gpio", MODE="0660"

SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c '\
        chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio;\
        chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio;\
        chown -R root:gpio /sys$devpath && chmod -R 770 /sys$devpath\
'"

KERNEL=="ttyAMA[01]", GROUP="dialout", PROGRAM="/bin/sh -c '\
        ALIASES=/proc/device-tree/aliases; \
        if cmp -s $ALIASES/uart0 $ALIASES/serial0; then \
                echo 0;\
        elif cmp -s $ALIASES/uart0 $ALIASES/serial1; then \
                echo 1; \
        else \
                exit 1; \
        fi\
'", SYMLINK+="serial%c"

KERNEL=="ttyS0", GROUP="dialout", PROGRAM="/bin/sh -c '\
        ALIASES=/proc/device-tree/aliases; \
        if cmp -s $ALIASES/uart1 $ALIASES/serial0; then \
                echo 0; \
        elif cmp -s $ALIASES/uart1 $ALIASES/serial1; then \
                echo 1; \
        else \
                exit 1; \
        fi \
'", SYMLINK+="serial%c"

其它蓝牙什么的因为我暂时不需要就懒得写了(不坑人了)

更改root密码:passwd

更改fstab:

/dev/mmcblk0p1          /boot           vfat            noauto,noatime  1 2
/dev/mmcblk0p2          none            swap            sw              0 0
/dev/mmcblk0p3          /               ext4            noatime         0 1

创建/boot/config.txt写入:

# have a properly sized image
disable_overscan=1

# lets have the VC4 hardware accelerated video
dtoverlay=vc4-fkms-v3d

# for sound over HDMI
hdmi_drive=2

# Enable audio (loads snd_bcm2835)
dtparam=audioon

# gpu_mem is for closed-source driver only; since we are only using the
# open-source driver here, set low
gpu_mem=16

创建/boot/cmdline.txt并写入:

root=/dev/mmcblk0p3 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

编辑/etc/portage/make.conf修改或添加:

...
CFLAGS="-march=armv8-a+crc -mtune=cortex-a53 -ftree-vectorize -O2 -pipe -fomit-frame-pointer"
...
ACCEPT_KEYWORDS="~arm64"

更新系统并安装必要软件

更新系统:emerge -auvDN @world

编辑/etc/ssh/sshd_config确保PermitRootLogin没有被注释且后面为yes

安装网络管理器:

echo net-misc/connman iptables >> /etc/portage/package.use
emerge -av connman

安装校时软件:emerge -av chrony

配置时区:

echo "Asia/Shanghai"  > /etc/timezone
emerge --ask sys-libs/timezone-data

配置locale:

echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen

启用开机服务:

rc-update add sshd default
rc-update add connman default
rc-update add chronyd default

插卡上电,查IP ssh连接

8条评论
  1. Jerry
    Jerry2018-12-13

    在qemu的“注册”这一步,我报错提示echo: write error: invalid argument,你有遇见过这种情况没。。。

    1. YangMame
      YangMame2018-12-13

      刚刚试了下没有这个问题 检查下make.conf是否正确写好了配置并在编译qemu(emerge -av qemu)时QEMU_SOFTMMU_TARGETS和QEMU_SOFTMMU_TARGETS有显示对应的构架 还有内核是否启用了相关的选项或加载文章中说的模块

      回复
    回复
  2. Jerry
    Jerry2018-12-13

    111

    回复
  3. Jerry
    Jerry2018-12-13

    make.conf配置无误,emerge -av qemu 后显示下面内容,有显示aarch64架构:

    [ebuild R ] app-emulation/qemu-2.12.1::gentoo
    ...
    QEMU_SOFTMMU_TARGETS="aarch64 alpha arm i386 mips mips64 mips64el mipsel ppc ppc64 s390x sh4 sh4eb sparc sparc64 x86_64 -cris -hppa -lm32 -m68k -microblaze -microblazeel -moxie -nios2 -or1k -ppcemb -riscv32 -riscv64 -tricore -unicore32 -xtensa -xtensaeb"
    QEMU_USER_TARGETS="aarch64 alpha arm armeb i386 mips mipsel ppc ppc64 ppc64abi32 s390x sh4 sh4eb sparc sparc32plus sparc64 -aarch64_be -cris -hppa -m68k -microblaze -microblazeel -mips64 -mips64el -mipsn32 -mipsn32el -nios2 -or1k -ppc64le -riscv32 -riscv64 -tilegx -x86_64 -xtensa -xtensaeb" 0 KiB
    ...

    lsmod也显示加载了binfmt_misc模块。
    另外发现用bash和zsh显示的报错信息还不相同,bash显示echo: write error: File exists,但试图删除这个文件会提示权限不足。

    回复
  4. [...]Raspberry Pi 3 64 bit Install为树莓派3B交叉编译安装Gentoo[...]

    1. YangMame
      YangMame2018-12-16

      嘛 解决了? 那天正在准备去上海没能回复

      1. Jerry
        Jerry2018-12-17

        解决了,zsh的事情,不用zsh就好了,原因不知道。

        1. YangMame
          YangMame2018-12-17

          应该是语法的问题 zsh和bash语法有点不一样

          回复
        回复
      回复
    回复
添加新评论