侧边栏壁纸
  • 累计撰写 140 篇文章
  • 累计创建 21 个标签
  • 累计收到 3 条评论

目 录CONTENT

文章目录

操作系统底层入门:计算机启动、内核架构、用户态、内核态与系统调用

YaFuX
2023-10-02 / 0 评论 / 0 点赞 / 0 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

平时按下电脑电源键,几秒钟后就能看到登录界面。

这件事太熟悉了,以至于很少有人继续追问:

  • 刚通电时,内存里明明什么都没有,CPU 第一条指令从哪里来?
  • 操作系统还没启动,究竟是谁先控制 CPU?
  • BIOS 和 UEFI 到底是什么关系?
  • Bootloader 为什么能够把 Linux、Windows 这样的系统启动起来?
  • 网上经常说 Bootloader 在 MBR,并被加载到 0x7C00,现在的 UEFI 机器还是这样吗?
  • Linux 内核启动后,为什么普通 Java 程序不能直接操作硬盘、网卡和其他硬件?
  • 所谓用户态、内核态和 Ring 0、Ring 3,到底分别是什么?
  • 一次 Files.read()、一次 Socket 读取,Java 是怎样跨进内核的?
  • “进入内核态”是不是就意味着发生了一次线程上下文切换?

如果这些问题没有串起来,我们很容易把:

BIOS
UEFI
MBR
Bootloader
Kernel
Ring 0
System Call

记成几个孤立的面试名词。

实际上,它们描述的是一条非常完整的控制权转移链:

按下电源
CPU Reset
Firmware
Boot Manager / Bootloader
OS Kernel
初始化硬件与内存
启动用户空间
JVM / Java 进程
System Call

这篇文章不准备深入到“自己写一个 Bootloader”的程度,而是先把从按下电源一直到 Java 程序调用操作系统的完整路径建立起来。

一、CPU 上电后从哪里执行第一条指令?

操作系统存储在 SSD 或硬盘中。

而 CPU 想执行代码,首先必须知道:

从哪个地址取第一条指令?

问题是,此时操作系统甚至还没有加载到内存。

所以开机最早期必须存在一段:

不依赖已经运行的操作系统,就能够被 CPU 找到并执行的固件代码。

这就是 Firmware 所处的位置。

1. BIOS:传统固件如何接管启动?

在传统 IBM PC 兼容机体系中,最熟悉的固件就是:

BIOS
Basic Input/Output System

它负责完成一系列最早期工作,例如:

  • 建立最基本的硬件环境;
  • 初始化和检查必要设备;
  • 找到可启动设备;
  • 把控制权交给下一阶段启动代码。

传统资料经常把开机流程写成:

通电
 ↓
BIOS
 ↓
POST 自检
 ↓
读取磁盘第一个扇区
 ↓
Bootloader

对于 Legacy BIOS 启动,这个模型非常有价值。

2. UEFI:现代固件改变了什么?

现在 PC 上更常见的是:

UEFI
Unified Extensible Firmware Interface

经常有人把它理解成:

BIOS 是黑白界面,UEFI 是有鼠标、有彩色 GUI 的新版 BIOS。

界面变化只是最表面的一层。

UEFI 真正重要的变化,是它重新定义了固件:

  • 怎样描述启动项;
  • 怎样加载可执行的 EFI Image;
  • 怎样提供 Boot Services;
  • 怎样通过 NVRAM 保存 BootOrderBoot#### 等启动配置;
  • 怎样从文件系统中寻找 OS Loader。

所以更准确地说:

BIOS 与 UEFI 都承担“操作系统之前的固件启动环境”角色,但 UEFI 不是给 BIOS 换了一个图形界面,而是一套更现代的固件接口与启动规范。

二、BIOS 与 UEFI 是怎么启动系统的?

这是整篇文章最容易被旧资料误导的地方。

因为:

MBR
0x7C00
第一扇区

都是真的。

但它们主要描述的是Legacy BIOS 时代的启动路径

1. Legacy BIOS:从启动扇区开始

传统 x86 BIOS 启动模式下,可以用下面的模型理解:

BIOS 初始化
选择启动磁盘
读取启动扇区
把启动代码放到 0000:7C00
CPU 跳转到启动代码
Bootloader 继续加载更多内容
加载 OS Kernel

0x7C00 这个地址因此非常经典。

Linux 官方 x86 Boot Protocol 的历史布局里,也仍然明确保留了:

Boot sector entry point 0000:7C00

这个概念。

但是必须注意:

0x7C00 是 Legacy x86 Boot Sector 的经典入口,不是“所有现代操作系统内核固定加载地址”。

例如 Linux 的传统 bzImage 协议中,Protected-Mode Kernel 可以被装载到:

0x100000

也就是 1 MiB 位置。

所以不能把:

Boot Sector Entry = 0x7C00

继续推导成:

Linux Kernel Entry 永远 = 0x7C00

2. MBR:传统磁盘的启动入口

MBR 是:

Master Boot Record

传统 MBR 磁盘布局中,磁盘最开始的位置包含:

  • 引导代码;
  • 分区信息;
  • 签名等数据。

Legacy BIOS 可以读取其中的启动代码,然后交给它继续完成启动。

但这同样属于历史路径。

3. UEFI:从 NVRAM 到 EFI Loader

UEFI 的正常启动流程完全可以不执行传统 MBR Boot Code。

UEFI Firmware 自己拥有 Boot Manager。

启动项保存在 NVRAM 中,例如:

Boot0000
Boot0001
Boot0002
...
BootOrder

某个 Boot#### 项会指向:

硬件设备
   ↓
分区
   ↓
某个 EFI 可执行文件

例如 Linux 系统中的引导器可能位于 EFI System Partition。

一个更接近现代机器的流程是:

UEFI Firmware
读取 NVRAM BootOrder
选择 Boot####
定位 EFI System Partition
加载 EFI OS Loader
OS Loader 加载 Kernel / initramfs
Kernel 初始化

这和:

BIOS → MBR → 0x7C00

已经是两套不同的启动模型。

三、CMOS、NVRAM 与主板电池是什么关系?

旧 PC 资料里经常会说:

BIOS 配置存储在 CMOS 中,主板电池给 CMOS 供电。

这句话有很强的历史背景。

1. CMOS 为什么需要 RTC 电池?

早期 PC 需要保存:

  • 时间;
  • 日期;
  • 某些硬件配置;
  • 启动相关设置。

因此主板上会存在 RTC / CMOS 相关电路,并通过纽扣电池在断电后维持部分状态。

这也是为什么老机器电池没电以后经常出现:

时间归零
BIOS 设置丢失
启动配置恢复默认

2. UEFI 为什么还需要 NVRAM?

现代 UEFI 的:

BootOrder
Boot####

等变量属于 Firmware NVRAM 机制。

所以今天再写:

所有 BIOS/UEFI 设置都存放在 CMOS 芯片中,拔掉主板电池就一定能清空全部密码和配置。

并不严谨。

不同厂商可能采用:

  • NVRAM;
  • Flash;
  • RTC-backed 配置;
  • 安全存储;

等不同方式。

因此:

拔主板电池可能重置部分传统固件设置和 RTC,但不能把它当成所有现代 UEFI 密码、Secure Boot 配置和 Firmware Variable 的通用清除方案。

四、Bootloader 如何把系统启动起来?

Firmware 的任务不是把整个 Linux 运行起来。

它需要把控制权继续交给更了解操作系统格式的下一阶段。

这个角色通常由:

Bootloader / OS Loader

承担。

1. Bootloader 负责做什么?

假设磁盘上同时安装:

Windows
Linux

Firmware 并不需要理解:

  • Linux 的 Kernel Command Line;
  • initramfs;
  • Windows 内核的具体启动协议;
  • 各种文件系统和启动参数。

Bootloader / OS Loader 可以承担这些更具体的事情。

它大致负责:

确定要启动哪个系统
定位对应的 OS Loader / Kernel
准备启动参数与运行环境
加载 Kernel 与必要启动数据
把控制权交给 Kernel

2. Kernel 获得控制权后做什么?

当 Linux Kernel 获得控制权以后,还会继续:

Kernel Entry
CPU / Memory Early Init
Interrupt / Scheduler / Driver Init
挂载 initramfs
找到真正 Root Filesystem
启动 PID 1
systemd / init
启动系统服务
进入完整用户空间

所以:

Kernel 启动

和:

用户看到登录界面

中间还有很长一段系统初始化过程。

3. 开机过程中的控制权转移

把前几章连起来:

CPU Reset
Firmware 获得最初控制权
Boot Manager / Bootloader 接手
Kernel 获得控制权
Kernel 初始化系统资源
创建并管理 User Space
普通用户程序开始运行

这条链真正说明的是:

计算机启动不是某个程序突然“出现”,而是每一阶段先完成自己的初始化任务,再把执行权交给下一阶段。

最终,一台刚刚通电、几乎还没有软件运行环境的机器,才逐步变成能够运行 Java、浏览器、数据库等应用程序的完整系统。

五、操作系统与 Kernel 到底管理什么?

Kernel 启动以后,机器真正进入操作系统管理阶段。

操作系统可以先理解成夹在:

Application
     ↓
Operating System
     ↓
Hardware

中间的一层。

Java / Browser / Database
User Space API / Runtime
Kernel
CPU
Memory
Storage
Network
Other Devices

1. Kernel 如何管理硬件?

Kernel 需要管理:

  • CPU 调度;
  • 内存;
  • 中断;
  • 设备驱动;
  • 文件系统;
  • 网络;
  • 权限和隔离。

2. 操作系统如何给应用提供抽象?

应用程序不需要知道:

某块 NVMe SSD 的控制寄存器地址是多少?

Java 只需要:

Files.readAllBytes(path);

浏览器只需要:

打开文件
建立 Socket
分配内存
创建线程

Kernel 负责把这些高级需求映射到真实硬件。

所以操作系统最重要的价值之一,就是把:

完全不同的硬件

封装成:

稳定的软件接口

六、宏内核、微内核与外核有什么区别?

这部分很容易因为各种营销材料而产生误解。

先只讨论架构思想。

1. 宏内核:核心服务集中在内核空间

Linux 属于 Monolithic Kernel 路线。

一个简化模型:

Kernel Space
Scheduler
Memory Management
VFS / Filesystem
Network Stack
Device Drivers
IPC
User Space Applications
Hardware

这里的“宏”并不意味着:

所有代码永远焊死在一个文件里,完全不能模块化。

Linux 本身就支持 Loadable Kernel Module。

宏内核真正强调的是:

大量操作系统核心服务运行在同一个特权内核地址空间中,并可以通过直接函数调用高效协作。

优势:

  • 调用链短;
  • 性能高;
  • 内核组件之间协作直接。

代价:

  • 大量代码都处在高权限区域;
  • 内核 Bug 的影响范围可能更大。

2. 微内核:把更多服务移出内核

Microkernel 的思想则是:

只在内核里保留尽量少的关键机制,把更多服务放到用户空间进程中。

一个概念模型:

Microkernel
User Space
IPC
Scheduling
Low-level Memory / Protection
File System Server
Network Server
Driver Server
Application
Hardware

不同微内核究竟把哪些功能留在 Kernel 中并不完全一样。

所以“微内核只负责调度”也过于绝对。

更稳定的理解是:

Microkernel 尽量缩小高特权内核,把文件系统、驱动、网络等更多服务迁移到隔离的用户空间组件,通过 IPC 协作。

2.1 微内核不等于分布式系统

这也是一个很容易混淆的点。

Microkernel 的:

IPC + User-space Service

通常首先描述的是同一台机器内部的 OS 架构

服务是否通过网络跨设备运行,属于:

Distributed System / Distributed OS

层面的设计。

它们可以结合,但:

Microkernel ≠ 天生就是跨设备分布式操作系统

3. OpenHarmony 应该怎么理解?

一些早期资料把鸿蒙简单描述成:

一个纯微内核操作系统。

这个说法今天已经不能这样写。

当前 OpenHarmony 6.0 官方架构文档描述的是分层架构,并且 Kernel Subsystem 使用:

多内核设计,可根据设备选择 Linux Kernel 或 LiteOS。

同时整个系统支持按照设备资源:

裁剪组件

这部分确实体现了面向不同设备进行灵活部署的设计目标。

因此更合理的表述是:

OpenHarmony 是面向多设备场景的分层、可裁剪系统框架,其当前开源架构包含 Linux / LiteOS 多内核支持;不能简单把整个现代 OpenHarmony 等同于“一颗微内核”。

4. 外核:把更多策略交给应用

Exokernel 是更偏研究性的 OS 架构思想。

MIT Exokernel 的核心目标不是:

Kernel 帮应用提供越来越高级的抽象。

反而是:

Kernel 尽量只负责安全地复用和保护原始硬件资源,把更高级的抽象交给应用层的 Library OS。

模型更接近:

Application A
LibOS A
Application B
LibOS B
Exokernel
Raw Hardware Resources

这样不同应用可以根据需要自己决定:

  • 文件系统抽象;
  • 网络策略;
  • 内存资源管理方式。

它强调的是:

Protection 留在 Kernel
Policy / Abstraction 尽量交给 LibOS

而不是简单理解成“给 Office 写一个专用 Windows”。

5. VMM / Hypervisor 为什么不是内核分类?

Virtual Machine Monitor,也就是 Hypervisor,解决的是另一件事:

怎样让多个操作系统共享一台物理机器。

Physical Hardware
Hypervisor / VMM
Guest OS 1
Guest OS 2
Guest OS 3

所以:

Monolithic Kernel
Microkernel
Exokernel

讨论的是 OS Kernel Architecture。

而:

VMM / Hypervisor

讨论的是 Virtualization。

它们不是同一维度的三个并列“内核类型”。

七、为什么要区分用户态和内核态?

如果每一个普通程序都可以:

随便修改页表
随便关闭中断
随便改磁盘控制器寄存器
随便覆盖 Kernel 内存

系统根本无法稳定运行。

因此现代处理器和操作系统共同建立了:

Privilege Separation

也就是权限隔离。

1. 应用程序为什么不能直接控制硬件?

早期 x86 实模式环境里的程序拥有远高于现代用户程序的直接硬件控制能力。

这种自由的代价也很明显:

一个程序写错地址,就可能把整个系统一起带走。

现代操作系统则把:

Kernel

和:

Application

隔离开。

2. Ring 0 与 Ring 3 分别代表什么?

x86 体系结构定义了多个 Privilege Level,常用“环”表示:

Ring 0
Ring 1
Ring 2
Ring 3

可以建立最基础的直觉:

Ring 0 → 高特权
...
Ring 3 → 低特权

现代 x86 Linux 通常主要使用:

CPL 0 → Kernel
CPL 3 → User Space

Ring 1 和 Ring 2 通常不用来承载普通 Linux 用户进程。

但这里还有两个特别重要的区别。

2.1 CPU 特权级

它回答:

当前 CPU 正以什么特权级执行指令?

2.2 地址空间与保护

它回答:

哪些虚拟地址和资源允许谁访问?

两者高度相关,但不是完全同义词。

3. 用户态到底能直接做什么?

有一种常见说法:

应用程序读内存也必须切换 Ring 0。

这是错误的。

一个 Java 程序正常执行:

int x = array[10];

读取的是当前进程自己合法映射的 User Virtual Memory。

这完全可以在用户态完成。

真正需要 Kernel 参与的是:

  • 访问受保护硬件;
  • 文件 I/O;
  • 网络 I/O;
  • 创建或管理 OS 资源;
  • 修改受保护的内存映射;
  • 执行 Privileged Operation。

可以直接对比:

读取自己进程中的数组
User Mode 直接完成
读取磁盘文件
发起 System Call
Kernel 处理
文件系统 / Driver / Device

八、System Call:用户程序怎么进入内核?

现在终于到 Java 和操作系统真正接上的地方。

假设 Java 执行:

Files.readAllBytes(path);

JVM 自己并不会偷偷去控制 NVMe 控制器。

它必须借助操作系统。

1. Java 调用如何一路进入 Kernel?

一个简化流程:

Storage DeviceFilesystem / DriverLinux KernelCPUJDK / JVM Native RuntimeJava ApplicationStorage DeviceFilesystem / DriverLinux KernelCPUJDK / JVM Native RuntimeJava ApplicationFiles.read(...)准备 System CallUser Mode → Kernel ModeVFS / 文件系统处理发起设备 I/O数据完成返回结果Kernel Mode → User Mode返回 System Call 结果Java 得到数据

这就是 System Call 的价值:

Kernel 向 User Space 暴露一组受控入口,让普通程序能够请求高权限服务,而不是直接获得高权限。

2. 常见 System Call 有哪些?

Linux 中可以看到很多系统调用,例如:

read
write
openat
mmap
futex
socket
accept
sendfile
clone
...

不要背:

Linux 一共有 200 多个系统调用。

系统调用表会随着:

  • Kernel 版本;
  • CPU 架构;
  • ABI;

变化。

Linux 官方文档甚至在介绍新增 System Call 时,要求直接修改对应架构的:

syscall_64.tbl
syscall_32.tbl

所以系统调用“总数”并不是一个值得记忆的固定常量。

3. fork 为什么不是创建 Java 线程?

这是另一个常见混淆。

fork

传统语义是创建新进程。

Linux 上 Native Thread 的创建通常会经过:

pthread
   ↓
clone / clone3 等 Kernel 机制

Java Platform Thread 再通过 JVM 与本地线程运行时映射到 OS 线程。

这部分涉及:

进程
线程
调度
上下文切换
虚拟线程

属于下一阶段内容,这里先不展开。

九、Mode Switch 与 Context Switch 有什么区别?

不是。

这是用户态 / 内核态最容易产生的误区之一。

1. System Call 为什么会发生 Mode Switch?

当前线程:

Thread A

执行:

User Mode
   ↓
System Call
   ↓
Kernel Mode
   ↓
处理请求
   ↓
返回
   ↓
User Mode

整个过程中仍然可能一直是:

Thread A

只不过 CPU 的执行特权级发生了变化。

所以:

Mode Switch

不等于:

Context Switch

2. 什么情况下才会发生 Context Switch?

假设 Thread A 调用:

read()

数据还没准备好。

Kernel 可能让它进入等待状态:

Thread A
   ↓
System Call
   ↓
等待 I/O
   ↓
Scheduler
   ↓
切换到 Thread B

这时候才进一步发生真正的线程调度 / Context Switch。

因此完整关系应该是:

Yes
No
User Mode Thread A
System Call
Kernel Mode Thread A
可以立即完成?
返回 User Mode Thread A
Thread A 阻塞
Scheduler
Context Switch 到其他线程

这个区别非常重要,因为很多性能文章一看到:

System Call

就直接等同于:

线程切换

这是不准确的。

十、JVM 在操作系统中处于哪一层?

从 Linux 看,JVM 不是特殊的“第二操作系统”。

执行:

java MyApplication

之后,本质上仍然创建了一个普通 User-Space Process。JVM 可以在这个进程内部继续构建 Java 自己的运行时抽象,但它并没有因此越过 Linux 的权限边界。

HotSpot 自己会:

  • 管理 Java Heap;
  • 管理 Class Metadata;
  • JIT 编译代码;
  • 管理 GC;
  • 管理 Java Thread / Virtual Thread;
  • 提供 Java Runtime。

但它没有因此获得:

Ring 0

权限。

可以画成:

Java Application
HotSpot JVM
Native Runtime / libc
Linux Kernel
Hardware

当 Java 只是:

int c = a + b;

JIT 编译后的机器码可以直接在 User Mode 执行。

但当 Java 执行:

文件 I/O
Socket I/O
内存映射
线程阻塞 / 唤醒

JVM / Native Runtime 就需要进入 Kernel 提供的接口。

因此这几层关系可以再画成:

Java Application
JDK API
HotSpot / Native Runtime
是否需要 OS 服务?
User Mode 中继续执行机器码
System Call
Linux Kernel
Filesystem / Network / Scheduler / Driver
Hardware

JVM 屏蔽了很多操作系统差异,但 JVM 自己仍然建立在操作系统之上。

十一、常见误区

1. 关于 BIOS / UEFI

误区 1:UEFI 就是带图形界面的 BIOS。

不准确。

UEFI 是完整的 Firmware Interface 与 Boot Architecture,GUI 只是表面变化。

误区 2:现代电脑启动时一定先执行 MBR 第一扇区。

错误。

这描述的是 Legacy BIOS 典型路径。原生 UEFI 启动可以通过 NVRAM Boot Option 直接定位 EFI Image。

误区 3:操作系统 Kernel 固定加载到 0x7C00

错误。

0x7C00 是 Legacy x86 Boot Sector 经典入口地址,不是现代 Kernel 的统一装载地址。

2. 关于 CMOS

误区 4:所有 UEFI 配置都保存在 CMOS,拔电池一定能清空。

不准确。

现代 Firmware 可能使用 NVRAM / Flash 等方式保存变量。主板电池与 RTC、历史 CMOS 配置密切相关,但不能把拔电池当成所有机器的统一清除方案。

3. 关于内核架构

误区 5:Linux 是宏内核,所以所有功能完全不可拆分。

错误。

Linux 属于 Monolithic Kernel 路线,但同时支持大量模块化机制和 Loadable Kernel Module。

误区 6:微内核就是“只有一个调度器”。

过度简化。

不同 Microkernel 会保留不同最小机制,通常包括 IPC、Scheduling、Address-Space / Protection 等核心能力。

误区 7:微内核的服务天然可以跑到冰箱、电视等另一台设备上。

错误。

Microkernel 首先描述单机 OS 内部的服务隔离和 IPC。跨设备协作属于 Distributed System / Distributed OS 的另一层问题。

误区 8:OpenHarmony 就等于纯微内核。

不准确。

当前 OpenHarmony 官方架构采用多内核设计,根据设备类型支持 Linux Kernel 或 LiteOS,并提供分层、组件裁剪等能力。

误区 9:Exokernel 就是给每个应用定制一套普通操作系统。

不准确。

Exokernel 的核心是安全复用原始硬件资源,把高层抽象更多交给 LibOS / Application。

4. 关于用户态与系统调用

误区 10:Java 程序读取自己的内存也要切 Ring 0。

错误。

合法的 User Virtual Memory 可以直接在 User Mode 访问。

误区 11:sudo 让程序直接变成 Ring 0。

错误。

sudo 是操作系统的用户身份 / 权限控制工具。即便 UID 0 的用户程序,普通用户代码依然运行在 User Mode;真正执行特权指令的仍然是 Kernel。

误区 12:一次 System Call 一定等于一次线程 Context Switch。

错误。

System Call 必然涉及受控的用户态 / 内核态转换,但如果内核能立即处理并返回,不一定切换到另一个线程。

误区 13:Linux 固定只有 200 多个系统调用。

错误。

数量随架构、ABI 和 Kernel 版本变化,不需要背固定数字。

十二、从上电到 Java 程序的完整启动链

现在重新看一次完整过程。

Legacy BIOS
UEFI
No
Yes
按下电源
CPU Reset
Firmware 开始执行
启动模式
读取 Boot Sector / MBR 路径
Bootloader
读取 NVRAM BootOrder
加载 EFI OS Loader
加载 Kernel / initramfs
Kernel 获得控制权
初始化 CPU / Memory / Driver / Scheduler
挂载 Root Filesystem
启动 PID 1
进入 User Space
启动 java 进程
HotSpot JVM
执行 Java 代码
需要 Kernel 服务?
继续 User Mode 执行
System Call
Kernel Mode
Driver / FS / Network / Scheduler
返回 User Mode

这条链里发生了两次非常重要的“接管”。

第一次:

Firmware / Bootloader
        ↓
Kernel

意味着操作系统正式接管机器。

第二次:

Kernel
   ↓
User Space

意味着操作系统开始允许普通程序运行,但不会把最高硬件权限一起交给它们。

于是:

浏览器
数据库
JVM
Java 应用

都能安全共存。

十三、总结

开机并不是:

按电源
  ↓
操作系统突然出现

而是一层层加载、一层层转移控制权:

CPU Reset
   ↓
Firmware
   ↓
Boot Manager / Bootloader
   ↓
Kernel
   ↓
User Space
   ↓
JVM
   ↓
Java Application

Legacy BIOS 时代常见:

MBR + 0x7C00

而现代 UEFI 则更多依赖:

NVRAM Boot Option
+
EFI System Partition
+
EFI OS Loader

Kernel 启动以后,又通过 CPU 特权级和虚拟内存保护,把系统拆成:

Kernel Mode
User Mode

普通程序不能直接拥有硬件最高权限,只能通过:

System Call

进入 Kernel 提供的受控服务入口。

这也解释了 Java 和 Linux 真正的关系:

Java API
   ↓
JVM / JDK Native Runtime
   ↓
System Call
   ↓
Linux Kernel
   ↓
Driver / Hardware

从按下电源到运行一行 Java 代码,本质上是一场不断交接控制权的过程:Firmware 负责把系统带到 Bootloader,Bootloader 把控制权交给 Kernel,Kernel 建立用户空间和保护边界,而 JVM 最终作为普通用户态进程,通过 System Call 使用操作系统提供的硬件能力。

0

评论区