飞羽小随笔-个人技术文章

树莓派镜像制作

因为需要4.19的内核,需要制作树莓派的img镜像,因此,就顺便编译一下树莓派3B+的内核,并制作成树莓派镜像。

树莓派镜像制作

一、树莓派介绍

[collapse title="树莓派介绍" status="false"]
树莓派由注册于英国的慈善组织“Raspberry Pi 基金会”开发,Eben·Upton/埃·厄普顿为项目带头人。2012年3月,英国剑桥大学埃本·阿普顿(Eben Epton)正式发售世界上最小的台式机,又称卡片式电脑,外形只有信用卡大小,却具有电脑的所有基本功能,这就是Raspberry Pi电脑板,中文译名"树莓派"。
[/collapse]

二、基础环境

[scode type="blue"]本文使用的是ubuntu 16.04的系统[/scode]

三、基础环境安装

3.1 编译内核用的工具gcc

[scode type="blue"]本文使用gcc-4.9
下载地址:https://releases.linaro.org/components/toolchain/binaries/
[/scode]

3.1.1下载并配置gcc
root@ubuntu16:~# wget https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu/gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu.tar.xz
# 下载64位gcc
root@ubuntu16:~# mkdir ~/toolchains
# 创建文件夹
root@ubuntu16:~# tar xf gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu.tar.xz -C ~/toolchains/
# 解压缩
root@ubuntu16:~# cd ~/toolchains/gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu/
root@ubuntu16:~# echo 'export PATH=${PATH}:$(pwd)/bin' > env.sh
# 创建环境变量
root@ubuntu16:~# source env.sh
# 让环境变量在当前终端生效
root@ubuntu16:~# wget https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu/gcc-linaro-4.9.4-2017.01-i686_aarch64-linux-gnu.tar.xz
# 下载32位gcc
root@ubuntu16:~# mkdir ~/toolchains
# 创建文件夹
root@ubuntu16:~# tar xf gcc-linaro-4.9-2017.01-i686_aarch64-linux-gnu.tar.xz -C ~/toolchains/
# 解压缩
root@ubuntu16:~# cd ~/toolchains/gcc-linaro-4.9.4-2017.01-i686_aarch64-linux-gnu/
root@ubuntu16:~# echo 'export PATH=${PATH}:$(pwd)/bin' > env.sh
# 配置环境变量
root@ubuntu16:~# source env.sh
# 让环境变量在当前终端生效

3.2 安装依赖环境

[scode type="blue"]依赖环境安装[/scode]

root@ubuntu16:~# sudo apt install build-essential bison make debootstrap qemu-user-static kpartx util-linux vim git libncurses5-dev bc git dosfstools -y
# 安装依赖
root@ubuntu16:~# sudo service binfmt-support start
# 启动binfmt服务

3.3 下载内核并配置

3.3.1 下载内核
root@ubuntu16:~# mkdir ~/kernel
root@ubuntu16:~# cd ~/kernel
# 创建文件夹并进入
root@ubuntu16:~# git clone https://github.com/raspberrypi/linux.git
# 下载linux内核

3.4 下载树莓派的启动文件

root@ubuntu16:~# git clone --depth=1 https://github.com/raspberrypi/firmware/
# git上下载boot文件

3.5 配置树莓派固件

  1. 树莓派3b
    1.1 固件1:brcmfmac43430-sdio.bin
root@ubuntu16:~# mkdir ~/wifi
root@ubuntu16:~# cd ~/wifi
# 新建文件夹并进入
root@ubuntu16:~# wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm/brcmfmac43430-sdio.bin
# 下载brcmfmac43430-sdio.bin

1.2 固件2:brcmfmac43430-sdio.txt

root@ubuntu16:~# wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.txt
# 下载tree/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.txt
root@ubuntu16:~# cp brcmfmac43430-sdio.raspberrypi,3-model-b.txt brcmfmac43430-sdio.txt
# 复制并改名
  1. 树莓派3b+
    2.1 固件1:brcmfmac43455-sdio.bin
root@ubuntu16:~# mkdir ~/wifi
root@ubuntu16:~# cd ~/wifi
# 创建文件夹并进入
root@ubuntu16:~# https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm/brcmfmac43455-sdio.bin
# 下载brcmfmac43455-sdio.bin

2.2 固件2:brcmfmac43455-sdio.txt

root@ubuntu16:~# https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm/brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt
# 下载brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt
root@ubuntu16:~# cp brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt brcmfmac43455-sdio.txt
# 复制并改名
  1. 树莓派3b
    1.1 固件:BCM43430A1.hcd
root@ubuntu16:~# mkdir ~/bluetooth
root@ubuntu16:~# cd ~/bluetooth
root@ubuntu16:~# wget https://github.com/RPi-Distro/bluez-firmware/raw/master/broadcom/BCM43430A1.hcd
  1. 树莓派3b+
    2.1 固件:BCM4345C0.hcd
root@ubuntu16:~# mkdir ~/bluetooth
root@ubuntu16:~# cd ~/bluetooth
root@ubuntu16:~# wget https://github.com/RPi-Distro/bluez-firmware/raw/master/broadcom/BCM4345C0.hcd

四、编译内核

4.1 检查环境变量

root@ubuntu16:~# which aarch64-linux-gnu-gcc

4.2 创建内核编译环境变量并检查

root@ubuntu16:~# echo 'export ARCH=arm64' >> env.sh
root@ubuntu16:~# echo 'export CROSS_COMPILE=aarch64-linux-gnu-' >> env.sh
# 创建环境变量
root@ubuntu16:~# source env.sh
# 初始化环境变量
root@ubuntu16:~# echo "${ARCH}"
#  检查ARCH
root@ubuntu16:~# echo "${CROSS_COMPILE}"
# 检查CROSS_COMPILE
# 如果ARCH为arm64,CROSS_COMPILE为aarch64-linux-gnu-,环境配置正确

4.3 编译内核

4.3.1 内核编译1
root@ubuntu16:~# cd ~/kernel/linux
root@ubuntu16:~# make bcmrpi3_defconfig
# 生成默认配置文件
root@ubuntu16:~# make menuconfig
# 修改默认配置文件
4.3.2 内核配置

默认为配置如下图所示:

[*] Virtualization ---
[*] Kernel-based Virtual Machine (KVM) support 
<M> Host kernel accelerator for virtio net
[*] Cross-endian support for vhost
# 在Virtualization下的所有选项选中
# 然后按住左右按键找到save保存一下
General setup  ---> 
    -*- Control Group support  --->
        [*]   Memory controller          
        [*]     Swap controller                               
        [*]       Swap controller enabled by default (NEW)     
        [*]   IO controller                        
        -*-   CPU controller  --->                  
            [*]     CPU bandwidth provisioning for FAIR_GROUP_SCHED    
            [*]   Group scheduling for SCHED_RR/FIFO                    
        [*]   PIDs controller                        
        [*]   RDMA controller                         
        [*]   Freezer controller                       
        [*]   Cpuset controller     
        [*]     Include legacy /proc/<pid>/cpuset file  
        [*]   Device controller      
        [*]   Simple CPU accounting controller    

[scode type="blue"]使用CRIU必须开启[/scode]

General setup  ---> 
    [*] Checkpoint/restore support  

例如usb网卡驱动

Device Drivers  --->
    [*] Network device support  --->
        [*]   Wireless LAN  --->
            [*]   Realtek devices                      
            <M>   Realtek 8187 and 8187B USB support               
            <M>     Realtek rtlwifi family of devices  --->           
            <M>     Realtek 8192C USB WiFi                             
            <M>    RTL8723AU/RTL8188[CR]U/RTL819[12]CU (mac80211) support       

[scode type="blue"]选择完成后选择save后按exit钮退出即可[/scode]

4.3.3 内核编译
root@ubuntu16:~# make -j 4
# 编译内核

五、制作rootfs

root@ubuntu16:~# mkdir ~/rootfs/

[scode type="blue"]请从以下地址选取rootfs[/scode]

[collapse title="基本rootfs镜像" status="false"]

[/collapse]

root@ubuntu16:~# mkdir -p ~/rootfs/4.19/
# 创建文件夹
root@ubuntu16:~# cd rootfs/4.19
# 进入
root@ubuntu16:~# cp /usr/bin/qemu-aarch64-static  usr/bin
# 拷贝qemu-aarch64-static到usr/bin
root@ubuntu16:~# sudo mount -o bind /dev/ dev
root@ubuntu16:~# sudo mount -o bind /dev/pts dev/pts
root@ubuntu16:~# sudo mount -o bind /proc proc
root@ubuntu16:~# sudo mount -o bind /sys sys
root@ubuntu16:~# $ sudo cp etc/hosts etc/hosts.bak
# 备份原HOSTS
root@ubuntu16:~# sudo cp etc/resolv.conf etc/resolv.conf.bak
#备份原resolv.conf
root@ubuntu16:~# sudo cp /etc/hosts etc/hosts
# 复制系统文件
root@ubuntu16:~# sudo cp /etc/resolv.conf etc/resolv.conf
# 复制系统文件
root@ubuntu16:~# sudo chroot ./ /bin/sh
# 使用chroot进入
chroot # 
# 进入后
chroot # passwd root
# 更改密码,注意登入需要
chroot # apt update
# 更新
chroot # apt install vim wpasupplicant net-tools openssh-server bash-com* netbase iproute2 iputils-ping git 
# 安装依赖
chroot # exit
# 退出
root@ubuntu16:~# sudo umount dev/pts
root@ubuntu16:~# sudo umount dev
root@ubuntu16:~# sudo umount proc
root@ubuntu16:~# sudo umount sys
# 卸载文件系统
root@ubuntu16:~# sudo mv etc/hosts.bak etc/hosts
root@ubuntu16:~# sudo mv etc/resolv.conf.bak etc/resolv.conf
# 恢复网络配置
root@ubuntu16:~# sudo du -sh ./
# 有用
镜像大小= rootfs大小 + 300M + 200M

五、制作镜像文件

5.1 分区

[scode type="blue"]首先创建images文件[/scode]

root@ubuntu16:~# mkdir ~/images/
root@ubuntu16:~# cd ~/images/
root@ubuntu16:~# dd bs=1M count=545 if=/dev/zero of=ubuntu.img
# 根据镜像大小计算公式计算出的镜像大小来创建,本文创建的大小位545M

[scode type="blue"]为镜像分区[/scode]

root@ubuntu16:~# cfdisk ubuntu.img

[scode type="blue"]分区表选择dos[/scode]












                                       ┌ Select label type ───┐
                                       │ gpt                  │
                                       │ dos     *            │
                                       │ sgi                  │
                                       │ sun                  │
                                       └──────────────────────┘










                        Device does not contain a recognized partition table.
                Select a type to create a new label or press 'L' to load script file.

[scode type="blue"]选 new 创建分区,分区大小为100M,并且选择主分区,分区如下所示[/scode]


                                       Disk: ubuntu.img
                            Size: 545 MiB, 571473920 bytes, 1116160 sectors
                                  Label: dos, identifier: 0xd5f9f036

    Device                  Boot           Start        End     Sectors      Size     Id Type
>>  ubuntu.img1      *               2048     206847      204800      100M     83 Linux        
    Free space                       206848   1116159     909312      444M

 ┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
 │Partition type: Linux (83)                                                                        │
 │    Attributes: 80                                                                                │
 └──────────────────────────────────────────────────────────────────────────────────────────────────┘
    [ * Bootable]  [ Delete ]  [ Resize ]  [  Quit  ]  [  Type  ]  [  Help  ]  [  Write ]  [  Dump  ]

[scode type="blue"]选bootable使刚才创建的分区设定为可启动,Boot下,有一个星号代表设置完成[/scode]

    Device                  Boot           Start        End     Sectors      Size     Id Type
>>  ubuntu.img1               *      2048     206847      204800      100M     83 Linux        
    Free space                       206848   1116159     909312      444M

[scode type="blue"]选“type”改变分区标识,找到“W95 FAT32” 并回车,成功之后“Id Type”显示“b W95 FAT32”字样[/scode]

    Device                  Boot           Start        End     Sectors      Size     Id Type
>>  ubuntu.img1               *      2048     206847      204800      100M     83 Linux  b W95 FAT32      
    Free space                       206848   1116159     909312      444M

[scode type="blue"]按方向健下,切换到空余空间.选择new新健一个分区,分区使用所有空余空间,选择primary 主分区,成功之后如下显示[/scode]

    Device                  Boot           Start        End     Sectors      Size     Id Type
>>  ubuntu.img1               *      2048     206847      204800      100M     83 Linux  b W95 FAT32      
    ubuntu.img2                       206848   1116159     909312      444M

[scode type="blue"]选择Write 将更改写入镜像[/scode]

5.2 写入内容到img文件

5.2.1用kpartx挂载镜像到loop
root@ubuntu16:~/images# kpartx -av ubuntu.img
add map loop0p1 (252:2): 0 204800 linear 7:0 2048
add map loop0p2 (252:3): 0 909312 linear 7:0 206848
# 输出的信息就是需要挂载的文件
# loop0p1 为第一个分区
# loop0p2 为第二个分区
5.2.2 格式化分区
root@ubuntu16:~/images# sudo mkfs.vfat /dev/mapper/loop0p1
# 格式化第一个分区
root@ubuntu16:~/images# sudo mkfs.ext4 /dev/mapper/loop0p2
# 格式化第二个分区
root@ubuntu16:~/images# sudo apt install f2fs-tools
root@ubuntu16:~/images# sudo mkfs.f2fs -f /dev/mapper/loop0p2
# 格式化第二个分区
5.2.3挂载镜像
root@ubuntu16:~/images# sudo mkdir /mnt/loop0p1
# 创建文件夹
root@ubuntu16:~/images# sudo mount /dev/mapper/loop0p1 /mnt/loop0p1
# 挂载loop0p1
root@ubuntu16:~/images# sudo mkdir /mnt/loop0p2
# 创建文件夹
root@ubuntu16:~/images# sudo mount /dev/mapper/loop0p2 /mnt/loop0p2
# 挂载loop0p2
5.2.4向镜像里写入内容

[scode type="blue"]向第一个分区写入内容[/scode]

向第一个分区写入内容

[scode type="blue"]本节内容是向第一个分区写入启动引导。[/scode]

root@ubuntu16:~/images# cp -r /root/firmware/boot/* /mnt/loop0p1/
# 复制boot文件到loop0p1
root@ubuntu16:~/images# cd ~/kernel/linux/
# 进入编译的内核的工作目录
root@ubuntu16:~/kernel/linux# sudo cp ./arch/arm64/boot/Image /mnt/loop0p1/kernel8.img
# 复制编译好的内核
root@ubuntu16:~/kernel/linux# sudo mv /mnt/loop0p1/bcm2710-rpi-3-b.dtb /mnt/loop0p1/bcm2710-rpi-3-b.dtb_32
root@ubuntu16:~/kernel/linux# sudo mv /mnt/loop0p1/bcm2710-rpi-3-b-plus.dtb /mnt/loop0p1/bcm2710-rpi-3-b-plus.dtb_32
# 将32位的dtb文件更名
root@ubuntu16:~/kernel/linux# sudo cp ./arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /mnt/loop0p1/bcm2710-rpi-3-b.dtb
root@ubuntu16:~/kernel/linux# sudo cp ./arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dtb /mnt/loop0p1/bcm2710-rpi-3-b-plus.dtb
# 复制64位的dtb文件
root@ubuntu16:~/kernel/linux# sudo vim /mnt/loop0p1/cmdline.txt

写入内容

root=/dev/sda2 rootfstype=ext4 rw rootwait fsck.repair=yes program_usb_boot_mode=1

[scode type="blue"]注意:“program_usb_boot_mode=1”为u盘启动,如果内存卡启动请删除“program_usb_boot_mode=1”这行代码[/scode]

1.2 rootfstype=ext4 根分区类型 f2fs应更换为f2fs
1.3 rw 可写挂载跟分区
1.4 rootwait 等待内核识别根分区设备后再挂载
1.5 fsck.repair=yes 启动时自动检查修复文件系统错误

[scode type="blue"]向第二个分区写入内容[/scode]

向第二个分区写入内容

[scode type="blue"]本节主要内容是安装内核模块、固件和rootfs系统到镜像的第二个分区。[/scode]

root@ubuntu16:~/kernel/linux# cd ~/kernel/linux
#进入编译内核的工作目录
root@ubuntu16:~/kernel/linux# make modules_install INSTALL_MOD_PATH=/mnt/loop0p2
root@ubuntu16:~/kernel/linux# mkdir -p /mnt/loop0p2/lib/firmware/brcm
root@ubuntu16:~/kernel/linux# cp -r ~/wifi/* /mnt/loop0p2/lib/firmware/brcm/
root@ubuntu16:~/kernel/linux# cp -r ~/bluetooth/* /mnt/loop0p2/lib/firmware/brcm/
root@ubuntu16:~/kernel/linux# sync
# 同步写入
root@ubuntu16:~# sudo apt install rsync
# 安装rsync同步工具
root@ubuntu16:~# sudo rsync -HPavz -q ./ /mnt/loop0p2
# 使用rsync同步到loop0p2分区
root@ubuntu16:~# sync
# 同步一下
root@ubuntu16:~/kernel/linux# sudo umount /dev/mapper/loop0p1
root@ubuntu16:~/kernel/linux# sudo umount /dev/mapper/loop0p2
root@ubuntu16:~/kernel/linux# sudo kpartx -dv /dev/loop0
root@ubuntu16:~/kernel/linux# sudo losetup -d /dev/loop0

六、测试

[scode type="blue"]请自己进行测试,如果按照我的步骤来,应该不会出错,本人已经实验完成。[/scode]


当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »