Fuchsia 简介 许中兴 xu_zhong_xing@163.com
Fuchsia 的来历 多年年的 Android, ChromeOS 开发经验 一 方 面让 Google 在操作系统 方 面积累了了 足够多的 人才和组件, 另 一 方 面也充分认识到了了 Linux kernel 很多的局限性 Fuchsia 是 一个全新的操作系统的统称 Google 挑选了了 一系列列它认为合适的技术和组件进 入这个操作系统, 比如 : 微内核, 基于能 力力的访问控制,Vulkan 图形接 口,3D 桌 面渲染 Scenic,Flutter 应 用开发框架 目前 支持的编程语 言是 :C/C++, Go, Rust, Dart Google2016 年年中放出了了所有的代码, 但是没有正式宣布这个项 目的 目标, 开发社区 目前有 一个 IRC 频道进 行行交流 支持的架构是 X86-64 和 ARM 64, 支持的设备从 IoT 到服务器器
现代通 用 开放 OS 需要 面对的 方 面 上游硬件 厂商 下游应 用开发者 设备友商 用户 黑客
Fuchsia 解决现代 OS 痛点 原 生进程沙箱, 解决应 用安全和分发问题 ( 黑客 ) Linux: namespace, control group, unionfs => docker 稳定的驱动接 口, 硬件 厂商可独 立维护硬件驱动 ( 硬件 ) 系统模块化, 分层, 设备 厂商可以灵活定制专有系统 ( 友商 ) 基于 Vulkan 和物理理渲染的纯 3D UI, 全局光照 ( 用户 ) Flutter 应 用开发框架 ( 开发者 )
关于进程沙箱,Fuchsia 重新思考 三个 Unix 的基础抽象机制 全局 文件系统 用户 进程的创建
全局 文件系统 在 Unix 里里, 存在 一个全局的根 文件系统 它是每个进程共享的基础资源 文件系统涵盖了了 非 文件资源 :/proc, /sys,.. 网络是例例外 在 Fuchsia 里里, 没有全局根 文件系统 文件和 文件系统成为 一个局部概念 ( 局限在每个 文件系统进程 里里 ), 从 而在进程内核数据结构 里里没有 file 用 namespace 来定义 一个进程能够访问的资源 每个 name( 路路径 ) 对应 一个资源进程 channel 的 handle / -> root vfs service handle, /dev -> dev fs service handle, /net/dns -> DNS service handle
User 在 Unix 中,user 本来是 用作不不同的 用户登录共享服务器器的机制 user 是真正的 用户 后来主要 用作权限控制, 弱化的沙箱机制 在 Fuchsia 中, 在底层 (Zircon, Garnet) 没有 用户的概念 用namespace 来控制进程能够访问的资源 Capability-based access control 从 而在进程 里里没有 uid
进程的创建 在 Unix 中, 新的进程由 老老的进程 fork 而来 新的进程继承 父进程的全部资源 一种偷懒的设计 在 Fuchsia 中, 新进程的创建需要从头开始 创建 process, thread 父进程建 立初始的 namespace 到资源 channel handle 的映射 调 用process_start 显式的告诉内核新的进程可以跑了了 在 Fuchsia 内核的 process 数据结构 里里, 没有 file 和 uid
仿佛是专 门针对漏漏洞洞利利 用作出的设 计 典型的漏漏洞洞利利 用步骤 fork()/exec() 开反向 shell 继承 uid( 或者通过获得 root uid 进 行行提权 ) 获得泛在授权 访问全局 文件系统 在 Fuchsia 里里, 以上机制全都不不存在 创建进程时显式建 立root namespace 没有 user, 从 而没有 ambient authority (DAC/MAC) Capability-based access control 能访问的资源是 父进程赋予的 namespace 看不不到初始 namespace 之外的任何资源
微内核 Linus vs Tanenbaum 的论战 Tanenbaum: Linux 是七 十年年代的技术 在 1991 年年写宏内核是错误的 争论早就结束了了, 微内核已经赢了了 我是教授,Minix 只是我的 hobby, 所以别拿 Minix 说 事 Linus: Linux 比你写的 Minix 强多了了 微内核只是你们学术界的玩具, 我看过所有的关于微内核效率优化的论 文, 它们实际上只是在重复宏内核早就 用过的技巧 Mach, Hurd Performance overhead Context switching (user space <=> kernel space) Thread scheduling
Overhead: single core case Monolithic CPU0 Context switching: 2 Micro CPU0 Context switching: 8 Thread scheduling: 4
CPU0 CPU0 CPU1 CPU2 CPU3
Overhead: multicore case Monolithic CPU0 Context switching: 2 Micro CPU0 Context switching: 2 CPU1 Context switching: 2 CPU2 Context switching: 2 CPU3 Context switching: 2
Fuchsia 架构 Applications Flutter Framework Kernel (process, IPC, mm) devmgr(/dev) appmgr(/hub) fshost(/) sysmgr svchost(/svc) scenic (Vulkan) devhost(/dev/x) devhost devhost devhost(gpu driver) Hardware
世界需要新的操作系统 Windows 老老迈 龙钟, 历史负担太重, 微软 自 己的创新 Midori 胎死腹中, 因为 无法承受在新的框架中重新实现 一遍 Windows 的全部功能, 只能在原地进 行行重构 Linux 只关 心服务器器的世界, 就像 一个专注于在甲板下 面锅炉房 里里 干活的锅炉 工, 上不不得桌 面 MacOS, ios 封闭在苹果的硬件 生态 里里 Android 为了了弥补 Linux 的缺点打上了了 一个厚厚的中间层, 不不断在做着妥协 GNU Hurd 作为 GNU 项 目 最后的组件 一直未能产品化, 原因是 微内核消息传递机制 debug 太困难? Unix 的后继者 Plan 9 于 2002 年年发布了了最后 一个版本, 它的余热随着作者融 入了了 Go
Fuchsia 在各个平台上的可能的优 势 在服务器器平台上, 原 生的进程沙箱机制将带来新的安全特性和容器器机制 在桌 面平台上, 类似于游戏 3D 引擎 pipeline 的图形栈以及毫 无遗产负担的实现将使电 子娱乐应 用变得更更为 高效 ; 无缝兼容庞 大的 Android 生态 在移动平台上, 系统的模块化 方便便第三 方设备 厂商的全 面定制, 驱动框架 方便便硬件 厂商编写和维护私有驱动
Fuchsia 分层 Fuchsia 是 一个像 Lego 玩具 一样组装起来的操作系统 谷歌在设计时已经考虑了了其他 厂商可能会深度定制适配 自 己产品的操作系统, 所以模块化做得 比 Android 彻底很多 厂商的深度定制可以从以下任意 一层开始 Zircon: 微内核, 基础服务进程 ( 设备管理理器器, 核 心设备驱动,libc, 进程间通信接 口库 fidl) Garnet: 设备层 面的系统服务 : 软件安装, 通信, 媒体, 图形, 包管理理, 更更新系统等 Peridot: 用户体验的基础设施层 : 模块, 用户, 存储服务, 等等 Topaz: 系统的基础应 用,Web, Dart, Flutter 这些名字来 自于 Steven Universe
Fuchsia 启动流程 设置各种控制寄存器器, 进 入 EL1 设置内核 页表, 打开虚拟内存 之后进 入 C 的世界 用 psci smc call 启动副 cpu devmgr=> svchost, fshost, devhost, appmgr=> sysmgr userboot 从 bootfs 中加载 第 一个 文件进程 devmgr 构造第 一个 用户态线程 userboot, 内核线程进 入 idle 进 行行 一系列列初始化, 包括各种设备 为当前执 行行轨迹初始化为线程结构 Zircon 内核线程 比较少, 主要是 dpc thread (deferred procedure call)
上 面的符号代表虚拟地址 (-4G 之上 ) code_start=-4g, code_end tt_trampoline KERNEL_BASE boot_cpu_kstack boot_cpu_kstack_end 0 64k _start, IMAGE_ELF_ENTRY 64k+80 bss_start _end sp(third) stack_end, sp_el1, sp(first) _bootdata_file_header kernel 下 面的符号代表物理理地址 (0 开始 ) _bootdata_kernel_header sp(second) _bootdata_kernel_payload kernel_image
第 一个 用户态进程的创建 之前的微内核 一般需要实现 一个基本的 文件系统加载功能在内核 里里, 然后加载第 一个 用户进程 文件, 之后就不不再使 用内核 里里的 文件系统功能 Zircon 把第 一个 用户态进程的 ELF 文件嵌 入进内核映像 里里, 这样就不不需要从 文件系统 里里加载了了
系统调 用 vdso 内核映像还嵌 入了了 一个 vdso, 包含了了系统调 用 入 口 这个 vdso 被映射到每个进程的内存地址空间 里里 它本身是 ELF shared object 文件格式, 但是 又不不是以 文件形态存在, 所以叫做 vdso Linux kernel 也 用这种 方式实现了了 一些简单的系统调 用, 比如 getdaytime() 但是 Zircon 并不不是为了了避免切换内核态, 而是把系统调 用的代码嵌 入到了了内核 里里
内核态功能 虚拟内存和物理理内存管理理 vmo: virtual memory object: 包含物理理 页 进程和线程管理理 Handle 指向内核中的各种对象 进程间通信 channel MessagePack signal and wait 中断处理理 唤醒等待该中断的 用户线程 没有 POSIX 支持
Zircon 用户态 devmgr, devhost, svchost, fshost appmgr sysmgr Fuchsia 定义了了 一套稳定的 DDK 接 口, 硬件 厂商开发 自 己的闭源驱动的 方便便性 大 大提 高了了 因为 Linux kernel 是拒绝提供稳定的内核内部驱动接 口的 要想被官 方维护, 就得放进内核 里里, 否则只能 自 己跟着内核去改接 口 内核不不提供 POSIX 支持, 用户层可以模拟 一部分 POSIX 接 口
channel channel 是进程间通信的 ( 唯 一 ) 机制 一个 channel 有 2 个 handle,h1, h2, 从 一头写 入消息, 从另 一头读出消息 一个进程在创建时有 一些初始 channel handle 要与 一个服务 x 建 立通信, 进程创建 一个 channel, 自 己拿 h1, 把 h2 通过已有的 channel(root_svc) 发送给相应的服务, 服务拿到 h2, 将其放到 自 己的事件监听循环 里里 示意 api:connecttoservice(root_svc, x, h2) 比如 open(), 在 linux 里里会在进程的内核数据结构 里里增加打开的 文件描述符, 不不涉及到其他进程 ; 在 fuchsia 里里则是创建 一个 channel, 把远端发送给相应的服务, 建 立通信通道 channel_write() 把消息写到另 一个进程能看到的地 方 进程间是不不共享内存地址空间的 只有内核的地址空间是进程共享的 所以 channel_write() 必须是 一个系统调 用, 切换到内核地址空间 里里进 行行消息写 入 一旦切换到内核地址空间 里里, 就能看到另 一个 handle 了了 写到那个 handle 的消息队列列 里里, 等另 外 一个进程切换到内核地址空间 里里, 就能看到消息了了
channel 的实现 Process A Process B handleindex 1 handleindex 2 handle 1 peer handle msg list Kernel handle 2 peer handle msg list
Kernel Address Space Layout Randomization ELF 的加载位置是随机的, 并不不是遵守 ELF program header 里里规定的 v_addr 会在加载时对符号地址进 行行修正
Fuchsia 目前的运 行行环境 Qemu 最 方便便的环境, 没有 GUI Intel NUC 目前最好的测试环境, 有 GUI Vim2 dev board 学习 ARM64 架构, 等 谷歌开放出 GPU 驱动和 Bootloader
Qemu 在 Qemu 中可以直接运 行行 booloader 加载到 0x40080000 内核加载到 0x40090000 ramdisk 加载到 0x48000000 0x40000000-0x40080000 之间是 FDT flattened device tree
Intel NUC 开发机启动 paving 服务, 会将整个 Fuchsia 操作系统刷到 NUC 上 启动 zircon 到 zedboot 模式, 会直接连接开发机
Khadas Vim2 开发板 Amlogic S912 SoC Quad Core A53 Mali-T450MP5 GPU 3G DDR4 64G emmc storage HDMI, USB-C, USB 2.0, TF Card, Ethernet, WiFi, Bluetooth
Vim2 的启动 Arm Trusted Firmware: BL1 in ROM Custom u-boot: BL2 + BL30 +BL31 + BL32 + u-boot(bl33) 其中 bl2,bl30,bl31,bl32 都是 amlogic 提供的 binary bl33 从 emmc offset 0x50200 处开始, 加载到内存 16MB 处执 行行 使 用fastboot 协议可以 用usb-c 将 zircon kernel 写 入boot 分区 需要 一个适合 zircon 的 bootloader 来启动 zircon, 但是 Google 尚未放出 所以还不不能启动 zircon
系统软件研发能 力力的获得 系统软件与应 用软件不不同 有 大量量的缄默知识, 长期积累的 know-how 工具链 :gcc, ld, as, clang, ELF, 微处理理器器 :X86, ARM, 周边设备 :UEFI, ACPI, APIC, PCIE, USB, SATA, AHCI, GPU 知识存在于代码中, 没有系统化的 know-how 文档, 硬件标准 文档 一般都是 1000+ 页 写玩具系统容易易, 产品级的设计 非常困难 : 支持海海量量的设备, 应 用, 负载 要经过以下四个阶段 模仿 理理解 掌握 创新
总结 Fuchsia 在安全 方 面具有重要的创新 在未来 Fuchsia 会成为 一个 非常重要的操作系统
一些笔记 https://github.com/xuzhongxing/fuchsia-notes