rCore-Tutorial-Book-v3 icon indicating copy to clipboard operation
rCore-Tutorial-Book-v3 copied to clipboard

rCore-Tutorial-Book-v3/chapter3/1multi-loader

Open utterances-bot opened this issue 3 years ago • 9 comments

多道程序放置与加载 — rCore-Tutorial-Book-v3 0.1 文档

https://rcore-os.github.io/rCore-Tutorial-Book-v3/chapter3/1multi-loader.html

utterances-bot avatar Aug 07 '21 15:08 utterances-bot

我在切换到ch3-coop的时候(ch3之后的应该都会有),多了一个toolchain文件,其中设置rust 工具链版本为nightly-2022-01-19,是文件夹目录下的override,会导致rust-analyzer报错 具体是执行cargo之后出现: error: the 'cargo' binary, normally provided by the 'cargo' component, is not applicable to the 'nightly-2022-01-19-x86_64-unknown-linux-gnu' toolchain 执行rustup upgrade,并执行rustup component remove cargo、rustup component add cargo之后可解决

yxd0379 avatar Apr 08 '22 06:04 yxd0379

尝试着改造自己的内核成多道程序加载执行,然后对于最后的执行,把用户栈改造成多个栈供用户程序使用,然后run_next_app关于restore程序传入,改造成如下代码

__restore(
    KERNEL_STACK.push_context(TrapContext::app_init_context(
        APP_BASE_ADDRESS + current_app * APP_SIZE_LIMIT,
        USER_STACK[current_app].get_sp(),
    )) as *const _ as usize,
);

然后执行到第二个程序就开始报错

Loaded app 0 within 0x80400000 to 0x804014B0
Loaded app 1 within 0x80420000 to 0x80421558
Loaded app 2 within 0x80440000 to 0x80441720
Loaded app 3 within 0x80460000 to 0x80461540
Loaded app 4 within 0x80480000 to 0x80481AD8
Loaded app 5 within 0x804A0000 to 0x804A1BC0
[kernel] Running app_0
Entry: 0x80400000
UserStack: 0x80207000
syswrite buf: 0x80400F28
Hello, world!
[kernel] Application exited with code 0
[kernel] Running app_1
Entry: 0x80420000
UserStack: 0x80208000
syswrite buf: 0x80207F30
Panicked at src/syscall/fs.rs:15 called `Result::unwrap()` on an `Err` value: Utf8Error { valid_up_to: 3, error_len: Some(1) }

完全不知道哪里出了问题...

SnowWarri0r avatar Aug 01 '22 02:08 SnowWarri0r

本来以为我解决了这个问题,没想到最后还是没解决... 麻了,我跟上面这位老哥基本是以相同的方式操作的,只不过我的源程序是模块化的,所以说比较怪异 输出:

[ INFO] [kernel] num_app = 12
[ INFO] All application has been linked at this location( in memory )
[ INFO] [kernel] app_0 [0x80400000, 0x80420000)
[ INFO] [kernel] app_1 [0x80420000, 0x80440000)
[ INFO] [kernel] app_2 [0x80440000, 0x80460000)
[ INFO] [kernel] app_3 [0x80460000, 0x80480000)
[ INFO] [kernel] app_4 [0x80480000, 0x804a0000)
[ INFO] [kernel] app_5 [0x804a0000, 0x804c0000)
[ INFO] [kernel] app_6 [0x804c0000, 0x804e0000)
[ INFO] [kernel] app_7 [0x804e0000, 0x80500000)
[ INFO] [kernel] app_8 [0x80500000, 0x80520000)
[ INFO] [kernel] app_9 [0x80520000, 0x80540000)
[ INFO] [kernel] app_10 [0x80540000, 0x80560000)
[ INFO] [kernel] app_11 [0x80560000, 0x8026d6a8)
[DEBUG] KERNEL_STACK:8020D000
[DEBUG] USER_STACK:8020E000
[DEBUG] you are now loading application:1
[DEBUG] restore to address in :80400000
[DEBUG] USER_STACK.get_sp:8020E000
Hello, world!
[ INFO] [kernel] Application exited with code 0
[DEBUG] you are now loading application:2
[DEBUG] restore to address in :80420000
[DEBUG] USER_STACK.get_sp:8020E000
[ERROR] [kernel] IllegalInstruction in application, core dumped.
[ INFO] exit and run next application:
[DEBUG] you are now loading application:3
[DEBUG] restore to address in :80440000
[DEBUG] USER_STACK.get_sp:8020E000
[ERROR] unsupported trap
Panicked at trap/src/lib.rs:53 Unsupported trap Exception(LoadFault), stval = 0x0!

其他乱七八糟的东西

pub fn run_next_app() -> ! {
    let mut app_manager = APP_MANAGER.exclusive_access();
    
    let current_app = app_manager.get_current_app();
    if current_app == app_manager.num_app {
        // debug!("inside");
        panic!("all application has been run successed");
    }
    // copy app instruction to APP_BASR_ADDRESS
    app_manager.set_current_app(current_app + 1);
    let next_app_num = current_app + 1;
    let next_ptr = app_manager.app_start[current_app];
    drop(app_manager);
    // before this we have to drop local variables related to resources manually
    // and release the resources
    debug!("you are now loading application:{}",next_app_num);
    debug!("restore to address in :{:x}", next_ptr);
    debug!("USER_STACK.get_sp:{:X}", USER_STACK.get_sp());
    extern "C" {
        fn __restore(cx_addr: usize);
    }
    unsafe {
        // push TrapContext into kernelStack
        __restore(KERNEL_STACK.push_context(TrapContext::app_init_context(
            next_ptr, 
            USER_STACK.get_sp(),
        )) as *const _ as usize)
    }
    panic!("Unreachable in batch::run_current_app!");
}
lazy_static! {
    // UPSafeCell: prevent multi borrows
    static ref APP_MANAGER: UPSafeCell<AppManager> = unsafe {
        UPSafeCell::new({
            extern "C" {
                // static mut _num_app: u64;
                fn _num_app();
            }
            // get _num_app
            let num_app_ptr = _num_app as usize as *const usize;
            // read number of "should run" apps 
            let num_app = num_app_ptr.read_volatile();
            // array stores the start address of app
            let mut app_start: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1];
            // read address of app from _num_app, should from [1..?]
            let app_start_raw: &[usize] =
            core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1);
            // app_start[0..num_app] stores app start addresses
            app_start[..=num_app].copy_from_slice(app_start_raw);
            
            // before this line we have successed load all application in the location of app_start
            // and all application has been load in the address start from 0x80218790?
            // so we just load it in the address from 0x8400000
            // core::arch::asm!("fence.i");

            // load application in memory
            for i in 0..num_app {
                let base_i = APP_BASE_ADDRESS + i * APP_SIZE_LIMIT;
                // the app_start[i] here is stand for the location where they has been load in memeory now
                loader::load_app(app_start[i], app_start[i+1], base_i);// 将app_start[i]~app_start[i+1]的内容装载到base_i的位置上
                // update app_start
                app_start[i] = base_i;
            }

            // store infos into AppManager
            AppManager {
                num_app,
                current_app: 0,
                app_start,
            }
        })
    };
}

jackyliu16 avatar Aug 17 '22 07:08 jackyliu16

docs error: 最后一段执行应用程序处,应为sepc而非epc寄存器

jackyliu16 avatar Aug 24 '22 06:08 jackyliu16

@SnowWarri0r @jackyliu16 我也有这个问题,后来发现是我的user程序的起始地址有问题,以前是固定的0x80400000,而这一章需要是不同的地址。我不知道你们是不是这个问题。

renranwuyue avatar Sep 02 '22 09:09 renranwuyue

@SnowWarri0r @jackyliu16 我也有这个问题,后来发现是我的user程序的起始地址有问题,以前是固定的0x80400000,而这一章需要是不同的地址。我不知道你们是不是这个问题。

我想应该不是这个原因,写的时候我人工deprecated了原先版本中由APP_MANAGER提供的load_app(i)函数,并且将原先的这个load模块中与APP_BASE_ADDRESS相关的内容全部替换成为了APP_BASE_ADDRESS+app_id * APP_SIZE_LIMIT的这种类型的操作,并且通过extern "C" { fn _num_app(); }在初始化阶段完成了对应程序的装载操作,除了我仍使用原来提供的__restore函数来达成切换当前正在运行的程序以外,我似乎没有任何有关于引起程序没有办法正常加载的想法。

jackyliu16 avatar Sep 02 '22 09:09 jackyliu16

@SnowWarri0r @jackyliu16 使用cargo clean清理user程序,然后使用build.py重新编译生成user程序。cargo build 貌似不会跟踪ld文件改动。

rainsmell avatar Feb 02 '23 08:02 rainsmell

与第二章相同,所有应用的 ELF 格式执行文件都经过 objcopy 工具丢掉所有 ELF header 和符号变为二进制镜像文件,随后以同样的格式通过在操作系统内核中嵌入 link_user.S 文件,在编译时直接把应用链接到内核的数据段中。

多道程序放置一节中此处的link_user.S是否应为link_app.S?

xukp20 avatar Feb 20 '23 11:02 xukp20