Linux内核分析作业第三周
2016-03-10 16:01
666 查看
一、实验楼实验
使用实验楼的虚拟机打开shell
内核启动完成后进入menu程序,支持三个命令help、version和quit
使用gdb跟踪调试内核
另开一个shell窗口
按c后系统开始运行,启动到start_cernel的位置
输入list之后看到执行的位置
再设置一个断点,系统执行到rest_init的位置
init_process是一号进程。
init目录下main.c中的start_kernel是启动内核的起点。
[/code]
使用实验楼的虚拟机打开shell
1 cd LinuxKernel/ 2 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
内核启动完成后进入menu程序,支持三个命令help、version和quit
使用gdb跟踪调试内核
1 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明: 2 # -S freeze CPU at startup (use ’c’ to start execution) 3 # -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
另开一个shell窗口
1 gdb 2 (gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表 3 (gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行 4 (gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后
按c后系统开始运行,启动到start_cernel的位置
输入list之后看到执行的位置
再设置一个断点,系统执行到rest_init的位置
二、简单分析一下start_kernel
1、在init目录下main.c里找到start_kernel函数500asmlinkage __visible void __init start_kernel(void) 501{ 502 char *command_line; 503 char *after_dashes; 504 505 /* 506 * Need to run as early as possible, to initialize the 507 * lockdep hash: 508 */ 509 lockdep_init(); 510 set_task_stack_end_magic(&init_task); //全局变量init_task,即手工创建的PCB,0号进程即最终的idle进程 511 smp_setup_processor_id(); 512 debug_objects_early_init(); 513 514 /* 515 * Set up the the initial canary ASAP: 516 */ 517 boot_init_stack_canary(); 518 519 cgroup_init_early(); 520 521 local_irq_disable(); 522 early_boot_irqs_disabled = true;
init_process是一号进程。
393static noinline void __init_refok rest_init(void) 394{ 395 int pid; 396 397 rcu_scheduler_starting(); 398 /* 399 * We need to spawn init first so that it obtains pid 1, however 400 * the init task will end up wanting to create kthreads, which, if 401 * we schedule it before we create kthreadd, will OOPS. 402 */ 403 kernel_thread(kernel_init, NULL, CLONE_FS); //创建第一个用户态进程 404 numa_default_policy(); 405 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); //内核进程来管理资源 406 rcu_read_lock(); 407 kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); 408 rcu_read_unlock(); 409 complete(&kthreadd_done);
[b]三、总结 [/b]
总的来说在rest_init函数中,内核产生第一个真正的进程: (pid=1):init_idle(current, smp_processor_id())函数的调用把init_task初始化成idle task init_idle函数的第一个参数current就是&init_task,在init_idle中将会把init_task加入到cpu的运行队列中,这样当运行队列中没有别的就绪进程时,init_task(也就是idle task)将会被调用。sched_init()初始化函数内对0号进程,即idle进程进行初始化rest_init()->cpu_startup_entry()->cpu_idle_loop()就是一直循环,当系统没有进程需要执行的时候就调度idle进程,从内核启动开始一直存在,0号进程。0号进程创建了1号进程,并且还创建了内核中其他的一些服务线程。
init目录下main.c中的start_kernel是启动内核的起点。
[/code]
相关文章推荐
- WebLogic 12c Linux 命令行 安装
- linux系统·环境配置
- CentOS6.5配置python开发环境之一:CentOS图形化界面显示
- eXtremeDB hostlinux Target-ARM 的目标码编译
- Linux下ejabberd安装配置
- Linux内核中的初始化initcall
- Ubuntu下的交叉编译
- Linux常用软件
- 【C/C++】Linux C,关于刷新printf输出问题
- centOS 7 安装 MySQL5.7.11
- Linux学习笔记:压缩解压命令
- Linux多线程同步的几种方式
- Linux-非结构化数据同步-Linux下实现非结构化数据同步的介绍1
- 用十条命令在一分钟内检查Linux服务器性能[转]
- Linux - This system is not registered with RHN
- Linux多线程——使用信号量同步线程
- linux学习经验与教训
- linux 进程和线程或线程和线程之间通过管道通信(pipe)
- 一个网卡配置多个ip配置实现,centos7系统
- centos上的KVM安装