最近一直想做一个运行linuxcnc的SBC(Single Board Computer),手上有块 orangepi Zero2 的开发板,就先用它试试.
1.下载官方SDK
想要快速把板子用起来还得看官方的手册,orangepi zero2的手册下载地址http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-Zero-2.html
这里选linux旧版SDK,因为我看过了,这个SDK支持linux5.13内核,有对应的版本的preempt-rt补丁。获取SDK,然后先编译一遍(系统要求是Ubuntu18.04),把缺少的东西都补上(主要是内核源码和交叉编译器,编译时会自动补全)
git clone https://github.com/orangepi-xunlong/orangepi-build.git
cd ./orangepi-build
./build.sh
选择Kernel package -> orangepizero2 -> current Mainline
弹出内核配置界面后不做修改直接推出该界面等待编译完成.
2.打preempt实时补丁
设置 userpatches/config-default.conf 中的 IGNORE_UPDATES 变量为“yes”,否则在运行build.sh进行编译时会自动同步远程代码,导致所有的更改都丢失。
从这个地址下载linux5.13.0的preempt-rt补丁
https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/5.13/patch-5.13-rt1.patch.xz
下载好后放到orangepi-build/kernel目录下
cd kernel/orange-pi-5.13-sunxi64
xzcat ../patch-5.13-rt1.patch.xz | patch -p1
这时补丁已经打好了,如果这时候编译内核或镜像文件,能够正常编译,但在启动时会启动失败,内核启动错误如下(截取了一部分),大致意思就是fpsimd.c文件有问题,异常导致有空指针。
[23:49:11:757] [ 1.576261] WARNING: CPU: 0 PID: 168 at arch/arm64/kernel/fpsimd.c:296 task_fpsimd_load+0x90/0xb8␍␊
[23:49:11:768] [ 1.576290] Modules linked in:␍␊
[23:49:11:771] [ 1.576299] CPU: 0 PID: 168 Comm: modprobe Not tainted 5.13.0-rt1-sun50iw9 #2.2.2␍␊
[23:49:11:776] [ 1.576308] Hardware name: OrangePi Zero2 (DT)␍␊
[23:49:11:782] [ 1.576313] pstate: 40000005 (nZcv daif -PAN -UAO -TCO BTYPE=--)␍␊
[23:49:11:787] [ 1.576321] pc : task_fpsimd_load+0x90/0xb8␍␊
[23:49:11:793] [ 1.576329] lr : task_fpsimd_load+0x18/0xb8␍␊
[23:49:11:796] [ 1.576336] sp : ffff800011dbbdd0␍␊
[23:49:11:798] [ 1.576338] x29: ffff800011dbbdd0 x28: ffff000001b80e80 x27: 0000000000000000␍␊
[23:49:11:807] [ 1.576351] x26: 0000000000000000 x25: 0000000000000000 x24: ffff000001b81540␍␊
[23:49:11:815] [ 1.576362] x23: ffff000001b80e80 x22: ffff000001b81550 x21: ffff000001b80e80␍␊
[23:49:11:821] [ 1.576373] x20: ffff800011dbbeb0 x19: 0000000000000008 x18: 0000000000000014␍␊
[23:49:11:832] [ 1.576384] x17: 000000008ace27e8 x16: 000000008968cf76 x15: 000000002db56098␍␊
[23:49:11:839] [ 1.576395] x14: 0000000000000000 x13: 0000ffffd46cf9e8 x12: 000000000000000f␍␊
[23:49:11:844] [ 1.576406] x11: 0000ffffd46cffe9 x10: 000000000000001f x9 : 0000000000000000␍␊
[23:49:11:848] [ 1.576417] x8 : ffff800011dbc000 x7 : 0000000000000000 x6 : 000000000000003f␍␊
[23:49:11:857] [ 1.576427] x5 : 0000000000000040 x4 : 0000000000000000 x3 : 0000000000000000␍␊
[23:49:11:862] [ 1.576437] x2 : 0000000000000008 x1 : 0000000000000000 x0 : 0000000000000000␍␊
[23:49:11:871] [ 1.576448] Call trace:␍␊
[23:49:11:873] [ 1.576451] task_fpsimd_load+0x90/0xb8␍␊
[23:49:11:876] [ 1.576459] fpsimd_restore_current_state+0x94/0xd0␍␊
[23:49:11:882] [ 1.576469] do_notify_resume+0x114/0x470␍␊
[23:49:11:885] [ 1.576479] work_pending+0xc/0x5f8␍␊
[23:49:11:890] [ 1.576487] ---[ end trace 0000000000000001 ]---␍␊
[23:49:11:893] [ 2.576669] ------------[ cut here ]------------␍␊
[23:49:11:899] [ 2.576677] WARNING: CPU: 0 PID: 168 at arch/arm64/kernel/fpsimd.c:169 __get_cpu_fpsimd_context+0x44/0x58␍␊
[23:49:11:907] [ 2.576700] Modules linked in:␍␊
[23:49:11:912] [ 2.576707] CPU: 0 PID: 168 Comm: modprobe Tainted: G W 5.13.0-rt1-sun50iw9 #2.2.2␍␊
[23:49:11:922] [ 2.576716] Hardware name: OrangePi Zero2 (DT)␍␊
[23:49:11:929] [ 2.576720] pstate: 800000c5 (Nzcv daIF -PAN -UAO -TCO BTYPE=--)␍␊
[23:49:11:934] [ 2.576728] pc : __get_cpu_fpsimd_context+0x44/0x58␍␊
[23:49:11:938] [ 2.576735] lr : __get_cpu_fpsimd_context+0x18/0x58␍␊
[23:49:11:941] [ 2.576742] sp : ffff800011dbbb60␍␊
[23:49:11:944] [ 2.576745] x29: ffff800011dbbb60 x28: ffff000001b80e80 x27: 0000000000000000␍␊
[23:49:11:951] [ 2.576757] x26: ffff8000110311b0 x25: ffff80001135b000 x24: ffff800010d07d88␍␊
[23:49:11:957] [ 2.576769] x23: ffff80001135ccd0 x22: ffff000001b80e80 x21: ffff0000018bab80␍␊
[23:49:11:965] [ 2.576780] x20: ffff000001b80e80 x19: ffff0000018bab80 x18: 0000000000000014␍␊
[23:49:11:971] [ 2.576791] x17: 000000008ace27e8 x16: 000000008968cf76 x15: 0000000000000000␍␊
[23:49:11:979] [ 2.576803] x14: 0000000000000000 x13: 0000000000000129 x12: 0000000000000000␍␊
[23:49:11:987] [ 2.576813] x11: 0000000000000000 x10: 00000000000003d0 x9 : 0000000000000000␍␊
[23:49:11:993] [ 2.576824] x8 : ffff00003fd79400 x7 : ffff00003fd79480 x6 : ffff000001b80f40␍␊
[23:49:12:001] [ 2.576835] x5 : 0000000000000000 x4 : 0000000000003d09 x3 : 0000000000000001␍␊
[23:49:12:007] [ 2.576846] x2 : 0000000000000001 x1 : ffff80002ebea000 x0 : ffff800011187088␍␊
[23:49:12:017] [ 2.576857] Call trace:␍␊
[23:49:12:024] [ 2.576860] __get_cpu_fpsimd_context+0x44/0x58␍␊
[23:49:12:024] [ 2.576868] fpsimd_thread_switch+0x24/0xe0␍␊
[23:49:12:030] [ 2.576876] __switch_to+0x24/0x210␍␊
[23:49:12:030] [ 2.576884] __schedule+0x24c/0x848␍␊
[23:49:12:035] [ 2.576892] preempt_schedule_irq+0x40/0x80␍␊
[23:49:12:039] [ 2.576899] arm64_preempt_schedule_irq+0x14/0x28␍␊
[23:49:12:042] [ 2.576906] el1_irq+0xe8/0x168␍␊
[23:49:12:046] [ 2.576913] task_fpsimd_load+0x94/0xb8␍␊
[23:49:12:049] [ 2.576920] fpsimd_restore_current_state+0x94/0xd0␍␊
[23:49:12:054] [ 2.576928] do_notify_resume+0x114/0x470␍␊
[23:49:12:057] [ 2.576938] work_pending+0xc/0x5f8␍␊
[23:49:12:060] [ 2.576944] ---[ end trace 0000000000000002 ]---␍␊
[23:49:12:065] [ 3.577074] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000␍␊
3.修复打补丁后的内核问题
修改orange-pi-5.13-sunxi64/arch/arm64/kernel/fpsimd.c文件中的get_cpu_fpsimd_context()和put_cpu_fpsimd_context()函数为:
static void get_cpu_fpsimd_context(void)
{
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
local_bh_disable();
else
preempt_disable();
__get_cpu_fpsimd_context();
}
//----------------------------------------------------------------
static void put_cpu_fpsimd_context(void)
{
__put_cpu_fpsimd_context();
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
local_bh_enable();
else
preempt_enable();
}
修改orange-pi-5.13-sunxi64/arch/arm64/include/asm/pgtable.h中的arch_faults_on_old_pte()函数为:
static void put_cpu_fpsimd_context(void)
{
__put_cpu_fpsimd_context();
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
local_bh_enable();
else
preempt_enable();
}
4.编译 内核deb包(如果不需要内核安装包可直接进行第5步)
cd ../../
./build.sh
选择Kernel package -> orangepizero2 -> current Mainline
在进入到内核配置界面后勾选 premmpt-rt选项
最后生成的内核deb包在orangepi-build ->output->debs 里面。
5.编译镜像
./build.sh
选择Full OS image for flashing-> orangepizero2 -> current Mainline->focal Ubuntu Focal 20.04 LTS
最后生成的镜像文件orangepi-build ->output->images 里面。
6.烧录镜像,查看实时内核是否制作成功
将第5步制作的镜像烧入sd卡,插入orangepi zero2开发板,上电启动。
启动后打开终端输入uname -a
如果出现PREEMPT_RT字样说明实时内核制作成功。
7.镜像下载链接
如果以上这些对你来说实在太麻烦了,你只想找一个做好的镜像,请留言,我会上传做好的镜像。