mainline的u-boot和linuxkernel
可能好多玩Linux的朋友都听过mainline或则upstream这两个词,并且又搞不清她们究竟指的是哪些。
通常你们领到一块开发板,前面搭载的都是芯片原厂开发的u-boot和linuxkernel,我们称之为vendor的u-boot和kernel,这种内核通常是基于linux官方的某个分支更改的,例如i.MX6目前用的内核好多是Linux4.1,rk3288/rk3399目前用的内核大部份是Linux4.4,芯片原厂为了系统的稳定和便于维护,通常会在这个特定的版本上做常年开发,轻易不会升级内核版本,而Linux官方内核却会以固定的节奏往前不停的演化,例如目前最新的稳定版本为Linux5.4.2,我们称这些内核为mainline内核或则upstream内核,u-boot也是同样的概念。
过去两个月借助空闲时间在RK3399LeezP710开发板上移植了最新的U-Boot和Linuxkernel,之后把对应的补丁递交到了mainline上,LinuxKernel的补丁被合并到Linux5.4中,对U-Boot的支持补丁也在V2020.01中被合并了。
随着近来U-Bootv2020.1和Linux5.4的相继发布,这块开发板早已可以直接用mainline的U-Boot和Linuxkernel来启动了。
这儿顺便说下当前Linux和U-Boot开源社区的开发节奏。
Linux通常是两个月发布一个大版本,像Linux5.2、Linux5.3、Linux5.4这样的,在这两个月的开发周期中,通常会根据一周五个的节奏发布7~8个候选版本(rc1~rc8),rc1上面会包含各类新功能新特点,rc2~rc8通常只接受对当前版本中存在的bug更改,不容许降低新功能,直至整个系统渐趋稳定,没有显著的bug,之后发布即将版本,例如Linux5.4就是经过了8个候选版本才发布的。即将版本发布后同时也会打开下一个大版本的合并窗口,这个合并窗口大约是两个礼拜的时间,开源社区的各路大鳄(Linus信任的maintainer)会在这两个礼拜中把自己收到的补丁以PullRequest的方式发送给Linus,由Linus来决定是否最终合并。
U-Boot开源社区目前是3个月发布一个大版本,并且版本号根据即将发布的时侯对应的时间命名,例如v2019.07,v2019.10,v2020.01,通常是两到三个礼拜发布一个候选版本linux kernel社区,并且也是只在rc1版本中接受新增功能和特点,其他的候选版本只容许更改bug。
所以假如你要向Linux和U-Boot社区递交代码,一定要赶在rc1版本发布之前把补丁发给对应的maintainer,错过这个窗口期就要等几个月到下一个版本就会被接受了。
Armbian
Armbian是美国开发者维护的一个针对各类Arm开发板的开源项目,支持了大量基于Rockchip、Allwinner、Amlogic主控的开发板,还有少量几款基于i.MX的开发板。从这个项目上面可以编译出在Arm上运行的Debian和Ubuntu系统。
我以mainline的u-boot和Linuxkernel为基础,借助Armbian做了一个Debian10的镜像,分享在百度云盘上:链接:提取码:af5i。
这个镜像可以用Etcher软件烧讲到TF卡中,之后把卡插到开发板上,让系统从开发板启动。
假如你的板子上有eMMC,最好先把eMMC上的固件擦除,起码把eMMC从第64个磁道开始的一小段擦除,由于RK3399默认是优先从eMMC启动的,擦除方式好多,例如步入u-boot命令行,通过mmcerase命令擦除:
把TF卡插到板子后上电,系统会从TF卡上启动linux删除文件夹,接上并口或则HDMI能够看见系统启动后的登陆信息linux删除命令,默认登陆帐号和密码分别为root和1234,输入密码后系统会要求重新更改密码,根据要求操作即可。
步入命令行后,可以通过nmtui-connect命令扫描WiFi,联网。
在HDMI屏幕上可以通过lightdm命令启动桌面。不过这个桌面是不带GPU加速的,我旁边会专门写一篇文章来讲如何启动GPU加速。
还可以通过nand-sata-install命令把整个系统从TF卡上迁移到eMMC上,不过整个操作你最好通过ssh登陆后操作,我发觉在并口下边界面显示的有问题。
安装完毕后会提示Alldone.Poweroff,选择Poweroff后,拔除卡,再上电,系统还会从eMMC启动了。
更新U-Boot
我们可以自己编译mainline的U-Boot之后更新到板子上。
由于RK3399是Arm64,所以我们还须要编译ATF(Armtrustfirmware),ATF主要负责在启动U-Boot之前把CPU从安全的EL3切换到EL2,之后跳转到U-Boot,但是在内核启动后负责启动其他的CPU。
git clone https://github.com/ARM-software/arm-trusted-firmware.git
复制
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399
复制
最终编译下来的目标文件为:build/rk3399/release/bl31/bl31.elf,这个文件须要和编译下来的u-boot一起打包成fit格式的镜像能够被SPL加载。
git clone https://gitlab.denx.de/u-boot/u-boot.git
复制
export BL31=../../arm-trusted-firmware/build/rk3399/release/bl31/bl31.elf
make leez-rk3399_defconfig
make CROSS_COMPILE=aarch64-linux-gnu-
复制
第一步设置BL31环境变量,即指定上面编译的bl31.elf的位置,u-boot编译到最后会把它打包到fit镜像中。
第二步执行Leez-RK3399这块开发板对应的配置文件。
第三步开始编译。
最终编译成功后会生成两个供烧录的文件:
idbloader.img:是TPL和SPL的合成文件,后者负责DDR初始化,前者负责加载ATF和u-boot。u-boot.itb:是由u-boot和上面的ATF合成的FIT格式的镜像文件。
可以通过scp命令把编译的idbloader.img和u-boot.itb拷贝到开发板上,之后通过dd命令把这两个文件写入eMMC中。其中idbloader.img讲到64磁道处,u-boot.itb讲到16384磁道处:
写完后执行reboot命令重启,可以从时间戳上判定u-boot早已更新成功了。
更新LinuxKernel
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
复制
假如下载速率比较慢,可以参考这篇文章:一个GitClone加速小方法来提速。
git checkout -b linux-5.4.y origin/linux-5.4.y
复制
make ARCH=arm64 defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8
复制
编译成功后会生成Image和dtb文件:
编译生成的Image和dtb文件还是通过scp命令拷贝到开发板上。
Armbian采用和PCUbuntu发行版同样的机制,把KernelImage置于/boot目录下,
所以我们只要用编译好的Image和dtb来分别替换vmlinuz-5.4.1-rockchip64和rk3399-leez-p710.dtb即可。
为了安全起见,最好先把系统中原生的vmlinuz-5.4.1-rockchip64和rk3399-leez-p710.dtb拷贝下来备份上去,万一更新的固件破坏了某个功能,还可以用备份的来恢复。
更新完重启,可以见到最新的内核早已生效。
若果在编译LinuxKernel或则U-Boot的过程中遇见问题linux kernel社区,可以参考这篇文章:LinuxKernel和U-Boot编译的这些事。