跟 UMU 一起玩 OpenWRT(高级篇3):在线升级内核

需求

想升级 OpenWRT 路由器的内核,又不想每次都把 SD 卡拿下来刷,怎么办?

前提

  • 本文将以 Nano Pi R4S 为例。

  • 这里的“在线”指的是:不重新刷 ROM,也不用 sysupgrade,纯手动替换文件,然后 reboot 生效。

解决

1. 先查看当前版本

1
2
uname -a
Linux UMUR4S 5.10.107 #0 SMP PREEMPT Sat Mar 19 19:05:00 2022 aarch64 GNU/Linux

目前是 5.10.107,想升级到 5.10.108!

2. 下载新 ROM 到路由器

可以直接在 OpenWRT 里用 wget 下载到 /tmp 下,或者在其它机器下载好,用 scp 上传到路由器的 /tmp 下。

下载地址:https://github.com/UMU618/openwrt-config/releases

3. 解压新 ROM、挂载分区

1
2
3
4
5
6
7
8
9
cd /tmp/

# wget

gunzip -d openwrt-rockchip-armv8-friendlyarm_nanopi-r4s-ext4-sysupgrade.img.gz

parted openwrt-rockchip-armv8-friendlyarm_nanopi-r4s-ext4-sysupgrade.img
unit B
p

可以看到 img 里的两个分区:

1
2
3
4
5
6
7
8
9
Model:  (file)
Disk /tmp/openwrt-rockchip-armv8-friendlyarm_nanopi-r4s-ext4-sysupgrade.img: 176160768B
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number Start End Size Type File system Flags
1 33554432B 50331647B 16777216B primary ext2 boot
2 67108864B 176160767B 109051904B primary ext2

把这两个分区别分挂载:

1
2
3
4
5
mkdir new_boot
mount -o loop,offset=33554432 openwrt-rockchip-armv8-friendlyarm_nanopi-r4s-ext4-sysupgrade.img new_boot

mkdir new_root
mount -o loop,offset=67108864 openwrt-rockchip-armv8-friendlyarm_nanopi-r4s-ext4-sysupgrade.img new_root

4. 挂载待更新的 boot 分区

1
2
mkdir boot
mount /dev/mmcblk1p1 boot

检查一下,时间是不一样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@UMUR4S:/tmp# ll boot/
drwxr-xr-x 3 root root 4096 Jan 1 1970 ./
drwxrwxrwt 23 root root 660 Mar 27 18:17 ../
-rw-r--r-- 1 root root 352 Mar 21 01:17 boot.scr
-rw-r--r-- 1 root root 14860296 Mar 21 01:17 kernel.img
drwx------ 2 root root 4096 Jan 1 1970 lost+found/
-rw-r--r-- 1 root root 55738 Mar 20 19:26 rockchip.dtb
root@UMUR4S:/tmp# ll new_boot/
drwxr-xr-x 3 root root 4096 Jan 1 1970 ./
drwxrwxrwt 23 root root 660 Mar 27 18:17 ../
-rw-r--r-- 1 root root 352 Mar 27 17:56 boot.scr
-rw-r--r-- 1 root root 14860296 Mar 27 17:56 kernel.img
drwx------ 2 root root 4096 Jan 1 1970 lost+found/
-rw-r--r-- 1 root root 55738 Mar 27 17:45 rockchip.dtb

开始复制文件:

1
2
cp new_boot/* boot/
cp -r new_root/lib/modules/5.10.108 /lib/modules/

检查一下,现在应该同时存在两个版本的 modules:

1
2
3
4
5
root@UMUR4S:/tmp# ll /lib/modules/
drwxr-xr-x 4 root root 4096 Mar 27 18:28 ./
drwxr-xr-x 10 root root 4096 Mar 21 05:24 ../
drwxr-xr-x 2 root root 4096 Mar 20 03:05 5.10.107/
drwxr-xr-x 2 root root 4096 Mar 27 18:28 5.10.108/

5. 重启验证

reboot 后查看版本,如果没问题就清理旧版本:

1
2
3
4
uname
Linux UMUR4S 5.10.108 #0 SMP PREEMPT Sun Mar 27 04:00:50 2022 aarch64 GNU/Linux

rm -rf /lib/modules/5.10.107

诗盗·疏漏聋锈

《#诗盗#·疏漏聋锈》:学堂初出欲躺平,技术更迭,规模不减反增。KPI,OKR,内卷岁月财源正盛,共印萧条疑似有染。

注解

改编自霹雳角色“疏楼龙宿”的诗号。

华阳初上鸿门红,疏楼更迭,龙麟不减风采;
紫金箫,白玉琴,宫灯夜明昙华正盛,共饮逍遥一世悠然。

诗盗·天行日月

《#诗盗#·天行日月》:白首方知友难交,一意逍遥,钱袋飘飘;十岁春风稣不晓,一心求道,人间邈邈。

注解

改编自霹雳角色“天迹”的诗号。

仙衣眠云碧岚袍,一襟潇洒,两袖飘飘;
玉墨舒心春酝瓢,行也逍遥,坐也逍遥。

  • 天行日月:时间飞逝

诗盗·不算计·咏社

《#诗盗#·不算计·咏社》:风雨财源归,挨踢寒冬到。已是高僧绝尘心,犹有一诗骚。骚也不挣钱,只报暖春遥。待到资本卷死时,社在丛中笑。

注解

改编自近代伟人毛泽东的《卜算子·咏梅》。

风雨送春归,飞雪迎春到。已是悬崖百丈冰,犹有花枝俏。
俏也不争春,只把春来报。待到山花烂漫时,她在丛中笑。

  • 高僧绝尘心:当稣有“是非成败转头空,青山依旧在,几度夕阳红。”的领悟和境界时,总有人提醒“你是穷逼”啊。稣内心一骚,总不能暴露稣存款千万的秘密吧!

  • 社在丛中笑:财源是资本主义的报复行为……社会主义接班稣早就看穿这险恶的招数,社会主义必将笑到最后。

诗盗·财源与君

《#诗盗#·财源与君》:财源与君君自宽,挨踢翻覆似波澜。白首相知犹内卷,朱门先达笑弹冠。校招全经高薪稀,倒挂欲动冬风寒。绩效浮云何足问?不如卧槽且加班。

注解

改编自唐代诗人王维的《酌酒与裴迪》:

酌酒与君君自宽,人情翻覆似波澜。
白首相知犹按剑,朱门先达笑弹冠。
草色全经细雨湿,花枝欲动春风寒。
世事浮云何足问,不如高卧且加餐。

  • 朱门:这里特指资本家。

  • 高薪稀:每年校招工资上限都提高,而且大肆宣传,但其实都是一个广撒网的套路,一段时间后,公司发现新人能力不够时,很容易被裁掉。高回报高风险。

  • 卧槽:卧在一个槽里,与“跳槽”相对。

现代 C++【3】返回类对象

前提

多现代?C++ 11 就有了。

问题

我想返回一个对象,但我受到惊吓……

是不是应该从指针型参数返回对象?

结论

已经 C++20 了,请放心,直接,返回对象!

概念

  • RVO:Return Value Optimization,返回值优化。

广义的 RVO 分为两种,它们之间的主要区别在于返回值是具名的局部变量还是无名的临时对象。

  1. NRVO:Named RVO,具名的返回值优化。这是可选的优化,通常没有多个返回路径返回不同的对象,或者返回的对象不依赖于条件判断时,会被实施。

  2. URVO:Unnamed RVO,匿名的返回值优化。通常 RVO 特指 URVO。C++ 17 开始 URVO 必然被实施。

返回的对象会 move 给接收的变量,并且,最多可能优化成直接对接收变量进行构造(NRVO)。

如果明确没有 move 构造函数,则会调用 copy 构造函数,当对象构造代价高时,应该尽量保证有 move 构造函数。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 传统,不建议,可读性差,使用也不方便
void GetName(std::string& name) noexcept {
name = "UMU";
}

// URVO,C++ 17 开始必然优化
std::string GetName() noexcept {
return "UMU618";
}

// NRVO, 可选优化,具体来说,以下的写法会优化
std::string GetName() noexcept {
std::string name("UMU618");
return name;
}

避坑

没有必要对返回值再加一次 std::move,因为返回本身就已经是 move,再加一次就是多一次没必要的 move。