在riscv上电时,会进行CPU自检,然后跳转到bootloader处执行。bootloader设置好kernel的运行环境后,从硬盘加载kernel到内存,最后再跳转到kernel入口地址。

我们采用的bootloader为OpenSBI,被加载到0x80000000地址,OpenSBI探测好外设并初始化内核的环境变量后,加载内核到0x80200000地址,最后再跳转到0x80200000地址。从上文我们知道,我们的入口点_start地址正好为0x80200000,也就是OpenSBI会调用我们kernel的_start函数。

在riscv64中,有如下几种特权级:

User模式:该特权模式为权限最小的模式,在linux系统中用户态就运行在该特权级;

Supervisor模式:该特权级时linux操作系统运行的模式,特权级别比User模式高;

Machine模式:CPU上电启动后运行在该特权模式,该特权比Supervisor更高。

从 U 到 S 再到 M,权限不断提高,这意味着你可以使用更多的特权指令,访需求权限更高的寄存器等等。我们可以使用一些指令来修改 CPU 的当前特权级

riscv64 的 M ModeM-mode(机器模式,缩写为 M 模式)是 RISC-V 中 hart(hardware thread,硬件线程)可以执行的最高权
限模式。在 M 模式下运行的 hart 对内存,I/O 和一些对于启动和配置系统来说必要的底层功能有着完全的
使用权。riscv64 的 S ModeS-mode(监管者模式,缩写为 S 模式)是支持现代类 Unix 操作系统的权限模式,支持现代类 Unix 操作系
统所需要的基于页面的虚拟内存机制是其核心。

OpenSBI运行在Machine模式,当跳转到kernel地址0x80200000执行时,会切换到Supervisor模式执行。

在我们之前的 _start() 代码中只执行了loop,也就是无限循环,没有做任何实质的操作。现在我们需要添加不同的功能,因此就需要设置一下kernel内核的运行环境。这个运行环境我们首先需要设置的是内核堆栈,在rust函数调用时会使用到这个堆栈,如果我们不设置sp的地址,那么就可能使用sp指向的任何地址,这将给程序带来意想不到的后果。

由于riscv64的sp地址不能通过rust语言设置,因此这部分的环境变量就需要在汇编程序下设置:

# src/boot/entry_riscv64.asm.section .text.entry.global _start
_start:la sp, bootstacktopcall rust_main.section .bss.stack.align 12.global bootstack
bootstack:.space 4096 * 4.global bootstacktop
bootstacktop:

_start 程序放在 .text.entry 这个段中,我们链接脚本中将 .text.entry 放在了.text 段的第一个位置,也就是将_start函数放在了.text的第一个位置。

在_start开始处,将堆栈的顶部地址加载到sp寄存器中,并且堆栈的大小为16k,然后调用rust_main函数。

在main.rs中,我们将_start函数删除,并且添加rust_main函数。

#![no_main]
#![no_std]use core::panic::PanicInfo;#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {loop{}
}#[no_mangle]
extern "C" fn rust_main() -> ! {loop{}
}

为了支持汇编代码,我们需要开启global_asm特性,因此我们在main.rs中开启该特性,并包含src/boot/entry_riscv64.asm汇编代码:

#![no_main]
#![no_std]use core::panic::PanicInfo;#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {loop{}
}#![feature(global_asm)]
global_asm!(include_str!("boot/entry_riscv64.asm"));#[no_mangle]
extern "C" fn rust_main() -> ! {loop{}
} 

注意,上面中我们将汇编特性代码添加在panic_handler下面,此时会报错:

error: an inner attribute is not permitted in this context--> src/main.rs:11:1|
11 | #![feature(global_asm)]| ^^^^^^^^^^^^^^^^^^^^^^^|= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them.error[E0658]: use of unstable library feature 'global_asm': `global_asm!` is not stable enough for use and is subject to change--> src/main.rs:13:1|
13 | global_asm!(include_str!("boot/entry_riscv64.asm"));| ^^^^^^^^^^|= note: see issue #35119 <https://github.com/rust-lang/rust/issues/35119> for more information= help: add `#![feature(global_asm)]` to the crate attributes to enableerror: aborting due to 2 previous errorsFor more information about this error, try `rustc --explain E0658`.
error: could not compile `rust_os`.

这里显示错误的原因为global_asm是不稳定的功能,需要使用nightly来编译程序。但我们此时已经是使用nightly了。正真的原因是#![feature(global_asm)]特性代码放在了panic_handler代码的后面,解决的办法是#![feature(global_asm)]特性必须放在文件开头的位置,修改后的代码如下:

#![no_main]
#![no_std]
#![feature(global_asm)]use core::panic::PanicInfo;#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {loop{}
}global_asm!(include_str!("boot/entry_riscv64.asm"));#[no_mangle]
extern "C" fn rust_main() -> ! {loop{}
} 

此时可以编译通过了。

vue-video-player修改src就会报错_4、修改入口点代码相关推荐

  1. vue 安装 less_解决旧Vue项目升级less-loader 6.0.0报错

    作为一个爱折腾的主,我的package随时都是ncu -u! 何为ncu,就是检查nodejs npm/yarn项目依赖最新版本package.json一个插件! 这不,前几天less-loader ...

  2. SAP QM QE02 修改检验结果,报错 -No characteristics were found–

    SAP QM QE02 修改检验结果,报错 -No characteristics were found– 已经执行完事务代码QE01为检验批9000000208的0010工序录入好了检验结果. 试图 ...

  3. SAP PP使用ECR去修改Recipe主数据,报错:Generation not supported for change object

    SAP PP使用ECR去修改Recipe主数据,报错:Generation not supported for change object 项目上启用了ECM(Engineer Change Mana ...

  4. 10g数据库入门与实践 oracle_修改oracle数据文件大小 报错:ORA-03297

    修改oracle数据文件大小 报错:ORA-03297 数据库中SXSJ的表空间SXS文件在创建的时候由于达到最大块空间,增加了一个SXSJ1的数据文件,但是增加时直接给的文件大小是30G,过于占用空 ...

  5. .vue文件在webstorm中es6语法报错解决方法

    .vue文件在webstorm中es6语法报错解决方法 参考文章: (1).vue文件在webstorm中es6语法报错解决方法 (2)https://www.cnblogs.com/yuqing6/ ...

  6. vue项目初始化时npm run dev报错webpack-dev-server解决方法

    vue项目初始化时npm run dev报错webpack-dev-server解决方法 参考文章: (1)vue项目初始化时npm run dev报错webpack-dev-server解决方法 ( ...

  7. SAP修改消息内容和报错类型(OBA5,SE91)

    FI: oBA5|oFMG|oFPM MM: oMRM|oKZZ|oMT4|oMCQ|o04C| SD: oVAH(V4)|oVM1(VL) CO:  oPR4_ACT|oPR4_CK|oPR4_CK ...

  8. vue项目在vscode中编译eslint报错没显示红色波浪线提示

    vue项目在vscode中编译eslint报错没显示红色波浪线提示. 如下图所示: 下图是预期效果: 不符合Eslint校验规则的代码位置都能展示出来,这样一目了然.能帮助我们迅速找到报错的位置. 然 ...

  9. 解决:room无论如何怎么修改数据库版本都报错java.lang.IllegalStateException: Room cannot verify the data integrity

    问题描述 这已经是第二次遇到这个bug了,第一次卡了一两天,这次卡了半天. bug: java.lang.IllegalStateException: Room cannot verify the d ...

最新文章

  1. 每日站会要关注团队目标-Scrum中文网
  2. 数据结构 第三周第四周学习小结
  3. The Genymotion virtual device could not obtain an IP address
  4. Leetcode-937-Reorder Log Files-(Easy)
  5. Java-Map从入门到性能分析3【LinkedHashMap(性能耗时对比、模拟LRU缓存)、TreeMap(排序、性能对比)】
  6. 常用的SQLAlchemy列选项
  7. Scala中的延迟初始化(Lazy vals)
  8. 【前端】网页布局基础
  9. idea报错:Error:java: JDK isn‘t specified for module ‘xxx‘
  10. 笔记本AutoCAD启动时闪退怎么办_戴尔笔记本电脑开不了机如何解决【解决方法】...
  11. python文件例题_文件操作练习题
  12. ArrayList学习[常用方法|源码]
  13. 催眠与大脑的信息处理
  14. 点击出现遮罩层时滚动条会自己回到顶部_浅谈内容型信息流产品的“返回顶部”功能...
  15. Maven scope中import的作用
  16. 2021中国统计摘要
  17. 零基础使用 MATLAB 求解偏微分方程(建议收藏)
  18. eclipse卸载插件
  19. 合并下载ts流媒体视频
  20. 自动驾驶扎堆“重感知”路线:毫末智行如何从独行到领航?

热门文章

  1. centos mysql 互为主从_centos7 mysql互为主从+keepalived
  2. html5+shim脚本,HTML5探秘:用requestAnimationFrame优化Web动画
  3. R语言中dim函数_R语言--向量化计算(apply族函数)
  4. vue key重复_【第2112期】 import { reactive } from #39;vue#39;
  5. Linux基础命令(1)
  6. Linux下的一些简单网络配置命令介绍
  7. Give Candies【快速幂+欧拉】
  8. drbd(三):drbd的状态说明
  9. 形象易懂讲解算法I——小波变换
  10. 【转】unity地形插件T4M使用帮助