[MIT 6.S081] Lec 20: Kernels and HLL 笔记

Lec 20: Kernels and HLL

使用 C 语言实现 OS

优点

  • 内存分配和释放的控制能力
  • 几乎无隐藏的代码
  • 直接访问内存的能力(可以读写 PTE 的标志位或设备寄存器)
  • 极少的依赖(不需要运行时)

缺点

  • 缓冲区越界
  • 使用已释放的内存(use-after-free bugs)
  • 线程共享动态内存(很难确定是否可以释放内存)

使用高级编程语言(HLLs)实现 OS

优点

  • 提供了内存安全性(memory-safety). 上述 C 语言实现 OS 的内存漏洞不会存在.
  • 类型安全
  • 通过 GC 实现的自动内存管理
  • 并发更友好
  • 更好的抽象(接口, 类等面向对象语法更易写出模块化代码)

缺点

  • 更差的性能(High Level Language Tax):
    • 边界检查, 类型检查, 空指针检查
    • 垃圾回收
  • 与内核编程不兼容
    • 无内存直接访问能力
    • 不能集成汇编语言
    • 受限的并发/并行(与内核所需的并行不一致, 比如在线程调度时线程的锁会传递, 在用户程序中不常见)

论文背景

  • 缺少对内核中高级编程语言的优劣分析的工作
  • 使用高级编程语言构建操作系统内核与 Linux 内核比较

选择的高级语言

Golang

  • 容易调用汇编代码
  • 静态编译语言, 性能更好
  • 容易并发
  • 容易静态分析
  • 带有垃圾回收

Biscuit

使用 Golang 实现的宏内核操作系统

特性

  • 支持多核 CPU
  • 支持用户程序多线程
  • 高性能日志文件系统
  • 虚拟内存系统
  • 完整的 TCP/IP 栈
  • 高性能驱动: 网卡和磁盘驱动

用户程序

  • 用户进程有自己的地址空间(页表)
  • 用户/内核内存空间由硬件隔离
  • 每个用户线程有对应的内核线程
  • 内核线程由 go runtime 提供的 goroutine 实现

系统调用

  1. 用户线程将参数保存在寄存器中
  2. 用户线程执行 SYSENTER 指令进入到系统内核
  3. 控制权转移到内核线程
  4. 内核线程执行系统调用, 通过 SYSEXIT 返回到用户空间

实现的挑战

  • 在裸机上运行 Go runtime
  • 使用 goroutines 运行不同应用程序
  • 在临界区中的设备中断处理
  • 最困难: 堆耗尽
    • 多数内核: 通过 malloc() 返回错误
    • Go 调用 new 分配对象, 总是成功

堆耗尽的解决方法

不合适的方法
  • 报 panic
  • 在内存分配器中等待 -> 可能导致死锁
  • 检测并处理无内存时返回的空指针
最终解决方案

保留内存. 在程序执行系统调用前调用 reserve() 函数预先保留足够内存(保留的内存通过算法分析得到)
优点:

  • 内核中没有检查
  • 不用错误处理代码
  • 没有死锁问题

选择 C 语言或 HLL 实现 OS

  • 性能至关重要 -> C 语言 (提升至少 15%)
  • 最小化内存使用 -> C 语言
  • 安全至关重要 -> HLL
  • 性能不那么重要 -> HLL
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值