Golang Go语言中编写的跑在x86裸机上的unikernel
Golang Go语言中编写的跑在x86裸机上的unikernel
github 地址 https://github.com/icexin/eggos
这是一个使用 Go 编写的运行于 x86 机器的 unikernel,全部用 go 编写(除了 bootloader 和一些汇编)
Go 的 runtime 提供了一些基本的操作系统抽象,goroutine 对应进程,channel 对应进程间通信,另外 go 有自己的虚拟内存管理,所以萌生了在裸机上运行 Go 程序的想法。
实际证明,Go 有操作硬件资源的能力,得益于 Go 可控的内存布局,以及不需要虚拟机直接翻译硬件指令的能力,还有类 C 的语法。这些都让 Go 编写运行于裸机的程序有了可能。
然而也有一些挑战,Go 在很多指令里面打桩来进行协程调度以及内存 GC,在一些不能重入的地方,如中断处理和系统调用,都带来了一些麻烦。
功能 list
- 基本的 go 功能,goroutine,channel,GC 等
- 大部分标准库
- TCP/IP 网络栈
- VFS 抽象
- nes 模拟器,js 解释器等
一些快照
支持 http get 的 js 解释器
nes 模拟器
欢迎学习交流!
更多关于Golang Go语言中编写的跑在x86裸机上的unikernel的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
厉害了,已点 star
未来会支持 x86_64 和 uefi 吗,毕竟现在也没有多少 x86 的机器了
更多关于Golang Go语言中编写的跑在x86裸机上的unikernel的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
x86_64 在计划中,切换到 64 位应该还好,主要是分页管理以及一些系统调用的不一样,可能有一些其他的坑,使用 multiboot 作为 bootloader 主要是方便 qemu 调试。
学习了,厉害
可执行文件是 elf 格式的吗,标准库是 c 库吗?
厉害,Star 了。加油。
我用 cxx 写过 os 但没想到还有这么屌的
楼主是实现了 go runtime 吗,可以运行 elf 也可以运行 go 程序?看介绍是实现了大部分 go 标准库?这就很强大了。
Unikernel 的意思就是程序作为代码连接进内核中,所以没有 elf 加载器之类的.
[email protected]/sleep/commit_noasm.go:38:45: undefined: preparingG 编译失败 😂
rust 更适合干这活啊
> Go 在很多指令里面打桩来进行协程调度以及内存 GC
这里的打桩具体指的是?
Go 的编译器会在函数入口检查栈是否溢出,如果溢出就执行 runtime 函数扩容,可能会触发调度,还有一些 writeBarrier 用于辅助 GC
现在只支持 go1.13 哈,其他版本可能会出现问题
硬核
我记得 go 设计出来的时候,为了显示 自举 和 兼容性,设计团队就在裸机上跑过
大佬
是用什么来模拟 x86 裸机呢
开发的时候用的 qemu,最终用 grub 引导在我自己的台式机上跑
虽然现在的 cpu 都是 64 位的,但如果没有显式开启 64 位,是可以运行于传统的 32 位保护模式下的。
在Golang中编写运行在x86裸机上的unikernel是一个高级且富有挑战性的任务,这通常涉及到底层系统编程和操作系统原理的深入理解。以下是一些关键点和建议:
-
了解裸机环境:
- 裸机(bare-metal)意味着没有操作系统层的抽象,你的代码直接与硬件交互。
- 熟悉x86架构的启动过程(如BIOS/UEFI引导),以及内存映射、中断和I/O端口等硬件资源。
-
使用适当的工具链:
- 使用像
x86_64-elf-gcc
这样的交叉编译器来编译你的Golang代码为目标架构。 - 可能需要自定义的链接脚本和启动代码(如用汇编语言编写的启动器)。
- 使用像
-
管理内存和中断:
- 在没有操作系统支持的情况下,手动管理内存分配和释放。
- 设置并处理中断,特别是与硬件交互时必不可少的定时器中断和I/O中断。
-
编写简单的操作系统框架:
- 使用Golang编写基本的操作系统服务,如任务调度、内存管理、文件系统抽象(如果需要)等。
- 由于Golang的runtime依赖于操作系统提供的服务,你可能需要实现或绕过这些依赖。
-
测试和调试:
- 使用硬件模拟器(如QEMU)进行初步测试,以避免直接在物理硬件上运行可能导致的损坏。
- 利用串行端口或其他调试接口进行日志记录和调试。
编写unikernel是一个复杂的项目,建议从简单的操作系统原理开始,逐步增加复杂性。