gdb跟踪调试内核从start_kernel到init进程启动

顾涛原创作品转载请注明出处《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

如果我写的不好或者有误的地方请留言

  • 题目自拟,内容围绕Linux内核的启动过程,即从start_kernel到init进程启动;
  • 博客中需要使用实验截图
  • 博客内容中需要仔细分析start_kernel函数的执行过程
  • 总结部分需要阐明自己对“Linux系统启动过程”的理解,尤其是idle进程、1号进程是怎么来的。

实验报告:

在实验楼里跑了一下gdb 没有多大印象 印象就是卡 这是卡吗 下面分析换自己的虚拟机

先来个宏观认识:

从start_kernel()中可以看到最后一条语句是rest_init();

  1 asmlinkage __visible void __init start_kernel(void)
  2 {
  3     char *command_line;
  4     char *after_dashes;
  5
  6     /*
  7      * Need to run as early as possible, to initialize the
  8      * lockdep hash:
  9      */
 10     lockdep_init();
 11     set_task_stack_end_magic(&init_task);
 12     smp_setup_processor_id();
 13     debug_objects_early_init();
 14
 15     /*
 16      * Set up the the initial canary ASAP:
 17      */
 18     boot_init_stack_canary();
 19
 20     cgroup_init_early();
 21
 22     local_irq_disable();
 23     early_boot_irqs_disabled = true;
 24
 25 /*
 26  * Interrupts are still disabled. Do necessary setups, then
 27  * enable them
 28  */
 29     boot_cpu_init();
 30     page_address_init();
 31     pr_notice("%s", linux_banner);
 32     setup_arch(&command_line);
 33     mm_init_cpumask(&init_mm);
 34     setup_command_line(command_line);
 35     setup_nr_cpu_ids();
 36     setup_per_cpu_areas();
 37     smp_prepare_boot_cpu();    /* arch-specific boot-cpu hooks */
 38
 39     build_all_zonelists(NULL, NULL);
 40     page_alloc_init();
 41
 42     pr_notice("Kernel command line: %s\n", boot_command_line);
 43     parse_early_param();
 44     after_dashes = parse_args("Booting kernel",
 45                   static_command_line, __start___param,
 46                   __stop___param - __start___param,
 47                   -1, -1, &unknown_bootoption);
 48     if (!IS_ERR_OR_NULL(after_dashes))
 49         parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
 50                set_init_arg);
 51
 52     jump_label_init();
 53
 54     /*
 55      * These use large bootmem allocations and must precede
 56      * kmem_cache_init()
 57      */
 58     setup_log_buf(0);
 59     pidhash_init();
 60     vfs_caches_init_early();
 61     sort_main_extable();
 62     trap_init();
 63     mm_init();
 64
 65     /*
 66      * Set up the scheduler prior starting any interrupts (such as the
 67      * timer interrupt). Full topology setup happens at smp_init()
 68      * time - but meanwhile we still have a functioning scheduler.
 69      */
 70     sched_init();
 71     /*
 72      * Disable preemption - early bootup scheduling is extremely
 73      * fragile until we cpu_idle() for the first time.
 74      */
 75     preempt_disable();
 76     if (WARN(!irqs_disabled(),
 77          "Interrupts were enabled *very* early, fixing it\n"))
 78         local_irq_disable();
 79     idr_init_cache();
 80     rcu_init();
 81     context_tracking_init();
 82     radix_tree_init();
 83     /* init some links before init_ISA_irqs() */
 84     early_irq_init();
 85     init_IRQ();
 86     tick_init();
 87     rcu_init_nohz();
 88     init_timers();
 89     hrtimers_init();
 90     softirq_init();
 91     timekeeping_init();
 92     time_init();
 93     sched_clock_postinit();
 94     perf_event_init();
 95     profile_init();
 96     call_function_init();
 97     WARN(!irqs_disabled(), "Interrupts were enabled early\n");
 98     early_boot_irqs_disabled = false;
 99     local_irq_enable();
100
101     kmem_cache_init_late();
102
103     /*
104      * HACK ALERT! This is early. We‘re enabling the console before
105      * we‘ve done PCI setups etc, and console_init() must be aware of
106      * this. But we do want output early, in case something goes wrong.
107      */
108     console_init();
109     if (panic_later)
110         panic("Too many boot %s vars at `%s‘", panic_later,
111               panic_param);
112
113     lockdep_info();
114
115     /*
116      * Need to run this when irqs are enabled, because it wants
117      * to self-test [hard/soft]-irqs on/off lock inversion bugs
118      * too:
119      */
120     locking_selftest();
121
122 #ifdef CONFIG_BLK_DEV_INITRD
123     if (initrd_start && !initrd_below_start_ok &&
124         page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
125         pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n",
126             page_to_pfn(virt_to_page((void *)initrd_start)),
127             min_low_pfn);
128         initrd_start = 0;
129     }
130 #endif
131     page_cgroup_init();
132     debug_objects_mem_init();
133     kmemleak_init();
134     setup_per_cpu_pageset();
135     numa_policy_init();
136     if (late_time_init)
137         late_time_init();
138     sched_clock_init();
139     calibrate_delay();
140     pidmap_init();
141     anon_vma_init();
142     acpi_early_init();
143 #ifdef CONFIG_X86
144     if (efi_enabled(EFI_RUNTIME_SERVICES))
145         efi_enter_virtual_mode();
146 #endif
147 #ifdef CONFIG_X86_ESPFIX64
148     /* Should be run before the first non-init thread is created */
149     init_espfix_bsp();
150 #endif
151     thread_info_cache_init();
152     cred_init();
153     fork_init(totalram_pages);
154     proc_caches_init();
155     buffer_init();
156     key_init();
157     security_init();
158     dbg_late_init();
159     vfs_caches_init(totalram_pages);
160     signals_init();
161     /* rootfs populating might need page-writeback */
162     page_writeback_init();
163     proc_root_init();
164     cgroup_init();
165     cpuset_init();
166     taskstats_init_early();
167     delayacct_init();
168
169     check_bugs();
170
171     sfi_init_late();
172
173     if (efi_enabled(EFI_RUNTIME_SERVICES)) {
174         efi_late_init();
175         efi_free_boot_services();
176     }
177
178     ftrace_init();
179
180     /* Do the rest non-__init‘ed, we‘re now alive */
181     rest_init();
182 }

start_kernel

 1 static noinline void __init_refok rest_init(void)
 2 {
 3     int pid;
 4
 5     rcu_scheduler_starting();
 6     /*
 7      * We need to spawn init first so that it obtains pid 1, however
 8      * the init task will end up wanting to create kthreads, which, if
 9      * we schedule it before we create kthreadd, will OOPS.
10      */
11     kernel_thread(kernel_init, NULL, CLONE_FS);
12     numa_default_policy();
13     pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
14     rcu_read_lock();
15     kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
16     rcu_read_unlock();
17     complete(&kthreadd_done);
18
19     /*
20      * The boot idle thread must execute schedule()
21      * at least once to get things moving:
22      */
23     init_idle_bootup_task(current);
24     schedule_preempt_disabled();
25     /* Call into cpu_idle with preempt disabled */
26     cpu_startup_entry(CPUHP_ONLINE);
27 }

rest_init

咱们需要知道的东西如下:

在start_kernel中:

init_task:手工创建的PCB 0号进程即最终的idle进程
trap_init:初始化中断管理模块
mm_init:初始化内存管理模块
sched_init:初始化调度模块

在rest_init中:

run_init_process:linux系统中的1号进程 第一个用户态进程

注意:

1.我们需要首先初始化获得pid=1的进程 如果初始化最终创建了ktheads

我们在创建kthreadd之前调度它 Linux系统将会OOPS

2.启动空闲线程必须至少执行一次schedule()

时间: 2024-10-01 03:42:51

gdb跟踪调试内核从start_kernel到init进程启动的相关文章

Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动

姓名:江军 ID:fuchen1994 实验日期:2016.3.13 实验指导 使用实验楼的虚拟机打开shell cd LinuxKernel/ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img 内核启动完成后进入menu程序(<软件工程C编码实践篇>的课程项目),支持三个命令help.version和quit,您也可以添加更多的命令,对选修过<软件工程C编码实践篇>的童鞋应该是a piece of

(作业3)Linux内核的启动过程(从start_kernel到init进程启动)

作业题目: 详细分析从start_kernel到init进程启动的过程并结合实验截图撰写一篇署名博客,并在博客文章中注明“真实姓名(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”,博客内容的具体要求如下: 题目自拟,内容围绕Linux内核的启动过程,即从start_kernel到init进程启动: 博客中需要使用实验截图 博客内容中需要仔细分析

构建一个简单的Linux系统 MenuOs —— start_kernel到init进程(20135304刘世鹏)

构建一个简单的Linux系统 MenuOs —— start_kernel到init进程 作者:刘世鹏20135304 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核代码简介 内核源码三个个重要目录 arch占有代码量最大,支持不同cpu的源代码,arch/x86目录下的代码是我们关注的重点 init,内核启动相关的代码基本都在init目录下,init/main.c中start_kernel是整

Android系统启动流程(一)解析init进程启动过程

前言 作为"Android框架层"这个大系列中的第一个系列,我们首先要了解的是Android系统启动流程,在这个流程中会涉及到很多重要的知识点,这个系列我们就来一一讲解它们,这一篇我们就来学习init进程. 1.init简介 init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等.init进程是由多个源文件共同组成的,这些文件位于源码目录system/core/init.本文将基于Androi

VELT-0.1.5开发: gdb串口调试内核时信息丢失的问题

快乐虾 http://blog.csdn.net/lights_joy/(QQ群:Visual EmbedLinux Tools 375515651) 欢迎转载,但请保留作者信息 本文仅适用于vs2013 + velt-0.1.5 VELT的全称是Visual EmbedLinuxTools,它是一个与visual gdb类似的visual studio插件,用以辅助完成Linux开发.利用这个插件,将可以在visual studio的IDE中进行Linux应用程序的开发(包括编译和调试),也可

通过gdb跟踪Linux内核装载和启动可执行程序过程

作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的:通过对一个简单的可执行程序用gdb进行代码的跟踪,剖析linux内核是如何动态和静态装载和启动程序的,进而总结linux内核可执行程序加载的过程. 一.实验过程 1.编写一个简单的Exec的创建进程的函数 2.打开gdb,并设置好如下断点 3.开始跟踪,找到第一个断点. (主程序还未创建子进程) 4.继续在此断点处逐步跟踪 5.

跟踪调试Linux内核的启动过程

跟踪调试Linux内核的启动过程---使用gdb 符钰婧 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 本次的实验是使用gdb跟踪调试内核从start_kernel到init进程启动,并分析启动的过程. 1.首先是在实验楼虚拟机上进行调试跟踪的过程. (1) 先构造一个简单的Linux系统 (2) 接下来使用gdb跟踪调试内核 启动(窗口被冻结) 另开一个shell窗口(水平分割)

GDB 多进程调试

启动: $gdb <file>  || $gdb 然后(gdb)file <file> 运行: (gdb)run <该程序本身的命令行参数> 查看代码: (gdb)list  简写为 (gdb)l 技巧(gdb)list 1,20   //查看1到20行的代码   使用断点: 建立断点 (gdb)break  //可以简写为(gdb)b (gdb)b <function>   || <file>:<function>  //这种是为还

《Linux内核》第七周 进程的切换和系统的一般执行过程 20135311傅冬菁

进程的切换和系统的一般执行过程 一.内容总结与分析 进程调度与进程调度时机 进程调度需求的分类: 第一种分类方式: I/O -bound(频繁进行I/O,通常会花很多时间等待I/O操作) CPU-bound(计算密集型.需要花大量CPU时间进行运算) 第二种分类方式: 批处理进程(后台进行,典型:编译程序.科学计算) 实时进程(有实时需求响应时间短.稳,典型:视频.音频.机械控制) 交互式进程(与用户交互多,响应时间要快,典型:shell.文本编辑程序.图形应用程序) Linux调度基于分时和优