如何在手机上搭建Linux学习环境
下面是针对 ARM 架构学习 Linux 内存子系统,可以进行本机编译和调试的环境搭建步骤。
核心思路就用TERMUX提供的Linux平台搭建编译仿真环境。
- 在 Termux 中安装 ARM 工具链:使用本机工具链编译 ARM 内核。
- 下载并编译 ARM 版本的 Linux 内核:选择 ARM64 架构。
- 制作 ARM 架构的根文件系统:使用 busybox for ARM。
- 使用 QEMU 模拟 ARM 虚拟机:使用 qemu-system-aarch64。
- 使用 GDB 调试 ARM 内核。
第一步:安装 Termux 和必要软件
更新和升级包
pkg update && pkg upgrade
安装核心开发工具
pkg install -y git make tar coreutils
安装本机编译工具链(clang/gcc for aarch64)
pkg install -y clang lld gdb
安装内核编译依赖
pkg install -y bison flex perl python ncurses-utils
安装 QEMU(支持 ARM64)
pkg install -y qemu-common qemu-system-aarch64
安装其他工具
pkg install -y wget
第二步:获取 Linux 内核源码
我们选择一个较新的长期支持版本,比如 Linux 6.1。
cd ~
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.79.tar.xz
tar -xvf linux-6.1.79.tar.xz
cd linux-6.1.79
第三步:配置和编译 ARM64 内核
由于是在 ARM 设备上编译 ARM64 内核,我们可以使用本机工具链。
清理旧配置
make ARCH=arm64 distclean
使用 defconfig
make ARCH=arm64 defconfig
现在配置内核以启用调试信息:
如果 menuconfig 可用
make ARCH=arm64 menuconfig
如果 menuconfig 不可用,直接编辑 .config 文件:
nano .config
确保以下配置项被正确设置:
启用调试信息
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_DEBUG_KERNEL=y
禁用 KASLR(对调试至关重要)
CONFIG_RANDOMIZE_BASE=n
启用 GDB 脚本
CONFIG_GDB_SCRIPTS=y
串口控制台支持
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
必要的文件系统支持
CONFIG_BLK_DEV_INITRD=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
支持 ARM virt 平台(QEMU)
CONFIG_ARCH_VIRT=y
开始编译内核:
使用本机编译器,不需要 CROSS_COMPILE
make ARCH=arm64 -j2
注意:编译时间会比 x86 版本短一些,因为是在本机架构上编译。
编译成功后,内核镜像位于:arch/arm64/boot/Image
第四步:制作 ARM64 根文件系统
- 创建工作目录和 init 脚本:
cd ~
mkdir arm64_initramfs
cd arm64_initramfs
创建 init 脚本
cat > init << 'EOF'
#!/bin/busybox sh
挂载虚拟文件系统
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
创建设备节点
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
显示信息
echo "=== ARM64 Linux Memory Subsystem Learning Environment ="
echo "Kernel Version: $(uname -r)"
echo "System is ready for memory subsystem exploration!"
echo "Use 'cat /proc/meminfo' to view memory information"
echo "Use 'cat /proc/buddyinfo' for buddy system info"
echo "Use 'cat /proc/pagetypeinfo' for page type info"
echo "Use 'cat /proc/vmallocinfo' for vmalloc info"
echo "========================================================"
启动 shell
exec /bin/sh
EOF
chmod +x init
创建必要的目录
mkdir -p proc sys dev etc
- 下载 ARM64 版本的 busybox:
下载静态链接的 busybox for ARM64
wget https://www.busybox.net/downloads/binaries/1.35.0-aarch64-linux-musl/busybox
chmod +x busybox
- 打包 initramfs:
find . -print0 | cpio --null -ov --format=newc | gzip > .../arm64_initramfs.cpio.gz
第五步:启动 QEMU ARM64 虚拟机
ARM 架构需要指定机器类型和设备树。我们将使用 QEMU 的 virt 机器。
cd ~
启动 QEMU
qemu-system-aarch64
-machine virt
-cpu cortex-a53
-smp 1
-m 512M
-kernel ./linux-6.1.79/arch/arm64/boot/Image
-initrd ./arm64_initramfs.cpio.gz
-append "console=ttyAMA0 earlycon=pl011,0x9000000 nokaslr"
-nographic
-s -S
参数解释:
• -machine virt:使用 QEMU 的 ARM virt 平台
• -cpu cortex-a53:指定 CPU 类型(常见的 ARM Cortex-A53)
• -smp 1:单核 CPU
• -m 512M:512MB 内存
• -append "console=ttyAMA0...":ARM 平台的串口配置
第六步:使用 GDB 调试 ARM64 内核
在另一个 Termux 会话中:
cd ~/linux-6.1.79
gdb
在 GDB 中执行:
加载带调试信息的内核
file vmlinux
连接到 QEMU
target remote :1234
设置 ARM64 特定的断点(内存管理相关)
break __meminit arm64_memblock_init
break paging_init
break mm_init
继续执行
continue
针对内存子系统的学习
现在环境已经搭建好,你可以探索以下内存管理相关的内容:
- 查看内存信息
在 QEMU 的 shell 中执行
cat /proc/meminfo
cat /proc/buddyinfo
cat /proc/pagetypeinfo
cat /proc/vmallocinfo
cat /proc/slabinfo
- 设置内存管理相关的断点
在 GDB 中设置这些关键函数的断点:
内存初始化
break mem_init
break mm_init
页面分配
break __alloc_pages
break get_page_from_freelist
页面错误处理
break do_page_fault
break handle_mm_fault
SLAB 分配器
break kmem_cache_alloc
break kmalloc
VMALLOC
break __get_vm_area_node
- 查看关键数据结构
查看 memblock 信息
print memblock
查看 zone 信息
print contig_page_data
查看特定进程的 mm_struct
print init_mm
- 内存调试技巧
创建一个简单的测试程序来触发内存操作:
在 QEMU 的 shell 中:
创建一个简单的内存测试脚本
cat > test_mem.sh << 'EOF'
#!/bin/sh
echo "=== Memory Test Start ==="
分配一些内存
echo "Testing kmalloc..."
echo 1024 > /proc/sys/kernel/printk # 降低日志级别
dmesg -c > /dev/null
触发页面分配
cat /proc/self/status | grep -i vm
显示内核消息
dmesg | tail -20
echo "=== Memory Test End ==="
EOF
chmod +x test_mem.sh
./test_mem.sh
针对 ARM64 内存特性的学习重点
ARM64 架构有一些特定的内存管理特性,特别值得关注:
- 多级页表:ARM64 通常使用 4级页表(CONFIG_ARM64_PGTABLE_LEVELS)
- MMU 配置:学习 ARMv8 的 MMU 寄存器配置
- 内存模型:稀疏内存模型(CONFIG_SPARSEMEM)
- 物理地址扩展:支持超过 4GB 物理内存
你可以在内核配置中关注这些选项:
在 .config 中查看 ARM64 特定的内存配置
grep CONFIG_ARM64 .config | grep -i memory
grep CONFIG_SPARSEMEM .config
grep CONFIG_PGTABLE .config
故障排除
-
QEMU 启动失败:
• 检查 -machine 和 -cpu 参数是否正确
• 确认内核配置支持 virt 平台
-
GDB 连接问题:
• 确保先启动 QEMU(带 -s -S)
• 检查端口 1234 是否被占用
-
内核崩溃:
• 确认 initramfs 中的 busybox 是 ARM64 版本
• 检查内核配置是否正确
这个 ARM64 环境更适合在 Termux 中学习,编译速度更快,而且能够直接观察 ARM 架构特有的内存管理机制。你可以单步调试内存初始化过程,观察页表建立,深入了解 Linux 在 ARM 平台上的内存管理实现。