为什么不用 Go 编写操作系统?| 技术解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 为什么不用 Go 编写操作系统?| 技术解析

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁

🦄 博客首页——猫头虎的博客🎐

🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺

🌊 《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐

🌊 《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大小厂~💐

🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥



文章目录

为什么不用 Go 编写操作系统?| 技术解析

摘要:

本文探讨了使用高级语言Go编写操作系统的可行性,以及为什么C语言在操作系统开发中占据主导地位。虽然Go具有类型安全、自动内存管理和并发等优良特性,但由于垃圾回收和运行时的限制,Go并不是最适合编写操作系统的选择。C语言以其直接内存管理、可移植性和对底层硬件的控制成为主流内核开发的首选。尽管有一些使用Go编写的操作系统研究项目,但要编写一个完整的、用户友好的操作系统仍然具有挑战性。本文还简要介绍了使用Go编写的操作系统项目Biscuit和gopher-os,以及它们所面临的局限性。

前言

操作系统是计算机系统的心脏和灵魂。操作系统管理计算机的硬件和软件资源,并为用户提供与计算机交互的手段。传统上,C语言和汇编等语言因其低开销和“接近机器”的特性而被用于编写操作系统。但是,越发流行的Go等高级语言新引入了一些特性,可以使操作系统等复杂软件更易开发。例如,类型安全、错误处理和并发等特性有利于操作系统编写。因此,Go这样的高级语言应该会成为操作系统开发的自然选择。所以,为什么不是呢?

在本文中,您将了解为什么C语言这样的语言在操作系统开发中占有重要地位,以及使用Go编写操作系统是否可行。

为什么操作系统或内核是使用C语言和汇编编写的?

用于编写特定操作系统的语言可能难以确定,因为每个操作系统都是使用多种语言的组合编写而成。

操作系统的组件具有不同职责,可能使用不同的语言编写。操作系统的核心组件是负责与硬件交互的内核,内核几乎从来都是使用C语言或汇编语言编写。面向用户的组件,例如GUI应用,可以使用任何语言编写。举例来说,Android将Java用于用户空间组件,比如GUI框架和“相机”、“电话”等系统应用。相比之下,内核使用的是C语言和汇编,而低级系统组件(例如库)使用的是C++。

本文特别关注Go是否适合编写操作系统内核。几乎所有的主流内核都使用C语言编写,中间夹杂着一些汇编。C语言统治内核领域的几个原因:

  1. 直接内存管理:C语言的卖点是它允许程序员直接处理内存。虽然在编写内核时手动内存管理通常具有挑战性,但您会想尽可能多地控制内存,而C语言恰恰可以满足这样的需求。内存映射I/O、DMA控制器、页表、交换等概念都需要内存操作,使用C语言可以实现。
  2. 没有抽象:C语言没有哈希、树或链表这样的复杂数据结构,程序员可以根据需要自己实现。这提供了对代码更精细的控制,因为程序员可以调整实现的详细信息来提高效率。
  3. 不需要运行时:与Java和Python不同,C语言不需要运行时。只需要一个调用main()函数的机制,C语言就能够顺畅运行。这意味着您可以直接在硬件上运行C语言程序,而不必纠结于内存管理、进程管理等问题。
  4. 可移植性:C语言已被移植到多种CPU架构,是编写支持多架构内核的绝佳选择。

不过,C语言本身通常不足以编写整个内核,某些情况下您需要编写汇编代码:

  1. 手动编写的汇编可能比编译器生成的更好。某些操作可能难以在C语言中实现,并且编译器生成的机器码可能较为复杂或效率低下。在这种情况下,手动编写汇编是更好的选择。
  2. 某些代码无法使用C语言编写。例如,在C语言中切换任务时,无法将寄存器保存到堆栈,也不能将堆栈指针保存到任务控制块,因为C语言不提供对堆栈指针的直接访问。

为什么Go可以成为操作系统开发的替代语言?

Go这样的高级语言提供了一些优良特性,从表面上看,它们似乎是操作系统开发的绝佳选择:

  1. 某些类型的bug在高级语言中不太可能出现。缓冲区溢出和use-after-free bug在Go等语言中几乎是不可能的。即使是由专业程序员精心编写的C语言代码也会无意中包含这样的bug。use-after-free bug十分常见,因此Linux内核包含内存检查器,用于在运行时检测一些use-after-free和缓冲区溢出bug。
  2. 在高级语言中并发更容易处理,因为几乎每种高级语言都内置了处理并发所需的机制。
  3. Go这样的语言的类型安全可以防止C语言的宽松类型强制。

为什么Go没有用于操作系统/内核开发?

虽然Go提供了优良的特性,可以让操作系统开发者的工作更加轻松,但它也有一些局限性。

作为具有垃圾回收的语言,Go并不真正适合操作系统开发。使用Go编写内核意味着仔细编写代码,最大程度减少堆使用来小心绕过Go的垃圾回收。如这篇Reddit帖子中所述,鼠标延迟可能是因为中断处理程序分配了触发垃

圾回收的内存。

Go还需要大量运行时才能执行,不能直接在硬件上运行。尽管TinyGo可以将Go编译为在裸机上运行,但与C语言相比,它只支持少量的架构,而C语言几乎可以在任何架构上运行。

另一个相关问题是系统调用构成了典型Go运行时中的大量操作。运行时为各种操作与操作系统通信,例如写入文件或启动线程。但是,编写操作系统时,您必须在裸机上实现这些操作,并修改Go运行时来调用实现。然后问题归结为,您是否真的想花这么多时间和精力来修改运行时,毕竟C语言等其他语言允许您立即开始编写操作系统。

正如您所看到的,使用Go编写操作系统并非不可能。不过,编写可供普通用户使用的非小型操作系统几乎不可能。编写一个在单一架构上启动并进入shell的操作系统很容易,但是使用Go编写一个在多种架构上运行、支持不同设备(如显卡或网卡)并且可能符合POSIX的操作系统将非常具有挑战性。当然一些特性可以省略,但这会限制操作系统的可行性。

使用Go编写的操作系统

虽然Go不是最适合操作系统开发的选择,但这并不意味着使用Go编写操作系统是不可能的,许多研究项目正在探索如何做到这一点。

Biscuit 是使用Go编写的操作系统,在64位X86架构上运行。它使用经过修改的Go 1.10运行时实现,其中添加了更多汇编代码来处理系统调用和中断处理程序的引导和进入/退出。使用汇编编写的引导块加载Go运行时和“shim”层。Go运行时期望与底层内核通信来提供各种功能。由于没有底层内核,“shim”层提供了这些功能。

Biscuit为用户进程提供POSIX接口,支持fork、exec等。它实现了支持核心POSIX文件系统调用的文件系统。Biscuit为使用Go编写的Intel PCI-Express以太网NIC实现了TCP/IP堆栈和驱动程序。使用POSIX接口,Biscuit可以在不修改源代码的情况下运行许多Linux C程序。

不过,Biscuit缺少许多功能,例如调度优先级、换出页面或磁盘,以及许多安全功能,例如用户、访问控制列表和地址空间随机化。

有关Biscuit的更多详细信息,请参阅白皮书

gopher-os是另一个使用Go编写的概念验证内核。与Biscuit一样,它使用汇编来设置Go运行时和加载内核。不过,它仍处于开发的早期阶段,自2018年以来没有获得任何更新。它在最新版本的Go上也无法运作。

Clive是另一个使用Go编写的单内核操作系统,但它不在裸机上运行,并且使用经过修改的Go编译器来编译Clive软件。

gVisor是使用Go编写的应用程序内核,它在沙盒容器中实现Linux系统API。

结论

虽然C语言在操作系统开发中占主导地位,但Go提供了类型安全、自动内存管理和并发等特性,有潜力成为操作系统开发的绝佳选择。不过,由于缺乏对运行时和语言不同方面的微调控制,以及C语言的受欢迎程度,Go很难在操作系统开发领域站稳脚跟。但是,一些研究操作系统已经使用Go编写,我们可以期待在不久的将来使用Go编写用户友好型的操作系统。

参考文献:

  1. Biscuit: The Operating System from Scratch - https://www.usenix.org/system/files/osdi18-cutler.pdf
  2. Gopher-os: A Proof of Concept of an Operating System Written in Go - https://github.com/gopher-os/gopher-os
  3. Clive: A Single-User Operating System Written in Go - https://lsub.org/clive/
  4. gVisor: Application Kernel for Containers - https://github.com/google/gvisor

原创声明

======= ·

  • 原创作者: 猫头虎

作者wx: [ libin9iOak ]

  • 今日已学习

本文为原创文章,版权归作者所有。未经许可,禁止转载、复制或引用。

作者保证信息真实可靠,但不对准确性和完整性承担责任

未经许可,禁止商业用途。

如有疑问或建议,请联系作者。

感谢您的支持与尊重。

点击下方名片,加入IT技术核心学习团队。一起探索科技的未来,共同成长。

目录
相关文章
|
3天前
|
网络协议 网络安全 网络虚拟化
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算。通过这些术语的详细解释,帮助读者更好地理解和应用网络技术,应对数字化时代的挑战和机遇。
20 3
|
3天前
|
存储 网络协议 安全
30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场
本文精选了 30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场。
13 2
|
7天前
|
存储 人工智能 安全
操作系统的心脏——内核深度解析
【10月更文挑战第29天】 本文深入探讨了操作系统的核心组件——内核,包括其定义、功能、架构以及在现代计算中的重要性。通过对比不同操作系统内核的设计哲学和技术实现,揭示了内核如何影响系统性能、稳定性和安全性。此外,文章还讨论了未来内核技术的潜在发展方向,为读者提供了一个全面了解内核工作原理的平台。
|
5天前
|
存储 消息中间件 算法
深入探索操作系统的心脏——内核机制解析
本文旨在揭示操作系统核心——内核的工作原理,通过剖析其关键组件与机制,为读者提供一个清晰的内核结构图景。不同于常规摘要的概述性内容,本文摘要将直接聚焦于内核的核心概念、主要功能以及其在系统管理中扮演的角色,旨在激发读者对操作系统深层次运作原理的兴趣与理解。
|
6天前
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
20 3
|
8天前
|
Kubernetes Cloud Native 云计算
云原生技术深度解析:重塑企业IT架构的未来####
本文深入探讨了云原生技术的核心理念、关键技术组件及其对企业IT架构转型的深远影响。通过剖析Kubernetes、微服务、容器化等核心技术,本文揭示了云原生如何提升应用的灵活性、可扩展性和可维护性,助力企业在数字化转型中保持领先地位。 ####
|
9天前
|
自然语言处理 并行计算 数据可视化
免费开源法律文档比对工具:技术解析与应用
这款免费开源的法律文档比对工具,利用先进的文本分析和自然语言处理技术,实现高效、精准的文档比对。核心功能包括文本差异检测、多格式支持、语义分析、批量处理及用户友好的可视化界面,广泛适用于法律行业的各类场景。
|
3天前
|
存储 供应链 物联网
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景
|
3天前
|
存储 供应链 安全
深度解析区块链技术的核心原理与应用前景
深度解析区块链技术的核心原理与应用前景
10 0
|
9天前
|
开发工具 Android开发 数据安全/隐私保护
探索移动应用的世界:从开发到操作系统的全面解析
【10月更文挑战第33天】在数字化时代,移动应用已成为我们日常生活中不可或缺的一部分。本文将深入探讨移动应用的开发过程,包括编程语言、开发工具和框架的选择,以及如何构建用户友好的界面。同时,我们还将分析移动操作系统的核心功能和安全性,以帮助读者更好地理解这些应用程序是如何在各种设备上运行的。无论你是开发者还是普通用户,这篇文章都将为你揭示移动应用背后的奥秘。