文章
2024/4/30
Arm的Chromebook手动切换AB分区 cgpt使用教程 Ubuntu双系统共存 改温度墙
2024-04-30
2024-06-24

本文讲教你如何使用cgpt命令,在ChromeOS上切换启动分区,大概在x64上也是差不多的(至少分区是一样的,虽然引导的方式可能不一样,未使用efi,是bios直接启动的Kernel),咩咩使用的是MT8183的Chromebook Duet 1代

插播一条提示,这是Chromebook Duet的113恢复镜像,解压后dd写u盘启动,最后一版ARC++的系统,流程多了
dl.google.com/dl/edgedl/chromeos/recovery/chromeos_15393.58.0_kukui_recovery_stable-channel_mp-v6.bin.zip

首先新的系统需要到tty2,也就是ctrl + alt + f2切换过去的,桌面则是f1,老的系统可以直接按ctrl + alt + t在桌面打开控制台,输入shell回车进入终端

首先说一下cgpt这个命令并不是ChromeOS独有的,你可以在其他Linux上直接拿包管理器装,就像gdisk一样
先sudo -i切换到root,方便操作,假设我的硬盘是/dev/mmcblk0,那么

# 查看分区表状态
cgpt show /dev/mmcblk0
# 看不全可以这样,按空格翻页
cgpt show /dev/mmcblk0 | more

Attr与cgpt add命令转换#

你会发现输出的分区信息中以KERN-开头的分区有一个Attr的参数,这个参数决定了启动的方式
例如这是part是2的KERN-A分区的参数

Attr: priority=2 tries=0 successful=l

priority 对应 -P 是启动优先级,越大越优先
tries 对应 -T 是尝试启动次数
successful 对应 -S 标记是否能成功启动
part 对应 -i
那么如果将上面的配置用命令写出来,就是

cgpt add -i 2 -P 2 -T 0 -S 1 /dev/mmcblk0

是不是一下就懂了?

AB分区切换#

KERN-A和KERN-B即为AB分区系统的内核,用于启动ROOT-A和ROOT-B中的系统,那么假设KERN-A在part2的位置,KERN-B在part4的位置

# 从A分区启动
cgpt add -i 2 -P 2 -T 0 -S 1 /dev/mmcblk0
cgpt add -i 4 -P 1 -T 0 -S 1 /dev/mmcblk0
# 从B分区启动
cgpt add -i 2 -P 1 -T 0 -S 1 /dev/mmcblk0
cgpt add -i 4 -P 2 -T 0 -S 1 /dev/mmcblk0

其实就是调整-P来修改启动优先级
至于怎么确定当前设置的是那个槽位呢,看一下show的时候priority谁更大即可

启动规则#

如果需要临时启动一次
此处我都拿/dev/mmcblk0的分区6来举例

cgpt add -i 6 -P 15 -T 1 -S 0 /dev/mmcblk0

经过多次测试得到以下结论
-S 0的情况下,一般启动后都不会保存(虽然理论上启动成功他应该从0变成1)
-T不为0时,会多次尝试启动,无法启动则跳到下一个
-P设置成15绝对够大,能确保他优先级一定是最高的

ChromeOS#

本次测试的版本是113和123,大部分数据从新系统切换到旧系统后都能完美兼容,但由于113是最后一个使用ARC++的版本,后面Android都变成ARCVM了,导致123下的ARCVM数据被自动删除,因此启动过113再次启动123,Android会变得完全无法启动
但是你如果被自动更新了想要回到旧系统,马上把槽位切换一下,应该还是完美回到旧系统的(因为我花了2小时去执行“升级优化”Android,他已经完全变成ARCVM的形状了)
理论上可以通过这种方式,在Arm的Chromebook上安装Ubuntu和ChromeOS双系统,毕竟ChromeOS的系统只是占了前面12个分区,通过调整第一个STSTE分区的大小(他虽然是第一个分区但是物理位置是在最后面)来腾出空间在后方安装Ubuntu

将Ubuntu与ChromeOS安装到eMMC共存#

可以查看 这个视频 可以达到双系统随意切换启动
ChromeOS占用了前12个分区,Ubuntu需要4个分区,咩咩将分区建到后面,相当于分区13到16为Ubuntu分区,此操作不会对ChromeOS有任何影响
其中ChromeOS是AB分区,对于咩咩这个Duet来说,系统因为arcvm性能差的原因,只能锁死到最后一版ARC++也就是113的系统了,此时113装在A分区,B分区内容虽然跟A的一样但是是完全没有用到的,因此可以缩小ROOT-B来腾出空间安装Ubuntu实现无损安装(用户空间也不会减少)当然,你也可以选择缩小分区1(就是用户数据空间),但是由于数据是加密的,也没法挂载,要缩小就得格式化了


如果你需要禁用ChromeOS系统自动更新 ``` sudo -i mkdir -p /mnt/stateful_partition/etc echo "CHROMEOS_RELEASE_VERSION=99999.9.9" > /mnt/stateful_partition/etc/lsb-release sync reboot ```
需要准备的有:写好Ubuntu可以启动的U盘,写入u盘用的镜像(拿另一个u盘装着也行,或者调整写好的盘第4个分区的大小,然后用复制进去也行),用U盘启动到Ubuntu,并将那个镜像挂载到loop0(直接在文件管理器用镜像挂载器打开就能自动挂好,没有提示),然后打开终端,`sudo -i`换成root开始操作

缩小ROOT-B(分区5,如果是A则是3)并创建Ubuntu需要的分区

cgpt show /dev/loop0
# 记录他展示的4个分区的UUID,待会会用到
gdisk /dev/mmcblk0
p
x
i
5
# 这里记录上面输出的Partition unique GUID
m
d
5
# 下面将创建1M的ROOT-B
n
5
# 直接回车
+1M
7F01
# 下面将创建Ubuntu的第1分区
n
13
# 直接回车
+32M
7F00
# 下面将创建Ubuntu的第2分区
n
14
# 直接回车
+1M
7F00
# 下面将创建Ubuntu的第3分区
n
14
# 直接回车
+100M
# 直接回车
# 下面将创建Ubuntu的第3分区
n
14
# 直接按3次回车
x
c
5
# 输入上面记录的Partition unique GUID
p
# 下面这一步会写入磁盘,如果前面做错了可以直接按Ctrl+C退出
w
y

不需要设置相同的uuid也能正常启动,如果设置相同的uuid会导致无法usb无法启动,如果使用dd镜像直接安装Ubuntu单系统,建议去x c R将每个分区的uuid都生成一个新的以保证usb启动的真的是usb的系统
进行完上面的操作,分区就准备好了,下面开始安装系统

dd if=/dev/loop0p1 of=/dev/mmcblk0p13
resize2fs /dev/loop0p3 90M
dd if=/dev/loop0p3 of=/dev/mmcblk0p15
resize2fs /dev/mmcblk0p15
dd if=/dev/loop0p4 of=/dev/mmcblk0p16 bs=100M

这样系统就安装好了,接下来将教你如何启动系统

# 切换启动到Ubuntu
cgpt add -i 13 -P 15 -S 1 /dev/mmcblk0
# 切换启动到ChromeOS
cgpt add -i 13 -P 0 /dev/mmcblk0
# 启动一次ChromeOS
cgpt add -i 13 -P 15 -T 1 -S 0 /dev/mmcblk0

以下方式可以让你在ChromeOS下创建一个启动脚本,快速启动到Ubuntu 按最上面说的,进入终端,并且`sudo -i`换成root ``` mkdir -p /usr/local/bin echo 'sudo cgpt add -i 13 -P 15 -T 1 -S 0 /dev/mmcblk0 && sync && sudo reboot' > /usr/local/bin/ubuntu chmod 777 /usr/local/bin/ubuntu ``` 这样你下次在终端运行`ubuntu`就会自动重启到Ubuntu,并且再重启就能回到ChromeOS

Ubuntu优化#

在Ubuntu下重力感应的方向不对,需要修改一下配置

sudo vim /etc/udev/hwdb.d/61-sensor-local.hwdb

按i进编辑模式输入以下内容(实测24系统失效)

sensor:modalias:platform:cros-ec-accel:*
ACCEL_MOUNT_MATRIX=0,1,0;-1,0,0;0,0,1

注意第二行开头有个空格
按esc,:wq回车保存退出

systemd-hwdb update
reboot

扩展btrfs文件系统到分区实际大小 ``` btrfs filesystem resize max / ```
另外可以把Ubuntu的软件源换成国内镜像,Ubuntu Arm的镜像源独此清华一家,其他都不知道为什么没arm ``` sudo sed -i 's@//.*archive.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn/ubuntu-ports@g' /etc/apt/sources.list sudo sed -i 's@//ports.ubuntu.com/ubuntu-ports@//mirrors.tuna.tsinghua.edu.cn/ubuntu-ports@g' /etc/apt/sources.list sudo apt update ```
可以进行系统更新,亲测更新到Ubuntu 24.04 LTS,但是WiFi会掉,解决方案很简单,把 [这个目录](https://github.com/hexdump0815/imagebuilder/tree/main/systems/chromebook_kukui/extra-files/lib/firmware) 下的文件 `cp -r` 合并到 `/lib/firmware` 即可
删除日志,日志其实很占空间的,将保留最后10M日志 ``` journalctl --vacuum-size=10M ```
另外有一些在Ubuntu的非必要操作 ``` sudo -i # 这系统里带了两套桌面环境 把没用的都删了,删完已用2.2G apt autoremove xubuntu* xfce* mate* # 删掉没用的软件 apt autoremove gimp transmission # 装回一个gnome3的文件浏览器 apt install nautilus # 切换语言为中文 sed -i 's/^# zh_CN.GBK GBK/zh_CN.GBK GBK/' /etc/locale.gen sed -i 's/^# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen locale-gen update-locale LANG=zh_CN.UTF-8 # 换成gdm3管理登录 才能用触摸屏登录 apt install gdm3 apt autoremove lightdm ``` ### 其他 btrfs硬盘压缩 (提升不大) 编辑`/etc/fstab`, 可以将此处的`compress-force=zstd`改为`compress-force=zstd:6`默认不写比例是3,可以提高压缩比 这条命令可以进行全盘压缩 ``` # 生效刚刚配置的zstd:6 mount -o remount / btrfs filesystem defragment -r -v -czstd / ``` 可见硬盘从已用3.1g降到了3.0g,提升显著?看来之前已经压过了
和ChromeOS一样的道理,我们也可以弄两个脚本在Ubuntu中快速切换系统 ``` echo 'sudo cgpt add -i 13 -P 15 -T 1 -S 0 /dev/mmcblk0 && sync && sudo reboot' > /usr/local/bin/ubuntu echo 'sudo cgpt add -i 13 -P 0 /dev/mmcblk0 && sync && sudo reboot' > /usr/local/bin/chromeos chmod 777 /usr/local/bin/ubuntu chmod 777 /usr/local/bin/chromeos ```
由于ChromeOS开启了ext4的FEATURE_C12特性,但是目前这版的Ubuntu不支持,可以这样关掉这个特性,达到共用state分区的操作(比如mount --bind 过去/) ``` tune2fs -O ^FEATURE_C12 /dev/mmcblk0p1 ```
在ChromeOS中Android(ARC++)设置深色主题/黑暗模式/夜间模式 ``` # 黑 adb shell settings put secure ui_night_mode 2 # 白 adb shell settings put secure ui_night_mode 1 # 自动 adb shell settings put secure ui_night_mode 0 # 设置完要重启Android才能生效 adb shell reboot ```
系统备份,备份整个emmc ``` dd if=/dev/mmcblk0 bs=100M | zstd -9 -T0 --long=27 -c > ddBackup.img.zst ``` 还原 ``` zstd -d -c ddBackup.img.zst | dd of=/dev/mmcblk0 bs=100M ```
修改ChromeOS的温度墙,让CPU高温不降频 因为是被动散热,所以默认68度的温度墙虽然摸起来一点不烫,但很影响使用,特别是充电时,本方法在113测试通过,125应该是不行了,或者说就根本没温度墙了,需要root(可能还需要将根分区设置成读写模式) ``` # 查看实际cpu温度(诊断的实际是主板温度) cat /sys/class/thermal/thermal_zone0/temp # 查看当前大核心最高主频,最高1989000 cat /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq # 小核心,最高1989000 cat /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq # 将温度墙改成95度,这个温度刚好能在满载时达到散热平衡 echo 95000 > /sys/class/thermal/thermal_zone0/trip_point_0_temp ``` 因为没办法开机启动,所以每次开机都要手动运行,用一句话执行就是这样 ``` sudo sh -c 'echo 95000 > /sys/class/thermal/thermal_zone0/trip_point_0_temp' ```