前言:
工作10几年了,第一次买开发板。
还是喜欢以前的linux开发,自己搭建整套环境,不像现在的傻瓜式开发。供应商环境都给你搭建好了。现在供应商恨不得能把代码喂到你嘴里。对我们这些老油条那是相当友好,但是对初入坑的小白那是“鸦片”。
言归正传,所有的开发板环境搭建(SOC+linux),无非就是uboot+linux+rootfs,外加交叉编译。
我买开发板的初衷就是想重温一下linux内核,“演而优则导”的中国IT环境坑害了一批优秀工程师。我已经好久没有实际摸过板子、看过示波器、调过驱动和优化内核了。
我接触过N多平台,包括最早的MIPS,PowerPC,到后面的ARM天下,我就没见过linux开发板逃得过uboot+linux+rootfs,我喜欢linux,它就是那么一成不变,哈哈。linux架构设计的有多牛,包罗万象又始终如一。
老是跑题,来看下鲁班猫4,硬件做的很精致,野火网站的资料很全,有些顺带讲了原理,对初入的小白来说还是很不错了学习资料。我习惯了我的开发方式,没有找到我想要的。对于厂家也很难,要让用户方便,无意间就会隐藏了很多细节,以前学linux的时候,记得看过一篇文章,你所不知道的XXX,写的很好。现在我也想写一些“你所不知道的那些细节”。
又跑题了,我想说的是,我开发内核,不可能老是编译完,用烧写工具烧到EMMC里,然后启动,然后调试,然后改代码,然后重新编译、烧写,哦,天,我要疯。在很多开发板的资料里貌似都是这样,现在我要说的是还有一种更好的方法,uboot里tftp 启动内核(比起烧EMMC、USB启动,效率不是一般的高)。 对,你会说,你也知道。但是,linux开发的魅力就在,你不是老鸟,即使你知道有这个方法,你也用过,可是你换个平台开发板你就不一定搞得定了,哈哈。
费了一番功夫,在鲁班猫4上终于搞定了我自己想弄的开发方式,啰里啰嗦,现在才切入正题,抱歉,我是第一次网上写文章。
总结一下,我要归纳的几个问题:
1. 鲁班猫4接交换机和PC连,网络不同,直连才能通,没去找原因,有知道的告诉我一下(貌似以前遇到过,一时忘了)。
2. 如何设置uboot环境变量,以及我是怎么得到这些环境变量的(鲁班猫4环境变量的设置原理)。
3. 如何制作uImage, 鲁班猫4 kernel编译出来只有Image, 我之前都是有zImage, uImage的啊,跟不上时代了。
4. tftp 环境搭建,以及tftp 命令。
5. 应用程序编译,遇到 “/lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found” 问题。
问题归纳解决记录:
一个问题一个问题总结,以前老是觉得自己记性好,现在不服老不行了,终于到了要写文章的年龄。
1. 忽略1.
2. 如何设置uboot环境变量,以及我是怎么得到这些环境变量的(鲁班猫4环境变量的设置原理)。
这里先插一下,国内访问github的问题。不表FanQ, 这里假设你已经可以了。我要解决的是虚拟机怎么git。虽然野火有重定向到mirrors.tuna.tsinghua.edu.cn方法,但我还是想github, 太轴了。
以前我讨厌虚拟机,主要是不稳定,现在发现还行。我是windows10+ubuntu22.04虚拟机。我windows10开的FanQ,虚拟机用windows代理。git可以设置代理,你可以在 ~/.gitconifg 最后面添加 以下几行 :
[https]
proxy = http://IP:端口
[https]
proxy = https://IP:端口
[socks]
proxy = socks://IP:端口
[socks5]
proxy = socks5://IP:端口
你就可以在终端里git github上代码了。
下载完鲁班猫4的SDK. 在 kernel/extboot里,你可以看到boot.cmd, 这是鲁班猫4 uboot环境变量设置的过程,和启动流程。我是怎么知道的呢?你可以从板子的uboot环境变量里知道答案(printenv看下哈)。
我翻译了下boot.cmd:
============================================================
load mmc 0:2 0x0a100000 /uEnv/uEnv.txt (从emmc里读取 环境变量文件)
env import -t 0x0a100000 0x8000 (导出环境变量到内存0x0a100000)
setenv bootargs $(bootargs} root=/dev/mmcblk2p3 $(cmdline} (基于新环境变量重新组装新的bootagrs)
load mmc 0:2 0xa200000 /initrd-5.10.160 (从emmc里读取ramdisk)
load mmc 0:2 0x00400000 Image-5.10.160 (从emmc里读取内核)
load mmc 0:2 0x8300000 /rk-kernel.dtb (从emmc里读取设备树)
fdt addr 0x8300000 (设置设备树的内存地址)
fdt set /chosen bootargs (更新设备树chosen节点 bootargs)
setenv dev_bootpart 0:2 (告诉内核系统盘?没深究)
dtfile 0x8300000 0x08000000 /uEnv/uEnv.txt 0x0a100000 (设备树的overlay, 可以在系统运行期间动态修改设备树)
booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
================================================================
看到鲁班猫4 自带的uboot是怎么启动的么? 那么我们照葫芦画瓢,tftp 如下:
================================================================
setenv ipaddr 192.168.0.117
setenv serverip 192.168.0.111
tftp 0x5000000 uImage;tftp 0xa200000 initrd-5.10.160;tftp 0x8300000 rk-kernel.dtb;tftp 0x0a100000 uEnv.txt
env import -t 0x0a100000 0x8000
setenv bootargs "storagemedia=emmc androidboot.storagemedia=emmc androidboot.mode=normal root=/dev/mmcblk0p3 earlyprintk console=ttyFIQ0 console=tty1 consoleblank=0 loglevel=7 rootwait rw rootfstype=ext4"
fdt addr 0x8300000
fdt set /chosen bootargs
setenv dev_bootpart 0:2
dtfile 0x8300000 0x08000000 /uEnv/uEnv.txt 0x0a100000
bootm 0x5000000 0xa200000 0x8300000
================================================================
如果你不依照上面来,tftp 你是启动不了内核滴。
3. 如何制作uImage, 鲁班猫4 kernel编译出来只有Image, 我之前都是有zImage, uImage的啊,跟不上时代了。
纯粹缅怀一下以前的启动,这里提一下uImage的制作方法:
aarch64-linux-gnu-objdump -O binary -R .note -R .comment -S arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage
mkimage -A arm64 -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -n 'Linux' -d arch/arm64/boot/zImage arch/arm64/boot/uImage
你不用uImage也行,用booti 启动 Image也可以的,只不过Image比 uImage 大很多。
4. tftp 环境搭建,以及tftp 命令。
这个百度一下吧,到处都有。命令见问题3。
5. 应用程序编译,遇到 “/lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found” 问题。
鲁班猫4的SDK git下来,我直接用build.sh(未加任何参数)编译完默认的是debian文件系统。我用SDK prebuilts目录带的交叉编译器编译出来的应用程序在板子上跑却遇到了 “/lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found”报错,很明显编出来的程序和文件系统里的glibc 不匹配。
在开发板上运行一下: strings /lib/aarch64-linux-gnu/libc.so.6 |grep GLIBC*, 看看支持哪些版本。
很奇怪的一点是SDK里debian用的是libc-2.31.so, 编译器用链接的确是libc-2.33.so。这不是坑人么?
我换了一个编译器版本 gcc-aarch64-linux-gnu-8.3.0,编译出来的就可以在板子上正常运行了。
自此,你可以编译内核,用tftp启动啦。魔改一通内核,调试试试。
总结:
这是我10几年来的第一篇网文,哈哈。写的有点乱。后续会接着写SystemTap。买开发板来就是为了重新玩内核,哈哈。