Linux ARM 微架构环境伪装切换工具

概述

arm_switch 用于在同一台 ARM 设备上切换不同的微架构模拟环境。切换后执行 reboot,
系统启动时自动应用目标环境,无需任何额外操作。SSH 登录即处于目标环境中。

本机硬件为 RK3528(Cortex-A53),目前支持模拟鲲鹏920。


工作原理

切换命令在 reboot 前写入两处持久配置:

  • /etc/arm_switch/current — 写入目标模式名
  • /etc/hostname — 通过 hostnamectl set-hostname 写入目标 hostname(在正常运行的系统中执行,稳定可靠)

系统启动时,systemd 服务 arm-switch.service 在所有用户服务启动前以
arm_switch --apply 方式调用同一脚本,读取 /etc/arm_switch/current
对非 native 模式执行三个全局 bind-mount:

1
2
3
/<mode>                              →  /root           家目录隔离
/etc/arm_switch/<mode>/fake_cpuinfo → /proc/cpuinfo CPU信息伪造
/etc/arm_switch/<mode>/fake_midr_el1 → /sys/devices/system/cpu/cpu0/regs/identification/midr_el1

bind-mount 运行在根 mount namespace,对所有进程全局可见,无需 namespace 隔离技巧。

reboot 后恢复 native 只需将 current 改写为 native,服务读到后不执行任何 mount。


文件布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/etc/arm_switch/
current 当前模式(native / kp920)
native_hostname 本机原始 hostname 备份
README.md 本文档
kp920/
fake_cpuinfo 鲲鹏920的 /proc/cpuinfo 内容
fake_midr_el1 鲲鹏920的 MIDR_EL1 寄存器值
hostname 该模式的目标 hostname(kunpeng920-dev)

/kp920/ kp920 模式的家目录(挂载到 /root)
.ssh/ SSH 密钥
.bash_profile bash login shell 配置(从 native /root 复制)
.bashrc bash 交互式配置(从 native /root 复制)
.conan2/ kp920 专属 Conan 配置
source_kp920/ 构建工作区

/usr/local/bin/arm_switch 用户命令(同时含 --apply 逻辑,供 systemd 调用)
/etc/systemd/system/arm-switch.service

注意:文档中曾提到的 /usr/local/bin/arm-switch-apply 不存在,
--apply 功能直接内嵌在 arm_switch 脚本中。


使用方法

切换到鲲鹏920环境

1
arm_switch kp920

执行后显示确认提示,输入 y 重启。重启后:

  • hostname 变为 kunpeng920-dev
  • cat /proc/cpuinfo 显示鲲鹏920 CPU 信息
  • cat /sys/devices/system/cpu/cpu0/regs/identification/midr_el1 显示 0x00000000481fd010
  • 家目录为 /kp920,与 native /root 完全隔离

恢复 native 环境

1
2
3
arm_switch
# 或
arm_switch native

查看帮助

1
arm_switch --help

各模式详情

native

  • hostname:rk3528-openeuler22
  • 家目录:/root(真实目录,无任何 mount 覆盖)
  • /proc/cpuinfo:真实硬件(Cortex-A53)
  • 重启默认即为此模式

kp920(鲲鹏920)

  • hostname:kunpeng920-dev
  • 家目录:/kp920
  • CPU implementer:0x48(华为)
  • CPU part:0xd01(TaiShan v110)
  • MIDR_EL1:0x00000000481fd010
  • 特性:sha3 sm3 sm4 asimddp lse 等鲲鹏920特有指令集

实际文件内容

/usr/local/bin/arm_switch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/bin/bash
CONF=/etc/arm_switch

# ── 动态发现已注册模式(扫描 $CONF 子目录) ─────────────────────────
valid_modes() {
local modes="native"
for d in "$CONF"/*/; do
[ -d "$d" ] && modes="$modes $(basename "$d")"
done
echo "$modes"
}

mode_hostname() {
local mode=$1
if [ "$mode" = "native" ]; then
cat "$CONF/native_hostname" 2>/dev/null
else
cat "$CONF/$mode/hostname" 2>/dev/null || echo "$mode-dev"
fi
}

# ── systemd 启动时调用,应用 bind-mount ──────────────────────────────
if [ "$1" = "--apply" ]; then
MODE=$(cat "$CONF/current" 2>/dev/null || echo native)
[ "$MODE" = "native" ] && exit 0
MIDR=/sys/devices/system/cpu/cpu0/regs/identification/midr_el1
set -e
mount --bind "/$MODE" /root
mount --bind "$CONF/$MODE/fake_cpuinfo" /proc/cpuinfo
if [ -f "$MIDR" ]; then
mount --bind "$CONF/$MODE/fake_midr_el1" "$MIDR"
fi
exit 0
fi

# ── 用户命令 ─────────────────────────────────────────────────────────
usage() {
echo "用法: arm_switch [模式]"
echo " arm_switch 无参数,恢复 native 并重启"
echo ""
echo "模式:"
for m in $(valid_modes); do
printf " %-10s %s\n" "$m" "$(mode_hostname "$m")"
done
echo ""
echo "当前模式: $(cat $CONF/current 2>/dev/null || echo native)"
echo ""
cat <<'EOF'
新增微架构步骤:
1. 从目标机采集 CPU 信息,放入 $CONF/<name>/:
fake_cpuinfo <- cat /proc/cpuinfo
fake_midr_el1 <- cat /sys/devices/system/cpu/cpu0/regs/identification/midr_el1
hostname <- echo "目标-hostname" > hostname
2. 创建 /<name>/ 作为该模式的家目录,复制必要文件:
mkdir -p /<name>
cp -a /root/.ssh /<name>/.ssh
cp /root/.bash_profile /<name>/.bash_profile
cp /root/.bashrc /<name>/.bashrc
3. arm_switch <name> (脚本无需修改)
EOF
}

TARGET=${1:-native}

if [ "$TARGET" = "--help" ] || [ "$TARGET" = "-h" ]; then
usage; exit 0
fi

MODES=$(valid_modes)
if [[ ! " $MODES " =~ " $TARGET " ]]; then
echo "错误: 不支持的模式 '$TARGET'"
echo "支持: $MODES"
exit 1
fi

CURRENT=$(cat "$CONF/current" 2>/dev/null || echo native)

if [ "$TARGET" = "$CURRENT" ]; then
echo "[arm_switch] 当前已是 $TARGET 模式,无需切换"
exit 0
fi

if [ "$TARGET" != "native" ]; then
[ ! -d "/$TARGET" ] && { echo "错误: /$TARGET 家目录不存在"; exit 1; }
[ ! -f "$CONF/$TARGET/fake_cpuinfo" ] && { echo "错误: $CONF/$TARGET/fake_cpuinfo 不存在"; exit 1; }
[ ! -f "$CONF/$TARGET/fake_midr_el1" ] && { echo "错误: $CONF/$TARGET/fake_midr_el1 不存在"; exit 1; }
[ ! -f "$CONF/$TARGET/hostname" ] && { echo "错误: $CONF/$TARGET/hostname 不存在"; exit 1; }
fi

TARGET_HOST=$(mode_hostname "$TARGET")
echo ""
echo "[arm_switch] 即将从 $CURRENT 切换到 $TARGET ($TARGET_HOST)"
echo "[arm_switch] 重启后生效,当前 SSH 会话将断开"
read -r -p "[arm_switch] 确认重启? [y/N] " ans
[[ "$ans" =~ ^[Yy]$ ]] || { echo "已取消"; exit 0; }

hostnamectl set-hostname "$TARGET_HOST"
echo "$TARGET" > "$CONF/current"

reboot

/etc/systemd/system/arm-switch.service

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=ARM CPU Environment Switch
DefaultDependencies=no
After=local-fs.target
Before=basic.target

[Service]

Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/arm_switch --apply

[Install]

WantedBy=basic.target

新增微架构

以飞腾 D3000 为例:

第一步 — 在目标真机上采集 CPU 信息

1
2
cat /proc/cpuinfo > fake_cpuinfo
cat /sys/devices/system/cpu/cpu0/regs/identification/midr_el1 > fake_midr_el1

第二步 — 将文件放入配置目录

1
2
3
mkdir -p /etc/arm_switch/ftD3000
cp fake_cpuinfo /etc/arm_switch/ftD3000/
cp fake_midr_el1 /etc/arm_switch/ftD3000/

第三步 — 创建家目录,复制 SSH 密钥和 bash 配置

1
2
3
4
mkdir -p /ftD3000
cp -a /root/.ssh /ftD3000/.ssh
cp /root/.bash_profile /ftD3000/.bash_profile
cp /root/.bashrc /ftD3000/.bashrc

第四步 — 切换验证(脚本无需修改,自动发现新模式)

1
arm_switch ftD3000

注意事项

  • 切换操作会立即 reboot,请确保当前工作已保存
  • 各模式家目录完全独立,native 的 /root 内容在 kp920 模式下不可见
  • SSH authorized_keys 在各模式家目录下单独维护,新增模式后需确保 .ssh/authorized_keys 正确
  • 各模式家目录需包含 .bash_profile.bashrc,否则 shell 提示符异常
  • reboot 后默认不会自动切换,需手动执行 arm_switch <mode> 再 reboot
  • 本工具仅伪造 CPU 识别信息,实际 CPU 仍为 Cortex-A53,带 LSE 等指令的二进制在本机无法运行