本文讲教你如何使用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-AKERN-B即为AB分区系统的内核,用于启动ROOT-AROOT-B中的系统,那么假设KERN-Apart2的位置,KERN-Bpart4的位置

# 从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会掉,解决方案很简单,把 这个目录 下的文件 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'