免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 8065 | 回复: 21

内核源码 到 应用层 过渡的 问题 [复制链接]

论坛徽章:
0
发表于 2009-10-15 14:42 |显示全部楼层

  1. static int noinline init_post(void)
  2. {
  3. free_initmem();
  4. unlock_kernel();
  5. mark_rodata_ro();
  6. system_state = SYSTEM_RUNNING;
  7. numa_default_policy();
  8. if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
  9.   printk(KERN_WARNING "Warning: unable to open an initial console.\n");
  10. (void) sys_dup(0);
  11. (void) sys_dup(0);
  12. if (ramdisk_execute_command) {
  13.   run_init_process(ramdisk_execute_command);
  14.   printk(KERN_WARNING "Failed to execute %s\n",
  15.     ramdisk_execute_command);
  16. }
  17. /*
  18.   * We try each of these until one succeeds.
  19.   *
  20.   * The Bourne shell can be used instead of init if we are
  21.   * trying to recover a really broken machine.
  22.   */
  23. if (execute_command) {
  24.   run_init_process(execute_command);
  25.   printk(KERN_WARNING "Failed to execute %s.  Attempting "
  26.      "defaults...\n", execute_command);
  27. }
  28. run_init_process("/sbin/init"); // 这里 ,/sbin/init,他们的源码 在那里啊?
  29. run_init_process("/etc/init");
  30. run_init_process("/bin/init");
  31. run_init_process("/bin/sh");
  32. panic("No init found.  Try passing init= option to kernel.");
  33. }
复制代码

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
发表于 2009-10-15 16:06 |显示全部楼层
busybox里应该能找到

论坛徽章:
0
发表于 2009-10-15 16:33 |显示全部楼层

回复 #1 eezzrr 的帖子

sam@sam-desktop:~$ dpkg -S `which init`
upstart: /sbin/init

论坛徽章:
0
发表于 2009-10-15 16:39 |显示全部楼层
static void run_init_process(char *init_filename)
{
        argv_init[0] = init_filename;
        kernel_execve(init_filename, argv_init, envp_init);
}

这个函数的原型,实际上就是调用你filesystem里面的init命令。

论坛徽章:
0
发表于 2009-10-15 22:00 |显示全部楼层
xian 先收下  谢谢 大侠 。。。

论坛徽章:
0
发表于 2009-10-15 22:09 |显示全部楼层
还有 我用的是  arm 体系结构的 linux .......buzybox 是Linux 命令和工具的集合,init 是1号进程,init如果是在
buzybox 我还是不太明白

以下,是我从网上 看到的,不知道 对不对
这些是 0号进程的代码
if (execute_command) {
  run_init_process(execute_command);  -------------------------------------------------------1
  printk(KERN_WARNING "Failed to execute %s.  Attempting "
     "defaults...\n", execute_command);
}
run_init_process("/sbin/init"); // 这里 ,/sbin/init,他们的源码 在那里啊?--------------------2
run_init_process("/etc/init");-----------------------------------------------------------------------3
run_init_process("/bin/init");-----------------------------------------------------------------------4
run_init_process("/bin/sh");-------------------------------------------------------------------------5


1,2,3,4,5,他们只能执行一个,因为执行run_init_process,就把当前进程变成1号了
网上说 就不返回了,我就不明白 为什么 不返回了,为什么只能执行一个

论坛徽章:
0
发表于 2009-10-15 22:19 |显示全部楼层
只执行一个,说明 init 一个就足够了。
其他进程从它上面生出来就可以了。

init 的源码看你的文件系统,你编个 hello world,换成这个 init 也是可以的。

论坛徽章:
0
发表于 2009-10-16 09:40 |显示全部楼层
我还是 不太明白 内核是c语言写的,在没有中断的情况下,应该一句一句的执行。假设执行了2这个函数,函数执行完,
网上说它不返回,那它运行到了哪里啊?
如果 说是进程切换的原因,假设我只有两个进程 0号和1号,2这个函数总会执行完的啊,2函数运行完后,它又到哪里运行
系统 待机 是执行 0号进程,0号进程的代码 还在init_post函数的后面

论坛徽章:
0
发表于 2009-10-16 10:23 |显示全部楼层
我还是 不太明白 内核是c语言写的,在没有中断的情况下,应该一句一句的执行。假设执行了2这个函数,函数执行完,
网上说它不返回,那它运行到了哪里啊?
如果 说是进程切换的原因,假设我只有两个进程 0号和1号,2这个函数总会执行完的啊,2函数运行完后,它又到哪里运行
系统 待机 是执行 0号进程,


代码里面很清楚了,run_init_process调用下面这个函数
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
        long __res;
        asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
        : "=a" (__res)
        : "0" (__NR_execve), "ri" (filename), "c" (argv), "d" (envp) : "memory");
        return __res;
}
这就是在执行execve系统调用阿,执行成功之后这个进程就被init替换掉了。
如果init真的像你说的执行完了,在do_exit中会引起kernel_panic的

0号进程的代码 还在init_post函数的后面

在rest_init里面有一句
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
这不是创建一个内核线程么,
所以根本不用等到1号进程执行完了才执行0号进程,二者是并行的

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
发表于 2009-10-16 10:27 |显示全部楼层
原帖由 eezzrr 于 2009-10-16 09:40 发表
我还是 不太明白 内核是c语言写的,在没有中断的情况下,应该一句一句的执行。假设执行了2这个函数,函数执行完,
网上说它不返回,那它运行到了哪里啊?
如果 说是进程切换的原因,假设我只有两个进程 0号和 ...


1,问题是他执行不完

  1. 691     /* Do the rest non-__init'ed, we're now alive */
  2. 692     rest_init();
复制代码

进入这个函数

然后

  1. 427     kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
复制代码

进入kernel_init
如果进去了,就起了一个内核线程


  1. 891     if (!ramdisk_execute_command)
  2. 892         ramdisk_execute_command = "/init";
  3. 893
  4. 894     if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
  5. 895         ramdisk_execute_command = NULL;
  6. 896         prepare_namespace();
  7. 897     }
  8. 898
  9. 899     /*
  10. 900      * Ok, we have completed the initial bootup, and
  11. 901      * we're essentially up and running. Get rid of the
  12. 902      * initmem segments and start the user-mode stuff..
  13. 903      */
  14. 904
  15. 905     init_post();
  16. 906     return 0;
  17. 907 }

复制代码


挂initcramfs/initrd
然后进入init_post
进到init_post里以后


  1. 839     if (execute_command) {
  2. 840         run_init_process(execute_command);
  3. 841         printk(KERN_WARNING "Failed to execute %s.  Attempting "
  4. 842                     "defaults...\n", execute_command);
  5. 843     }
  6. 844     run_init_process("/sbin/init");
  7. 845     run_init_process("/etc/init");
  8. 846     run_init_process("/bin/init");
  9. 847     run_init_process("/bin/sh");
  10. 848
  11. 849     panic("No init found.  Try passing init= option to kernel.");
  12. 850 }

复制代码


执行init,我这里的init是一个脚本


  1. [root@localhost ~]# cd busybox-initramfs
  2. [root@localhost busybox-initramfs]# pwd
  3. /root/busybox-initramfs
  4. [root@localhost busybox-initramfs]# cat init
  5. #!/bin/busybox sh
  6. mount -t proc proc /proc

  7. # configure network
  8. ifconfig eth0 192.168.1.2/24
  9. route add default gw 192.168.1.1 eth0

  10. # invoke shell
  11. exec busybox sh
  12. [root@localhost busybox-initramfs]#

复制代码

通过一个系统调用,exec一个新进程

  1. 237 /*
  2. 238  * Do a system call from kernel instead of calling sys_execve so we
  3. 239  * end up with proper pt_regs.
  4. 240  */
  5. 241 int kernel_execve(const char *filename, char *const argv[], char *const envp[])
  6. 242 {
  7. 243     long __res;
  8. 244     asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
  9. 245     : "=a" (__res)
  10. 246     : "0" (__NR_execve), "ri" (filename), "c" (argv), "d" (envp) : "memory");
  11. 247     return __res;
  12. 248 }

复制代码


他启动了一个新的进程
这个进程就是bash
当然,你也可以启动N多个进程,通过这个init可以启动N多个子进程
子又有子,子又有孙,孙又有子,孙又有孙,/proc/sys/kernel/pid_max穷溃也

[ 本帖最后由 T-bagwell 于 2009-10-16 10:30 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP