linux内核学习-3 init函数(关注新浪微博:寂寞侵蚀的岁月(4000多篇技术分享))

void init(void)

169 {

170 int pid,i;

171

172 setup((void *) &drive_info); // 读取硬盘参数包括分区表信息并建立虚拟盘和

// 安装根文件系统设备。(kernel/blk_drv/hd.c,71)

173 (void) open("/dev/tty0",O_RDWR,0); // 用读写访问方式打开设备“/dev/tty0”,

// 这里对应终端控制台。

// 返回的句柄号0 -- stdin 标准输入设备。

174 (void) dup(0); // 复制句柄,产生句柄1 号 -- stdout 标准输出设备。

175 (void) dup(0); // 复制句柄,产生句柄2 号 -- stderr 标准出错输出设备。

176 printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,

177 NR_BUFFERS*BLOCK_SIZE); // 打印缓冲区块数和总字节数,每块1024 字节。

178 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 数组给出。参见后面的描述。

179 if (!(pid=fork())) {

180 close(0);

181 if (open("/etc/rc",O_RDONLY,0))

182 _exit(1); // 如果打开文件失败,则退出(/lib/_exit.c,10)。

183 execve("/bin/sh",argv_rc,envp_rc); // 装入/bin/sh 程序并执行。

184 _exit(2);

185 }

// 下面是父进程执行的语句。wait()是等待子进程停止或终止,其返回值应是子进程的进程号(pid)。

// 这三句的作用是父进程等待子进程的结束。&i 是存放返回状态信息的位置。如果wait()返回值不

// 等于子进程号,则继续等待。

186 if (pid>0)

187 while (pid != wait(&i))

188 /* nothing */;

// 如果执行到这里,说明刚创建的子进程的执行已停止或终止了。下面循环中首先再创建一个子进程,

// 如果出错,则显示“初始化程序创建子进程失败”的信息并继续执行。对于所创建的子进程关闭所

// 以前还遗留的句柄(stdin, stdout, stderr),新创建一个会话并设置进程组号,然后重新打开

// /dev/tty0 作为stdin,并复制成stdout 和stderr。再次执行系统解释程序/bin/sh。但这次执行所

// 选用的参数和环境数组另选了一套(见上面165-167 行)。然后父进程再次运行wait()等待。如果

// 子进程又停止了执行,则在标准输出上显示出错信息“子进程pid 停止了运行,返回码是i”,然后

// 继续重试下去…,形成“大”死循环。

189 while (1) {

190 if ((pid=fork())<0) {

191 printf("Fork failed in init\r\n");

更多电子书教程下载请登陆http://down.zzbaike.com/ebook

本站提供的电子书教程均为网上搜集,如果该教程涉及或侵害到您的版权请联系我们。

第4 章 初始化程序 linux/init/

67

192 continue;

193 }

194 if (!pid) {

195 close(0);close(1);close(2);

196 setsid();

197 (void) open("/dev/tty0",O_RDWR,0);

198 (void) dup(0);

199 (void) dup(0);

200 _exit(execve("/bin/sh",argv,envp));

201 }

202 while (1)

203 if (pid == wait(&i))

204 break;

205 printf("\n\rchild %d died with code %04x\n\r",pid,i);

206 sync();

207 }

208 _exit(0);

}

时间: 2024-11-09 14:18:52

linux内核学习-3 init函数(关注新浪微博:寂寞侵蚀的岁月(4000多篇技术分享))的相关文章

linux内核学习-3 main函数(关注新浪微博:寂寞侵蚀的岁月(4000多篇技术分享))

#ifdef RAMDISK // 如果定义了虚拟盘,则主内存将减少. 124 main_memory_start += rd_init(main_memory_start, RAMDISK*1024); 125 #endif // 以下是内核进行所有方面的初始化工作.阅读时最好跟着调用的程序深入进去看,实在看 // 不下去了,就先放一放,看下一个初始化调用 -- 这是经验之谈?. 126 mem_init(main_memory_start,memory_end); 127 trap_init

linux内核学习-4kernal目录(关注新浪微博:寂寞侵蚀的岁月(4000多篇技术分享))

该目录下的代码文件从功能上可以分为三类,一类是硬件(异常)中断处理程序文件,一类是系统 调用服务处理程序文件,另一类是进程调度等通用功能文件.参见图1.5.我们现在根据这个分类方式, 从实现的功能上进行更详细的说明. 5.1.1.1 硬件中断处理类程序 主要包括两个代码文件:asm.s 和traps.c 文件.asm.s 用于实现大部分硬件异常所引起的中断的汇 编语言处理过程.而traps.c 程序则实现了asm.s 的中断处理过程中调用的c 函数.另外几个硬件中断 处理程序在文件system_

linux内核学习-5任务调度(关注新浪微博:寂寞侵蚀的岁月(4000多篇技术分享))

void schedule(void) 105 { 106 int i,next,c; 107 struct task_struct ** p; // 任务结构指针的指针. 108 109 /* check alarm, wake up any interruptible tasks that have got a signal */ /* 检测alarm(进程的报警定时值),唤醒任何得到信号的可中断任务 */ 110 // 从任务数组中最后一个任务开始检测alarm. 111 for(p =

linux内核学习-6信号量(关注新浪微博:寂寞侵蚀的岁月(4000多篇技术分享))

#include // 调度程序头文件,定义了任务结构task_struct.初始任务0 的数据,// 还有一些有关描述符参数设置和获取的嵌入式汇编函数宏语句.8 #include // 内核头文件.含有一些内核常用函数的原形定义.9 #include // 段操作头文件.定义了有关段寄存器操作的嵌入式汇编函数.1011 #include // 信号头文件.定义信号符号常量,信号结构以及信号操作函数原型.1213 volatile void do_exit(int error_code); //

Linux内核学习总结

李泽源 原创作品 转载请注明出处 <Linux内核分析>MOOC课程:http://mooc.study.163.com/course/USTC-1000029000 [Linux内核学习总结] 幸福来得很突然,这门课就快结束了…… 是时候,总结下这段时间的坚持了,也给同样对Linux内核有兴趣的你一个指南. 在这门课的学习过程中,按照老师的要求,每次课后都写一篇博文,这是一个很好的学习方式.每当写这些文章的时候,总是要多看几遍视频,再查查相关的资料,才能勉强凑成一个完整的文档:同时也把自己学

Linux内核学习--写一个c程序,并在内核中编译,运行

20140506 今天开始学习伟大的开源代表作:Linux内核.之前的工作流于几个简单命令的应用,因着对Android操作系统的情愫,"忍不住"跟随陈利君老师的步伐,开启OS内核之旅.学习路径之一是直接从代码入手,下面来写一个hello.c内核模块. 说明: 这个路径/usr/src/linux-headers-2.6.32-22/include/linux是引用的头文件. 内核模块固定格式:module_init()/ module_exit(),module函数是从头文件中来的.

Linux内核学习总结(final)

Linux内核学习总结 符钰婧 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 这八周以来,我从拼不出来"Linux"这个词到知道了很多专有名词,也能大概了解Linux的工作机制,这一系列的进步都是一周周积累下来的.现在回过头来看,有种阳光总在风雨后的感觉,虽然这个比喻好像不太恰当. 闲话少说,接下来就进入这次的正题. 一.首先是对Linux操作系统的理解 1.操作系

Linux内核学习-进程

先说几个术语: 一.Linux进程的五个段 下面我们来简单归纳一下进程对应的内存空间中所包含的5种不同的数据区都是干什么的.重点:代码段.数据段.堆栈段,这是一个概念堆.栈.全局区.常量区,这是另一个概念1)代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像.代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作--它是不可写的.代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域.这部分

linux内核学习:进程管理

进程状态 TASK_RUNNING 可运行或正在运行 TASK_INTERRUPTIBLE 进程被阻塞,但可以被信号唤醒 TASK_UNINTERRUPTIBLE 进程被阻塞,且不可以被信号唤醒 TASK_STOPPED 进程已停止,且不能再投入运行 TASK_ZOMBIE 所谓的僵死进程,进程描述符仍然保留 关键函数和结构 task_struct thread_info current clone fork exec wait exit linux内核学习:进程管理,布布扣,bubuko.co