Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支持glibc静态编译链接的vfork.c , init.c , helloworld.c,每个app都有自己的地址空间 #2

Open
wants to merge 13 commits into
base: dev
Choose a base branch
from

Conversation

xhyf77
Copy link

@xhyf77 xhyf77 commented Jun 27, 2024

运行效果:
b6cd27a26ea3689db7b5781cc8fd8bc2

我认为的几个bug
1.默认使用gp寄存器指向Task's SchedInfo,app跑起来的时候会修改gp寄存器导致程序运行时没法拿到当前task的sched info,因此我修改为全局静态变量CURRENT存储当前TASK’s的SchedInfo
2.pt_regs_addr()函数原来是

    pub fn pt_regs_addr(&self) -> usize {
        self.kstack.as_ref().unwrap().top() - align_down(TRAPFRAME_SIZE, STACK_ALIGN)
    }

但是由于align_down导致减去的值不是TRAPFRAME_SIZE
但在汇编中却是用self.kstack.as_ref().unwrap().top() 直接减去TRAPFRAME_SIZE
如下:

.Ltrap_entry_s:
    addi    sp, sp, -{trapframe_size}
    SAVE_REGS 0
    mv      a0, sp
    auipc   a1, 0          # Load the upper 20 bits of the PC into a1
    addi    a1, a1, 12
    call    riscv_trap_handler
    RESTORE_REGS 0
    sret

.Ltrap_entry_u:
    addi    sp, sp, -{trapframe_size}
    SAVE_REGS 1
    mv      a0, sp
    li      a1, 1
    call    riscv_trap_handler
    addi    t0, sp, {trapframe_size}    // put supervisor sp to scratch
    csrw    sscratch, t0
    RESTORE_REGS 1
    sret

因此在rust中是用pt_regs_addr()获取trap_frame地址然后进行读写操作是和汇编里面的存储位置不匹配。

3.不知道是不是因为静态链接的原因,我这边测试后argc,argv,env按照下图摆放app可以成功接收到参数(和ppt不一样)
image

4.对syscall的fileops的writev进行了修改,使得可以正常输出。
原本的如下

pub fn writev(fd: usize, iov_array: &[iovec]) -> usize {
    assert!(fd == 1 || fd == 2);
    for iov in iov_array {
        debug!("iov: {:#X} {:#X}", iov.iov_base, iov.iov_len);
        let bytes = unsafe { core::slice::from_raw_parts(iov.iov_base as *const _, iov.iov_len) };
        let s = String::from_utf8(bytes.into());
        error!("{}", s.unwrap());
    }
    iov_array.len()
}

修改后

pub fn writev(fd: usize, iov_array: &[iovec]) -> usize {
    assert!(fd == 1 || fd == 2);
    let mut total_bytes_written = 0;
    for iov in iov_array {
        //debug!("iov: {:#X} {:#X}", iov.iov_base, iov.iov_len);
        let bytes = unsafe { core::slice::from_raw_parts(iov.iov_base as *const _, iov.iov_len) };
        let s = String::from_utf8(bytes.into());
        early_console::write_bytes(bytes);
        total_bytes_written += iov.iov_len;
    }
    total_bytes_written
}

修改前的writev返回值不对

未解决的bug(但最后想办法绕过了):
之前群里说的关于给task.mm赋值后会导致原页面回收(Arc指针计数并没有到0)

@xhyf77 xhyf77 changed the title 支持glibc静态编译链接的vfork.c , init.c , helloworld.c 支持glibc静态编译链接的vfork.c , init.c , helloworld.c,每个app都有自己的地址空间 Jun 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant