vue-video-player修改src就会报错_4、修改入口点代码
在riscv上電時(shí),會(huì)進(jìn)行CPU自檢,然后跳轉(zhuǎn)到bootloader處執(zhí)行。bootloader設(shè)置好kernel的運(yùn)行環(huán)境后,從硬盤(pán)加載kernel到內(nèi)存,最后再跳轉(zhuǎn)到kernel入口地址。
我們采用的bootloader為OpenSBI,被加載到0x80000000地址,OpenSBI探測(cè)好外設(shè)并初始化內(nèi)核的環(huán)境變量后,加載內(nèi)核到0x80200000地址,最后再跳轉(zhuǎn)到0x80200000地址。從上文我們知道,我們的入口點(diǎn)_start地址正好為0x80200000,也就是OpenSBI會(huì)調(diào)用我們kernel的_start函數(shù)。
在riscv64中,有如下幾種特權(quán)級(jí):
User模式:該特權(quán)模式為權(quán)限最小的模式,在linux系統(tǒng)中用戶態(tài)就運(yùn)行在該特權(quán)級(jí);
Supervisor模式:該特權(quán)級(jí)時(shí)linux操作系統(tǒng)運(yùn)行的模式,特權(quán)級(jí)別比User模式高;
Machine模式:CPU上電啟動(dòng)后運(yùn)行在該特權(quán)模式,該特權(quán)比Supervisor更高。
從 U 到 S 再到 M,權(quán)限不斷提高,這意味著你可以使用更多的特權(quán)指令,訪需求權(quán)限更高的寄存器等等。我們可以使用一些指令來(lái)修改 CPU 的當(dāng)前特權(quán)級(jí)。
riscv64 的 M ModeM-mode(機(jī)器模式,縮寫(xiě)為 M 模式)是 RISC-V 中 hart(hardware thread,硬件線程)可以執(zhí)行的最高權(quán) 限模式。在 M 模式下運(yùn)行的 hart 對(duì)內(nèi)存,I/O 和一些對(duì)于啟動(dòng)和配置系統(tǒng)來(lái)說(shuō)必要的底層功能有著完全的 使用權(quán)。riscv64 的 S ModeS-mode(監(jiān)管者模式,縮寫(xiě)為 S 模式)是支持現(xiàn)代類 Unix 操作系統(tǒng)的權(quán)限模式,支持現(xiàn)代類 Unix 操作系 統(tǒng)所需要的基于頁(yè)面的虛擬內(nèi)存機(jī)制是其核心。OpenSBI運(yùn)行在Machine模式,當(dāng)跳轉(zhuǎn)到kernel地址0x80200000執(zhí)行時(shí),會(huì)切換到Supervisor模式執(zhí)行。
在我們之前的 _start() 代碼中只執(zhí)行了loop,也就是無(wú)限循環(huán),沒(méi)有做任何實(shí)質(zhì)的操作。現(xiàn)在我們需要添加不同的功能,因此就需要設(shè)置一下kernel內(nèi)核的運(yùn)行環(huán)境。這個(gè)運(yùn)行環(huán)境我們首先需要設(shè)置的是內(nèi)核堆棧,在rust函數(shù)調(diào)用時(shí)會(huì)使用到這個(gè)堆棧,如果我們不設(shè)置sp的地址,那么就可能使用sp指向的任何地址,這將給程序帶來(lái)意想不到的后果。
由于riscv64的sp地址不能通過(guò)rust語(yǔ)言設(shè)置,因此這部分的環(huán)境變量就需要在匯編程序下設(shè)置:
# 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 這個(gè)段中,我們鏈接腳本中將 .text.entry 放在了.text 段的第一個(gè)位置,也就是將_start函數(shù)放在了.text的第一個(gè)位置。
在_start開(kāi)始處,將堆棧的頂部地址加載到sp寄存器中,并且堆棧的大小為16k,然后調(diào)用rust_main函數(shù)。
在main.rs中,我們將_start函數(shù)刪除,并且添加rust_main函數(shù)。
#![no_main] #![no_std]use core::panic::PanicInfo;#[panic_handler] fn panic(_info: &PanicInfo) -> ! {loop{} }#[no_mangle] extern "C" fn rust_main() -> ! {loop{} }為了支持匯編代碼,我們需要開(kāi)啟global_asm特性,因此我們?cè)趍ain.rs中開(kāi)啟該特性,并包含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下面,此時(shí)會(huì)報(bào)錯(cuò):
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`.這里顯示錯(cuò)誤的原因?yàn)間lobal_asm是不穩(wěn)定的功能,需要使用nightly來(lái)編譯程序。但我們此時(shí)已經(jīng)是使用nightly了。正真的原因是#![feature(global_asm)]特性代碼放在了panic_handler代碼的后面,解決的辦法是#![feature(global_asm)]特性必須放在文件開(kāi)頭的位置,修改后的代碼如下:
#![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{} }此時(shí)可以編譯通過(guò)了。
總結(jié)
以上是生活随笔為你收集整理的vue-video-player修改src就会报错_4、修改入口点代码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: arduino 蓝牙示例_Arduino
- 下一篇: linux中系统修复