Linux 内核--任务0的调度切换
Linux 内核--任务0的调度切换
本文分析基于Linux 0.11内核,main.c中在move_to_user_mode()之后,切换到用户模式下运行,task0然后执行fork()创建进程task1来执行init()函数。init()函数如下:
- void init (void)
- {
- int pid, i;
- // 读取硬盘参数包括分区表信息并建立虚拟盘和安装根文件系统设备。
- // 该函数是在25 行上的宏定义的,对应函数是sys_setup(),在kernel/blk_drv/hd.c,71 行。
- setup ((void *) &drive_info);
- (void) open ("/dev/tty0", O_RDWR, 0); // 用读写访问方式打开设备“/dev/tty0”,
- // 这里对应终端控制台。
- // 返回的句柄号0 -- stdin 标准输入设备。
- (void) dup (0); // 复制句柄,产生句柄1 号 -- stdout 标准输出设备。
- (void) dup (0); // 复制句柄,产生句柄2 号 -- stderr 标准出错输出设备。
- printf ("%d buffers = %d bytes buffer space\n\r", NR_BUFFERS, NR_BUFFERS * BLOCK_SIZE); // 打印缓冲区块数和总字节数,每块1024 字节。
- printf ("Free mem: %d bytes\n\r", memory_end - main_memory_start); //空闲内存字节数。
- // 下面fork()用于创建一个子进程(子任务)。对于被创建的子进程,fork()将返回0 值,
- // 对于原(父进程)将返回子进程的进程号。所以180-184 句是子进程执行的内容。该子进程
- // 关闭了句柄0(stdin),以只读方式打开/etc/rc 文件,并执行/bin/sh 程序,所带参数和
- // 环境变量分别由argv_rc 和envp_rc 数组给出。参见后面的描述。
- if (!(pid = fork ()))
- {
- close (0);
- if (open ("/etc/rc", O_RDONLY, 0))
- _exit (1); // 如果打开文件失败,则退出(/lib/_exit.c,10)。
- execve ("/bin/sh", argv_rc, envp_rc); // 装入/bin/sh 程序并执行。
- _exit (2); // 若execve()执行失败则退出(出错码2,“文件或目录不存在”)。
- }
- // 下面是父进程执行的语句。wait()是等待子进程停止或终止,其返回值应是子进程的进程号(pid)。
- // 这三句的作用是父进程等待子进程的结束。&i 是存放返回状态信息的位置。如果wait()返回值不
- // 等于子进程号,则继续等待。
- if (pid > 0)
- while (pid != wait (&i))
- /* nothing */ ;
- // 如果执行到这里,说明刚创建的子进程的执行已停止或终止了。下面循环中首先再创建一个子进程,
- // 如果出错,则显示“初始化程序创建子进程失败”的信息并继续执行。对于所创建的子进程关闭所有
- // 以前还遗留的句柄(stdin, stdout, stderr),新创建一个会话并设置进程组号,然后重新打开
- // /dev/tty0 作为stdin,并复制成stdout 和stderr。再次执行系统解释程序/bin/sh。但这次执行所
- // 选用的参数和环境数组另选了一套(见上面165-167 行)。然后父进程再次运行wait()等待。如果
- // 子进程又停止了执行,则在标准输出上显示出错信息“子进程pid 停止了运行,返回码是i”,然后
- // 继续重试下去…,形成“大”死循环。
- while (1)
- {
- if ((pid = fork ()) < 0)
- {
- printf ("Fork failed in init\r\n");
- continue;
- }
- if (!pid)
- {
- close (0);
- close (1);
- close (2);
- setsid ();
- (void) open ("/dev/tty0", O_RDWR, 0);
- (void) dup (0);
- (void) dup (0);
- _exit (execve ("/bin/sh", argv, envp));
- }
- while (1)
- if (pid == wait (&i))
- break;
- printf ("\n\rchild %d died with code %04x\n\r", pid, i);
- sync ();
- }
- _exit (0); /* NOTE! _exit, not exit() */
- }
|
评论暂时关闭