飞羽

树莓派镜像制作
因为需要4.19的内核,需要制作树莓派的img镜像,因此,就顺便编译一下树莓派3B+的内核,并制作成树莓派镜像。
扫描右侧二维码阅读全文
08
2019/07

树莓派镜像制作

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

树莓派镜像制作

树莓派镜像制作2.jpg

一、树莓派介绍

树莓派介绍

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

二、基础环境

  • 使用X86交叉编译
  • 需要10G的硬盘空间

本文使用的是ubuntu 16.04的系统

三、基础环境安装

3.1 编译内核用的工具gcc

3.1.1下载并配置gcc
  • 64位下载
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
# 让环境变量在当前终端生效
  • 32位下载
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 安装依赖环境

依赖环境安装

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 配置树莓派固件

  • wifi固件
  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 内核配置

默认为配置如下图所示:

树莓派镜像制作1.png

  • 如果需要虚拟化支持,请选择
[*] Virtualization ---
[*] Kernel-based Virtual Machine (KVM) support 
<M> Host kernel accelerator for virtio net
[*] Cross-endian support for vhost
# 在Virtualization下的所有选项选中
# 然后按住左右按键找到save保存一下
  • 如果需要cgroup支持,请选择
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    
  • 如果需要Checkpoint/restore支持,请选择:

使用CRIU必须开启

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       

选择完成后选择save后按exit钮退出即可

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

五、制作rootfs

  • 首先创建rootfs文件夹
root@ubuntu16:~# mkdir ~/rootfs/

请从以下地址选取rootfs

  • 我选取的位ubuntu16.04版本
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
# 恢复网络配置
  • 计算一下rootfs大小
root@ubuntu16:~# sudo du -sh ./
# 有用
  • 镜像大小计算公式
镜像大小= rootfs大小 + 300M + 200M

五、制作镜像文件

5.1 分区

首先创建images文件

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

为镜像分区

  • 为镜像分区
root@ubuntu16:~# cfdisk ubuntu.img

分区表选择dos

  • 分区表选择dos











                                       ┌ 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.

选 new 创建分区,分区大小为100M,并且选择主分区,分区如下所示


                                       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  ]

选bootable使刚才创建的分区设定为可启动,Boot下,有一个星号代表设置完成

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

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

    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

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

    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

选择Write 将更改写入镜像

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 格式化分区
  • 格式化为ext4
root@ubuntu16:~/images# sudo mkfs.vfat /dev/mapper/loop0p1
# 格式化第一个分区
root@ubuntu16:~/images# sudo mkfs.ext4 /dev/mapper/loop0p2
# 格式化第二个分区
  • 格式化为f2fs【如果你想把第二个分区格式化为f2fs】
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向镜像里写入内容

向第一个分区写入内容

向第一个分区写入内容

本节内容是向第一个分区写入启动引导。

  • 为第一个分区写入内容
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文件
  • 写cmdline.txt
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

注意:“program_usb_boot_mode=1”为u盘启动,如果内存卡启动请删除“program_usb_boot_mode=1”这行代码

  • 其他说明
    1.1 root=/dev/sda2 将第二分区设置为根分区

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

向第二个分区写入内容

向第二个分区写入内容

本节主要内容是安装内核模块、固件和rootfs系统到镜像的第二个分区。

  • 1.安装内核模块
root@ubuntu16:~/kernel/linux# cd ~/kernel/linux
#进入编译内核的工作目录
root@ubuntu16:~/kernel/linux# make modules_install INSTALL_MOD_PATH=/mnt/loop0p2
  • 2.放入wifi和蓝牙固件
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
# 同步写入
  • 3.写入rootfs系统
root@ubuntu16:~# sudo apt install rsync
# 安装rsync同步工具
root@ubuntu16:~# sudo rsync -HPavz -q ./ /mnt/loop0p2
# 使用rsync同步到loop0p2分区
root@ubuntu16:~# sync
# 同步一下
  • 4.卸载分区
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

六、测试

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


文章名: 《树莓派镜像制作》

文章链接:https://blog.8086k.cn/archives/64/

联系方式:1412981048@qq.com

除特别注明外,文章均为飞羽小随笔原创,转载时请注明本文出处及文章链接
Last modification:July 8th, 2019 at 02:32 pm
如果觉得我的文章对你有用,请随意赞赏

One comment

  1. 飞羽 Google Chrome 80.0.3987.122 Windows 10

    滴!访客卡!请上车的乘客系好安全带,现在是:Fri Mar 06 2020 14:15:09 GMT+0800 (中国标准时间)

Leave a Comment Cancel reply