OrangePi zero 最小软件系统构建过程记录 / 全志 SOC / WhyCan Forum(哇酷开发者社区) 您所在的位置:网站首页 系统构建的过程 OrangePi zero 最小软件系统构建过程记录 / 全志 SOC / WhyCan Forum(哇酷开发者社区)

OrangePi zero 最小软件系统构建过程记录 / 全志 SOC / WhyCan Forum(哇酷开发者社区)

2024-02-26 08:41| 来源: 网络整理| 查看: 265

一下是我最近摸索构建一个最简单用于 OrangePi zero 的系统的过程,笔记是我从自己 OneNote 复制的,图片丢失,语言表述,格式等恐存在问题,见谅。也算踩了很多的坑,有些问题比较奇葩,网上搜索,qq群请教无果,最后也在本论坛上得到了帮助: https://whycan.cn/t_3243.html#p27998 也就把自己记录分享出来。            1. 大致流程        a. u-boot 编译,启用 ethernet 以太网,烧写到 sd 卡,验证 网络能用        b. 编译内核生成 zImage 和 dtb,放在开发机上的 tftp 目录, u-boot 端通过 tftp 下载内核和dt,并启动内核        c. 有了 u-boot 和 内核,还需要构建根文件系统 -- rootfs,使用 buildroot 构建, 并部署到开发机的 nfs 目录,避免重复插拔 sd 卡;u-boot 启动内核并通过 bootargs 传递 cmd line 给内核,内核通过nfs挂载rootfs。        d. 验证系统可用性        e. 烧写到 sd 卡    2. u-boot        a. 源码        opz 和 友善 nanopi duo 都是用 h2+,orangepi 技术支持太糟糕,所以采用友善 nanopi h3 的源码:         git clone https://github.com/friendlyarm/u-boot.git -b sunxi-v2017.x --depth 1        参考: http://wiki.friendlyarm.com/wiki/index.php/Building_U-boot_and_Linux_for_H5/H3/H2%2B                b. 配置编译            i. 默认配置                1) make ARCH=arm nanopi_h3_defconfig                2) configs/ 下有几个 h2+ soc 相关的                    a) orangepi_zero_defconfig  是 orangepi zero 的配置                    b) nanopi_h3_defconfig 是 nanopi h3 的配置,但是兼容 h2+            虽然我板子是 orangepi zero,但是这份源码是 友善修改过适配 h3 的,所以选择 nanopi_h3_defconfig 作为初始配置            ii. u-boot bootcmd 设置,bootcmd value :            fatload mmc 0:1 ${scriptaddr} boot.scr; source ${scriptaddr}                                                这个 bootcmd 命令会在 u-boot 指定 boot 命令时执行,或者自动加载时执行(倒计时之后)            它做的事:                1) 从 mmc 0:1 分区,也就是 sd 卡 fat 分区(boot) 加载 boot.scr 文件到 内存,地址由环境变量 scriptaddr 决定                2) 执行boot.scr 脚本                3) boot.scr 后面我们会看到,它就是加载内核的                4) 所以,u-boot 能够移到内核,这一个命令起到了关键的作用                        编译为 boot.scr             mkimage -C none -A arm -T script -d boot.cmd boot.scr                        iii. 配置以太网卡                1) > Device Drivers > Network device support                Allwinner Sun8i Ethernet MAC support  打勾            iv. 选择 u-boot dts 文件:不能使用 nanopi 的因为板级外设不同            Device Tree Control-> sun8i-h2-plus-orangepi-zero  注意不需要后缀            v. 保存配置文件            make ARCH=arm savedefconfig            会生成 defconfig 文件            mv defconfig configs/opz_defconfig            vi. 编写编译脚本 rebuild.sh             #!/bin/sh            time make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 2>&1 | tee build.log            vii. 编译 ./rebuild.h            viii. 生成              u-boot-sunxi-with-spl.bin        c. 烧写 u-boot            i. 把 sd 读卡器接入 vmware 虚拟机            ii. 烧写u-boot 镜像              ls /dev/sd*  查看sd卡的磁盘标号 一般是 sdb,sdb1,sdb2            dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8sync && eject /dev/sdb        d. 上电测试            i. 串口插上,查看日志                                    ii. 验证网卡                1) 插入网线到路由器 路由器网段 192.168.1.1/24                2) 设置关闭自动加载 setenv autoload no  (不然dhcp会触发自动从tftp 加载,但是我们还没配置)                3) dhcp  正常的话,会输出 bound to ip地址的日志                4) ping 192.168.1.1  会显示 host is alive    3. tftp 配置        a. tftp 是 u-boot 支持的网络文件共享方式,用于从另一个PC下载文件        b. 配置 ubuntu 运行 tftp 服务端            i. vmware 里的 ubuntu 增加桥接网络 —— 虚拟机接入路由器,拥有独立ip,开发板才能通过ip地址访问到            ii. 安装配置 tftp 服务  https://www.davidsudjiman.info/2006/03/27/installing-and-setting-tftpd-in-ubuntu/                1) sudo apt-get install xinetd tftpd tftp                2) 创建配置文件  /etc/xinetd.d/tftp                service tftp                {                protocol        = udp                port            = 69                socket_type     = dgram                wait            = yes                user            = nobody                server          = /usr/sbin/in.tftpd                server_args     = /tftpboot                disable         = no                }                3) 创建共享目录  /tftpboot                $ sudo mkdir /tftpboot                $ sudo chmod -R 777 /tftpboot                $ sudo chown -R nobody /tftpboot                4) 启动服务                $ sudo /etc/init.d/xinetd start                5) 在 /tftpboot 放置测试文件                 touch /tftpboot/hello        c. 在 u-boot 命令行,测试 tftp            i. 服务端地址环境变量设置            setenv serverip 192.168.1.76            ii. tftp 0x41000000 hello            日志显示下载到文件    4. linux 内核        a. 源码        opz 和 友善 nanopi duo 都是用 h2+,orangepi 技术支持太糟糕,所以采用友善 nanopi h3 的源码:         git clone https://github.com/friendlyarm/linux.git -b sunxi-4.14.y --depth 1        参考: http://wiki.friendlyarm.com/wiki/index.php/Building_U-boot_and_Linux_for_H5/H3/H2%2B        源码版本比荔枝派源码更新        b. 选择基础配置            i. 只有 sunxi_defconfig 可选            make  ARCH=arm sunxi_defconfig        c. 配置内核            make  ARCH=arm menuconfig            i. System Type                                    ii. Device Drivers > Network device support > Ethernet driver support                        为什么全志的网卡跟 ST 是关联的?                        iii. File Systems > Network File Systems            使能 nfs                                d. 保存配置        make ARCH=arm savedefconfig        mv defconfig arch/arm/configs/opz_defconfig                e. 创建编译脚本, 编译完成,拷贝镜像文件到 result_image/ 目录,方便导出        #!/bin/sh        make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 &&\        make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 INSTALL_MOD_PATH=out modules &&\        make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 INSTALL_MOD_PATH=out modules_install &&\        mkdir ./result_image -p  &&\        cp arch/arm/boot/zImage ./result_image &&\        cp arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dtb ./result_image/opz.dtb        f. 编译         ./rebuild.sh        g. 在 result_image/ 生成了 zImage 和 opz.dtb, dtb 复制的是orangepi-zeror 的与开发板对应        h. 测试 uboot tftp 加载内核            i. u-boot 正常的启动流程                1) boot.cmd 会被编译成 boot.scr,存放在sd 卡 boot 分区里                2) u-boot 环境变量 bootcmd,上一节提到的,它的作用就是去sd卡上加载 boot.scr 并执行                                                3) boot.cmd -> boot.scr                #boot.scr                  setenv bootargs console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk2p2 rootfstype=ext4 earlyprintk rw                load mmc 0:1 0x41000000 zImage                load mmc 0:1 0x41800000 opz.dtb                bootz 0x41000000 - 0x41800000                第一行设置的是 bootargs 环境变量,是传递给内核的参数                第二行从mmc0 分区1 也就是 mmcblk0p1 加载 zImage 文件到内存 0x41000000 地址处,也就是把zImage 从 sd卡 boot 分区拷贝到内存                第三行把 opz.dtb 加载到内存 0x41800000 地址处                第四行,跳转到 0x41000000 运行内核,也就是启动 linux 内核, u-boot 会把 bootargs 的值传给内核                                                mkimage -C none -A arm -T script -d boot.cmd boot.scr                            ii. 改用 tftp 启动            上面我们摸清了 u-boot 从sd卡的引导内核的流程,下面我用 tftp 的方式来代替                1) 设置 bootargs                原来 bootargs 是在 boot.scr 脚本里设置的,当然我们也可以通过 tftp 加载 boot.scr;不过,这种情况,直接设置 bootargs 环境变量即可:                => setenv bootargs console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk2p2 rootfstype=ext4 earlyprintk rw                => saveenv                # 没有改变,只是手动设定,并保存                2) 设置 bootcmd 环境变量                我们不需要 boot.scr 了,所以,bootcmd 可以直接代替 boot.scr 的功能                => setenv bootcmd                        tftp 0x41000000 zImage; tftp 0x41800000 opz.dtb; bootz 0x41000000 - 0x41800000                => saveenv                    1) 加载 zImage, 从 serverip:/tftpboot/ 下载 zImage                    2) 加载 dtb, 从 serverip:/tftpboot/ 下载 opz.dtb                    3) 启动内核                3) 启动,执行boot 命令,则会执行 bootcmd 并, 传递 bootargs                boot                 4) linux 下 tftp命令 : tftp 192.169.1.76 -g -r zImage -l zImage    5. 根文件系统 —— 使用 buildroot 构建根文件系统        a. buildroot 源码        https://buildroot.org/download.html        https://buildroot.org/downloads/buildroot-2019.02.7.tar.gz        git clone git://git.buildroot.net/buildroot  -b 2019.02.x        buildroot 不光可以构建根文件系统,还可以连内核,uboot 一键构建,最主要是用来把系统依赖的软件包打包进去根文件系统        b. 配置        make ARCH=arm menuconfig            i. Target options                                    ii. Toolchain                                1) 使用外部工具链: buildroot 可以支持内建交叉工具链(连工具链都给你准备好了 ?),但是我们这里使用跟编译u-boot 和 内核相同的外部工具链就可以                2) Custom toolchain 自定义的工具链                3) 工具链路径   /opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/                4) 工具链前缀  arm-linux-gnueabihf                5) 工具链 gcc 版本  6.x   查看工具链目录就知道                6) 头文件版本,查看                cat /opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include/linux/version.h                 #define LINUX_VERSION_CODE 263680                #define KERNEL_VERSION(a,b,c) (((a) ms dos blablabla -> *            iv. 恢复 u-boot bootcmd 默认引导            setenv bootcmd "load mmc 0:1 ${scriptaddr} boot.scr; source ${scriptaddr}"            fatload 改为 load , load 支持其他格式文件系统            v. 调试技巧                1) 从 tftp 加载 boot.scr,并启动                setenv bootcmd "tftp ${scriptaddr} boot.scr; source ${scriptaddr}"                saveenv                boot                2) 从 tftp 更新 zImage                setenv bootcmd "tftp ${scriptaddr} boot.scr; source ${scriptaddr}"                setenv serverip 192.168.1.76                setenv ipaddr 192.168.1.172                tftp 命令需要先设置好ip                3) 在linux系统里从 tftp 下载文件                tftp -g -r boot-mmc.scr 192.168.1.76        8. 内核模块拷贝进入根文件系统        a. 内核编译生成目录            i. 编译模块            make ARCH=arm modules            ii. 安装模块  INSTALL_MOD_PATH 指定安装的目录,我们安装到源码目录下            make INSTALL_MOD_PATH=out modules_install            iii. 得到 out/lib/modules/4.14.111-g08b7e83/        b. 拷贝        一般编译的是时候,文件系统没有挂载到主机上,所以需要多一步        把 p2 挂载到 /mnt,再把上一步生成的目录拷贝到目标根文件系统上。         sudo mkdir -p /mnt/lib/modules/$VERSION/ &&\        sudo cp modules/* /mnt/lib/modules/$VERSION -r &&\        $VERSION 是目标内核的版本号 通过 uname -r 查看        c. 疑问            i. 文件夹的名字需要改么,生成的 modules 带后缀            https://unix.stackexchange.com/questions/231500/difference-between-lib-module-uname-r-and-sys-module            -需要相同            ii. 内核模块安装错误            appledisplay: version magic '4.14.111-g08b7e83 SMP mod_unload ARMv7 p2v8 ' should be '4.14.111-g25f7b00-dirty SMP mod_unload ARMv7 p2v8 '            编译版本和运行版本不是一样的            http://billauer.co.il/blog/2013/10/version-magic-insmod-modprobe-force/                1) include/generated/utsrelease.h  里记录了自动生成的版本号                2) include/linux/vermagic.h 决定了随机的版本号                3) 编译菜单 General setup -> Automatically append version information to version string 去勾选,会去掉 版本后面的随机串,但是最后有个加号                4) 加号来源是版本控制系统,当前版本处于改动中就会自动附上+ http://smilejay.com/2012/07/kernel-version-plus-sign/             iii. 内核如何决定是否使用 这些模块,开机使用还是需要手动            应该是在内核使用到相应的功能时,会自动去查找安装

最近编辑记录 kernelpanic (2019-11-19 15:03:22)



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有