在未来Fuchsia会成为一个非常重要的操作系统。
重德智能工程师 许中兴如是说。
《世界需要新的操作系统-Fuchsia设计解读》的学习笔记。
了解Fuchsia操作系统的基本情况、设计原理和优点,了解市场上各个操作系统的境况。
Fuchsia的基本情况
- 全新的操作系统
- Google开发
- 微内核,基于能力的访问控制,Vulkan图形接口,3D桌面渲染Scenic,Flutter应用开发框架,目前支持的编程语言:C/C++,Go,Rust,Dart
- 2016年,Google放出所有代码,但是没有正式宣布项目目标,一个IRC频道交流
- 支持的架构X86-64和ARM 64,支持的设备从IoT到服务器
Google为什么要从头设计权限的操作系统
- 737问题:当系统总体设计出现问题的时候,用再多的技巧去弥补,也只会造成最终的灾难
现代通用、开放OS需要面对的方面
- 上游硬件厂商
- 下游应用开发者
- 设备友商
- 用户
- 黑客
Fuchsia解决现代OS痛点
- 原生进程沙箱,解决应用安全和分发问题
- Linux:Namespace,Control group,Unionfs => Docker
- 稳定的驱动接口,硬件厂商可独立维护硬件驱动
- 系统模块化,分层,设备厂商可以灵活定制专有系统
- 基于Vulkan和物理渲染的纯3D UI,全局光照
- Flutter应用开发框架
Fuchsia重新思考四个Unix的基础抽象机制
- 全局文件系统
- Unix,存在一个全局的跟文件系统
- 他是每个进程共享的基础资源
- 文件系统涵盖了非文件资源:/proc, /sys, …
- Fuchsia里,没有全局根文件系统
- 文件和文件系统成为一个局部概念,从而在进程内核数据结构里没有file
- 用Namespace来定义一个进程能够访问的资源,每个name对应一个资源进程channel的handle
- Unix,存在一个全局的跟文件系统
- 用户
- Unix中,User本来是用作不同的用户登录,共享服务器的机制
- User是真正的用户
- 后来主要用作权限控制,弱化的沙箱机制
- Fuchsia中,在底层(Zircon,Garnet)没有用户的概念
- 用namespace来控制进程能够访问的资源
- Capability-based access control
- 从而在进程里没有uid
- Unix中,User本来是用作不同的用户登录,共享服务器的机制
- 进程的创建
- Unix中,新的进程由老的进程fork而来
- 新的进程继承父进程的全部资源
- 偷懒的设计
- Andrew Baumann, a fork() in the road, ACM Hot Topics in OS, May 2019
- Fuchsia中,新进程需要从头开始创建
- 创建process,Thread
- 父进程建立初始的namespace到资源channel handle的映射
- 调用process_start显式的告诉内核新的进程可以跑了
- 在Fuchsia内核的process数据结构中,没有file和uid
- Unix中,新的进程由老的进程fork而来
- 系统调用
- Unix中,通过中断调用内核服务:int 0x80,syscall,sysenter 系统调用的方式是确定的,直接的
- 内核接口不能变
- 可以被任意注入的代码调用
- Zircon里系统调用通过vDSO进行,意图是防止用户代码直接通过固定的中断代码调用system call,达到内核详细接口的隔离,保持C层面的接口稳定:名字 + 参数。而不是内核入口汇编指令层面的稳定
- 注入的代码无法直接调用vDSO里的接口,虽然加载地址固定,但是计算出入口地址很难,如果不是不可能的话
- 内核会验证调用指定的地址,而vDSO的加载地址是固定的,并且在编译的时候会验证有限的入口符号,这些符号在编译时位移生成,防止用户进程绕过vDSO
- 这里主要的目地是隔离system call的调用方式,不是绝对已以上的不可注入调用
- Unix中,通过中断调用内核服务:int 0x80,syscall,sysenter 系统调用的方式是确定的,直接的
仿佛是专门针对漏洞利用作出的设计
- 典型的漏洞利用步骤
- 通过系统调用fork()/exec()直接创建反向shell
- 继承uid获得泛在授权
- 访问全局文件系统
- 在Fuchsia里,以上机制都不存在
- 没有固定的系统调用入口
- 船舰进程时显式建立root namespace
- 没有user,从而没有ambient authority (DAC/MAC)
- Capability-based access control
- 能访问的资源是父进程赋予的namespace,看不到初始namespace之外的任何资源
Kernel的本质是什么?
- 不是
- 管理硬件
- 执行特权指令
- 引导启动过程
- 处理中断
- 作者的理解:地址空间切换
- 不同进程唯一共享内存地址空间的场合
- 切换地址空间是进入内核的标志
- 不同的进程通过共享内核地址空间来交换信息
- 切换地址空间是切换进程的关键步骤
- Zircon主要内核态共跟你个
- 虚拟内存和物理内存管理
- 进程和线程管理
- 进程间通信
- 以内存为中心的设计
- VMO代表一个内存对象,懒分配
- VMO通过向channel发送handle在进程之间传递,进程拿到VOM handle,把VMP重新映射到自己的地址空间里
- Unix是以文件为中心的设计
- Channel
- 是进程间通信的唯一机制
- 一个channel有两个handle,h1,h2,从一头写入ixaoxi,从另一头读出消息
- 进程进程,有一些初始channel handle
- 要与一个服务建立通信,h1自己拿着,h2发送给响应的服务做监听
- channel_write() 必须是一个系统调用
- 系统调用vDSO
- 微内核
- 性能问题
- 上下文切换
- 线程切换
- 性能问题
Fuchsia在各个平台上的可能的优势
- 服务器平台,原生进程沙箱机制将带来新的安全特性和容器机制
- 桌面平台,无缝兼容Android
- 移动平台,系统的模块化方便第三方设备厂商的全面定制
Fuchsia分层
- 四层,后两层可以替换掉,不影响兼容性
- 用户体验层
- 应用层
- 内核层
- 系统服务层
Fuchsia 目前的运行环境
- 在Qemu中可以直接运行
- Booloader加载到0x40080000
- 内核加载到0x40090000
- Ramdisk加载到0x48000000
- 0x40000000 - 0x40080000之间是FDT flattened device tree
系统软件研发能力的获得
- 系统软件与应用软件不同
- 大量缄默知识
- 工具链:gcc,Id,as,clang,ELF
- 微处理器
- 周边设备UEFI,ACPI,APIC,PCIE,USB,STATA,AHCI,GPU…
- 知识存在与代码中,硬件标准文档内容太多
- 产品级的设计非常困难
总结
- Fuchsia重新思考了操作系统设计的各个方面,是一次男的的从头开始的机会
- 在未来Fuchsia会成为一个非常重要的操作系统
- 世界需要新的操作系统
- 每一个大型软件系统都值得尊重
- Windows老迈龙钟,历史负担太重,微软自己的创新Midori胎死腹中,因为无法承受在新的框架中重新实现一遍Windows的全部功能,只能在原地进行重构
- Linux里大部分开发人员只关心服务器的世界,就像一个专注与在加班下面锅炉房里干活的锅炉工
- MacOS,iOS封闭在苹果的硬件生态里
- Android微了弥补Linux的缺点打上了一个厚厚的中间层,不断在做着妥协
- GNU Hurd作为GNU项目“最后的组件”一直未能产品化,原因是“微内核消息传递机制debug态困难”?
- Unix的后继者 Plan 9 与2002年发布了最后一个版本,他的余热随着作者融入了Go