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

在K210运行时卡死,但是在QEMU运行没事 #16

Closed
sunshine-lcc opened this issue May 6, 2021 · 5 comments
Closed

在K210运行时卡死,但是在QEMU运行没事 #16

sunshine-lcc opened this issue May 6, 2021 · 5 comments

Comments

@sunshine-lcc
Copy link

sunshine-lcc commented May 6, 2021

我修改了initcode,把init程序硬编码到了内核里面,为什么在初始化时获取当前目录的ename函数时
2021-05-06_10-21-08
紧接着会卡死在申请加锁这里呢?
2021-05-05_11-01-00
并且在QEMU下面没问题,只在K210下有问题
就是这样的
2021-05-05_12-18-32

@sunshine-lcc sunshine-lcc changed the title 启动到K210时卡死,但是QEMU没事 在K210运行时卡死,但是在QEMU运行没事 May 6, 2021
@AtomHeartCoder
Copy link
Contributor

由于磁盘缓冲层需要进程获取睡眠锁,因此文件系统的初始化是在initcode第一次将要离开内核时进行的,在kernel/proc.c中的代码如下。

// A fork child's very first scheduling by scheduler()
// will swtch to forkret.
void
forkret(void)
{
  static int first = 1;

  // Still holding p->lock from scheduler.
  release(&myproc()->lock);

  if (first) {
    // File system initialization must be run in the context of a
    // regular process (e.g., because it calls sleep), and thus cannot
    // be run from main().
    first = 0;
    fat32_init();
    myproc()->cwd = ename("/");
  }

  usertrapret();
}

fat32_init中才会初始化ecache.lock,请确保这个函数在ename之前进行。

@sunshine-lcc
Copy link
Author

由于磁盘缓冲层需要进程获取睡眠锁,因此文件系统的初始化是在initcode第一次将要离开内核时进行的,在kernel/proc.c中的代码如下。

// A fork child's very first scheduling by scheduler()
// will swtch to forkret.
void
forkret(void)
{
  static int first = 1;

  // Still holding p->lock from scheduler.
  release(&myproc()->lock);

  if (first) {
    // File system initialization must be run in the context of a
    // regular process (e.g., because it calls sleep), and thus cannot
    // be run from main().
    first = 0;
    fat32_init();
    myproc()->cwd = ename("/");
  }

  usertrapret();
}

fat32_init中才会初始化ecache.lock,请确保这个函数在ename之前进行。

感谢

@sunshine-lcc
Copy link
Author

由于磁盘缓冲层需要进程获取睡眠锁,因此文件系统的初始化是在initcode第一次将要离开内核时进行的,在kernel/proc.c中的代码如下。

// A fork child's very first scheduling by scheduler()
// will swtch to forkret.
void
forkret(void)
{
  static int first = 1;

  // Still holding p->lock from scheduler.
  release(&myproc()->lock);

  if (first) {
    // File system initialization must be run in the context of a
    // regular process (e.g., because it calls sleep), and thus cannot
    // be run from main().
    first = 0;
    fat32_init();
    myproc()->cwd = ename("/");
  }

  usertrapret();
}

fat32_init中才会初始化ecache.lock,请确保这个函数在ename之前进行。

那为什么在QEMU下面能正常运行,而K210不能呢?这两个平台好像都用到了这段代码

@AtomHeartCoder
Copy link
Contributor

在K210上,内存的初始情况是未知的,而QEMU则可能事先将内存清零了,所以锁的未初始化状态可能不同。
由于在FAT32上并不实际存在根目录的目录项(目录项是存放在父目录中的,而根目录没有父目录),因此ename("/")并没有真正访问磁盘,而是直接返回它在内存中的静态数据结构。而根目录的结构体会被fat32_init()初始化,所以即使你先拿到根目录的结构体,再进行初始化,或许也能使文件系统继续运行下去。

@sunshine-lcc
Copy link
Author

在K210上,内存的初始情况是未知的,而QEMU则可能事先将内存清零了,所以锁的未初始化状态可能不同。
由于在FAT32上并不实际存在根目录的目录项(目录项是存放在父目录中的,而根目录没有父目录),因此ename("/")并没有真正访问磁盘,而是直接返回它在内存中的静态数据结构。而根目录的结构体会被fat32_init()初始化,所以即使你先拿到根目录的结构体,再进行初始化,或许也能使文件系统继续运行下去。

受教了感谢!

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

No branches or pull requests

3 participants