Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

84 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MyOS ARM64

这是一个基于 ARM64 架构的裸机操作系统项目,支持 QEMU virt 平台。

项目特性

  • 架构: ARM64 (AArch64),QEMU virt 平台
  • 内存管理: Buddy 物理分配器 + Slab 内核堆 + vmap/vmalloc + VMA 进程地址空间 + COW
  • 进程调度: 多级优先级队列、时间片轮转、fork/execve/wait4、Zombie 回收
  • 文件系统: FAT32 读写(创建/删除/截断/重定向)、VFS 抽象层
  • 信号: 位图信号量 pending/blocked/handler、用户态信号帧传递
  • Shell: cat/mkdir/rm/touch 内置命令、> 重定向、外部命令执行
  • 驱动: UART、GICv2 中断控制器、ARM Generic Timer、Virtio-blk、FDT 设备树
  • 混合编程: C 编写底层(MMU、中断、Buddy、Slab)、Rust 编写上层(调度、VFS、信号、Shell)

编译说明

环境要求

1. 交叉编译工具链

根据您的操作系统,需要安装以下工具链之一:

Windows (推荐):

ARM GNU Toolchain: aarch64-none-elf-gcc

Ubuntu/Linux:

sudo apt-get install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu

Termux (Android):

pkg install clang lld

2. QEMU 模拟器

Windows:

Ubuntu/Linux:

sudo apt-get install qemu-system-arm

Termux:

pkg install qemu-system-aarch64

3. 设备树编译器 (可选)

# Ubuntu/Linux
sudo apt-get install device-tree-compiler

# Windows (MSYS2)
pacman -S dtc

编译命令

基本编译

# 编译内核 ELF 文件
make

# 或使用多线程加速编译
make -j4

运行 QEMU

# 正常运行
make run

# GDB 调试(阻塞等待)
make debug

# GDB 调试(不阻塞)
make debug-no-suspend

# 串口独立调试
make serial

生成设备树

# 导出 QEMU 设备树并转换为 DTS
make dtb

清理编译结果

# 清理编译生成的文件
make clean

# 清理设备树文件
make clean-dtb

查看 ELF 信息

# 查看 ELF 文件段信息
make readelf-l

# 查看 ELF 文件节信息
make readelf-S

# 查看 ELF 文件符号表
make readelf-s

# 查看所有 ELF 信息
make readelf

编译选项

架构选择

默认编译 ARM64 架构,可以通过命令行指定:

make ARCH=arm64

功能配置

项目支持通过 config.mk 文件进行条件编译,可以启用或禁用特定功能。

编译输出

编译完成后,生成的文件位于 build/ 目录:

  • build/kernel.elf - ELF 格式的内核镜像(默认目标)
  • build/kernel.img - 二进制格式的内核镜像

调试

GDB 调试

  1. 启动 QEMU 调试模式:
make debug
  1. 在另一个终端启动 GDB:
aarch64-none-elf-gdb build/kernel.elf
  1. 在 GDB 中连接 QEMU:
target remote localhost:1234

常见问题

1. 找不到交叉编译器

确保交叉编译器已安装,并且路径已添加到系统 PATH 环境变量中。

Windows: 将 aarch64-none-elf-gcc 的 bin 目录添加到 PATH

Linux: 确保 gcc-aarch64-linux-gnu 已正确安装

2. 多线程编译失败

如果遇到目录创建错误,可以尝试:

# 先创建目录
make build_dir

# 再编译
make -j4

3. QEMU 无法启动

确保 QEMU 已正确安装,并且路径已添加到系统 PATH 环境变量中。

Rust 开发指南

环境要求

本项目基于 Rust 1.95.0 stable 开发,支持 Windows、Linux 和 Termux 环境。

Windows / Linux

推荐使用 rustup 安装 Rust 工具链:

# 安装 Rust(如果没有)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 安装 ARM64-none-none 目标(裸机目标)
rustup target add aarch64-unknown-none

# 安装 LLVM 工具(用于链接)
rustup component add llvm-tools-preview

# 验证安装
rustc --version
cargo --version
rustup target list --installed

Termux (Android)

Termux 没有 rustup,需要从项目分支安装 target:

# 克隆 rust-lib 分支
git clone -b rust-lib https://github.com/2312469331/myos-arm64.git

# 切换分支
cd myos-arm64
git checkout rust-lib

# 执行安装脚本
bash install-none.sh

# 或手动设置
# cp -r none-* ~/.rustup/toolchains/*/lib/rustlib/

Rust 代码结构

rust/
├── src/
│   ├── lib.rs          # 库入口(包含 rust_main)
│   ├── allocator.rs    # 全局内存分配器
│   ├── ffi.rs         # FFI 接口定义
│   ├── irq.rs         # 中断管理接口
│   └── ...
├── Cargo.toml          # Rust 项目配置
├── build.rs            # 构建脚本
└── install-none.sh     # Termux 安装脚本

Rust 编译命令

# 编译 Rust 代码
cd rust
cargo build

# 清理 Rust 编译结果
cargo clean

# 查看 Rust 代码大小
cargo size --release 2>/dev/null || echo "Build required first"

Rust 语言项要求

由于本项目使用 #![no_std]#![no_main],需要定义以下语言项:

// #[panic_handler] - 必须:处理所有 panic 情况
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
    // 打印错误信息并进入死循环
    loop {}
}

// #[lang = "eh_personality"] - 必须:异常处理 personality 函数
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

// #[global_allocator] - 可选:自定义全局内存分配器
#[global_allocator]
static ALLOCATOR: KernelAllocator = KernelAllocator;

内存分配策略

Rust 分配器对接 C 的 kmalloc/kfree

  1. ≤ 64KB: 走 C 侧 kmalloc → Slab 或 large_alloc
  2. > 64KB: 直接走 Buddy 分配物理页
  3. 失败: 返回 NULL 触发 alloc_error(目前不处理,直接 panic)

FFI 接口

Rust 代码通过 FFI 调用 C 函数:

// 声明 FFI 函数
unsafe extern "C" {
    fn c_print_str(s: *const c_char);
    fn rust_kmalloc(size: usize) -> *mut u8;
    fn rust_kfree(ptr: *mut u8, size: usize);
}

常见问题

1. Rust 编译错误:unknown target aarch64-unknown-none

# 添加 ARM64 裸机目标
rustup target add aarch64-unknown-none

2. 链接错误:rust_main 符号未找到

确保在 main.c 中调用了 rust_main()

extern void rust_main(void);
rust_main();

3. 内存分配失败导致 panic

检查 C 侧的 rust_kmalloc 是否正确实现,确保内存分配器已初始化。

相关文档

项目结构

myos-arm64/
├── arch/arm64/          # ARM64 启动代码 + 异常向量表 + MMU 页表操作
│   ├── boot/           # boot.S + link.ld + vector.S
│   ├── Core/           # CMSIS-Core 代码
│   └── device/         # 设备初始化
├── kernel/              # C 内核(内存分配器 + 缺页处理 + 驱动)
│   ├── main.c          # 主函数
│   ├── pmm.c           # Buddy 物理内存分配器
│   ├── slab.c          # Slab 内核堆分配器
│   ├── mmu.c           # 页表映射(arm64_map_one_page)
│   ├── vmalloc.c       # vmalloc 内核虚拟内存
│   ├── vmap.c          # vmap 红黑树+链表区间管理
│   ├── page_fault.c    # COW + 按需缺页处理
│   └── ...
├── rust/src/            # Rust 上层(调度 + VFS + 信号 + syscall + Shell)
│   ├── kernel/
│   │   ├── scheduler.rs  # 进程调度 + rust_main
│   │   ├── task.rs       # PCB + fork/exit/wait4
│   │   ├── syscall.rs    # 30+ 系统调用
│   │   ├── elf.rs        # ELF 加载器
│   │   ├── fs/           # VFS + FAT32 驱动
│   │   ├── mm.rs         # VMA 地址空间管理
│   │   ├── signal.rs     # 信号位图
│   │   ├── tty.rs        # TTY 输入环形缓冲
│   │   ├── virtio.rs     # Virtio-blk 驱动
│   │   └── wait.rs       # 等待队列
│   ├── arch/aarch64/     # TaskContext + context_switch
│   └── allocator.rs      # 全局分配器(对接 C kmalloc)
├── driver/              # C 驱动
│   ├── uart.c           # UART 串口
│   ├── gic.c            # GICv2 中断控制器
│   ├── timer.c          # Cortex-A53 定时器
│   └── fdt/             # FDT 设备树解析
├── user_bin/            # 用户态程序
│   ├── shell.c          # Shell(cat/mkdir/rm/touch/重定向)
│   └── echo.S           # 测试 ELF
├── include/             # C 头文件
└── doc/                 # 文档

文档

许可证

本项目采用 MIT 许可证。

贡献

欢迎提交 Issue 和 Pull Request!

About

arm64 os for cortex-a53

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages