rCore-Tutorial-Book-v3
rCore-Tutorial-Book-v3 copied to clipboard
rCore-Tutorial-Book-v3/chapter1/1app-ee-platform
应用程序执行环境与平台支持 — rCore-Tutorial-Book-v3 0.1 文档
https://rcore-os.github.io/rCore-Tutorial-Book-v3/chapter1/1app-ee-platform.html
有个疑问
编译器在将其通过编译、链接得到目标文件的时候
一个现代编译器的主要工作流程如下:
源代码(source code)→ 预处理器(preprocessor)→ 编译器(compiler)→ 汇编程序(assembler)→ 目标代码(object code)→ 链接器(linker)→ 可执行文件(executables),最后打包好的文件就可以给电脑去判读运行了。
有个疑问
编译器在将其通过编译、链接得到目标文件的时候
一个现代编译器的主要工作流程如下: 源代码(source code)→ 预处理器(preprocessor)→ 编译器(compiler)→ 汇编程序(assembler)→ 目标代码(object code)→ 链接器(linker)→ 可执行文件(executables),最后打包好的文件就可以给电脑去判读运行了。
这里“目标文件”的原意是“能在目标平台上执行的可执行文件”,但当时在写的时候没有注意到“目标文件”也有自身的含义,可能确实有点问题。在后续的更新中修改一下。
哦哦明白了
想问一下,程序不是可以直接编译成汇编语言吗?直接根据目标平台生成对应的汇编不可以吗?即使是调用了系统函数也是可以直接在裸机上运行吧?
@wangzhankun 在编写系统级软件之前需要确定它将会被运行在处理器的哪一特权级。就RV而言,如果是运行在M特权级的裸机应用的话,就可以直接执行;如果运行在S/U特权级的话,它们通常都需要以或直接(比如系统调用或 sbi call 需要通过 ecall
指令)、或间接的方式调用更高特权级软件提供的服务并被监管。事实上M特权级是必须存在的,取决于应用需求的不同可以有M或者M+U或者M+S+U这几种不同的特权级组合。
特权级的机制应该是操作系统实现的吧?对CPU而言,它看到的是源源不断的指令。如果是实现了特权级转换的话,那么一些系统调用应该也是已经实现了吧?那么再这种情况下直接调用系统函数也是可以的呀。据原文所述:
但目前我们所选的目标平台不存在任何操作系统支持,于是 Rust 并没有为这个目标平台支持完整的标准库 std。类似这样的平台通常被我们称为 裸机平台 (bare-metal)。
那么既然没有操作系统的支持,也就不存在特权级的转换吧?
@wangzhankun
特权级的机制应该是操作系统实现的吧?对CPU而言,它看到的是源源不断的指令。如果是实现了特权级转换的话,那么一些系统调用应该也是已经实现了吧?那么再这种情况下直接调用系统函数也是可以的呀。据原文所述:
但目前我们所选的目标平台不存在任何操作系统支持,于是 Rust 并没有为这个目标平台支持完整的标准库 std。类似这样的平台通常被我们称为 裸机平台 (bare-metal)。
那么既然没有操作系统的支持,也就不存在特权级的转换吧?
请阅读一下CPU手册吧。特权级别是CPU内置的实现,它通过识别指定寄存器上的标志位,来确定当前应该处于何种特权级别,而从硬件电路的实现上,就可以使某些机器指令失效或生效。
在某级别发生的异常、中断,只可以在该级别,或该级别更高的级别中去处理,比如U-mode的异常和中断可以在U-mode下自己解决,自己解决不了就可以交给S-mode下的操作系统去解决。而操作系统级别发生的异常和中断,只可以在S-mode和M-mode中解决。
再回答一下你更前面的疑问:
想问一下,程序不是可以直接编译成汇编语言吗?直接根据目标平台生成对应的汇编不可以吗?即使是调用了系统函数也是可以直接在裸机上运行吧?
既然是裸机,那根本不存在操作系统,也就不存在系统函数,所以也就没有“即使调用了系统函数也可以在裸机上直接运行”的说法。
Rust、C等编程语言的编译器,是可以把源代码经过编译、汇编、链接然后生成目标平台的机器码的(注意,是机器码,不是汇编程序)。只有01二进制的纯机器码才可以直接被高低电平表示,然后输入CPU,CPU内的电路就根据这些高低电平开始工作了。
真正从0编写操作系统,是少不了要写汇编代码的,要把系统的启动引导过程都实现(就不止是CPU自己上电了这么单一的事情),然后才是把控制权移交到OS层。
对rust生态不太了解,冒昧问一个小白问题: 我理解的是,对于架构的特权指令(比如Machine级别的指令)这部分应该只能用汇编来写,然后与rust编译出的目标文件(*.o)进行链接,组装成os内核Binary。 我想问的问题是,rust在进行操作系统开发的时候,生成目标文件这一步是用的什么工具链?也是用的gcc吗?因为rust编译器其实也是生成的llvm的中间表示(LLVM-IR),再从LLVM-IR的字节码编译成gcc的汇编文件。最后经由gcc工具链进行目标文件生成和链接。
对rust生态不太了解,冒昧问一个小白问题: 我理解的是,对于架构的特权指令(比如Machine级别的指令)这部分应该只能用汇编来写,然后与rust编译出的目标文件(*.o)进行链接,组装成os内核Binary。 我想问的问题是,rust在进行操作系统开发的时候,生成目标文件这一步是用的什么工具链?也是用的gcc吗?因为rust编译器其实也是生成的llvm的中间表示(LLVM-IR),再从LLVM-IR的字节码编译成gcc的汇编文件。最后经由gcc工具链进行目标文件生成和链接。
@TuringKi 可以看此页面有关linker和LLVM的信息。
计算机科学中遇到的所有问题都可通过增加一层抽象来解决。
太帅了
目标平台换成 riscv64gc-unknown-none-elf时,std crate库无法对不存在的操作系统进行系统调用这意味着在裸机平台上的软件没有传统操作系统支持,只能直接访问硬件。
抽象层是好文明,不过我个人理解“计算机科学中遇到的所有问题都可通过增加一层抽象来解决”这句话应该更像是“计算机科学中遇到的所有问题都可通过增删抽象层来解决”的意思。
第二行“主要注意额是”应改为“主要注意的是”