内核的编译和环境的搭建过程如图
分析内核源码
#include <asm/uaccess.h>
13
14static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
15static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
16
17/* Initial task structure */
18struct task_struct init_task = INIT_TASK(init_task);
19EXPORT_SYMBOL(init_task);
20
21/*
22 * Initial thread structure. Alignment of this is handled by a special
23 * linker map entry.
24 */
25union thread_union init_thread_union __init_task_data =
26 { INIT_THREAD_INFO(init_task) };
init/init_task.c
0号进程pcb初始化方法:内核从init/main.c里面的start_kernel函数开始执行, 如下代码设置了中断初始化:
/*
525 * Interrupts are still disabled. Do necessary setups, then
526 * enable them
527 */
528 boot_cpu_init();
529 page_address_init();
530 pr_notice("%s", linux_banner);
531 setup_arch(&command_line);
532 mm_init_cpumask(&init_mm);
533 setup_command_line(command_line);
534 setup_nr_cpu_ids();
535 setup_per_cpu_areas();
536 smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
537
538 build_all_zonelists(NULL, NULL);
539 page_alloc_init();
540
541 pr_notice("Kernel command line: %s\n", boot_command_line);
542 parse_early_param();
可见在上述过程中对CPU进行必要的设置准备好中断的初始环境
如下代码是start_kernel中对内存,陷阱等的初始化入口
/*
554 * These use large bootmem allocations and must precede
555 * kmem_cache_init()
556 */
557 setup_log_buf(0);
558 pidhash_init();
559 vfs_caches_init_early();
560 sort_main_extable();
561 trap_init();
562 mm_init();
以下是rest_init部分的相关代码初始化了第一个用户态进程并且使用kernel_thread初始化管理系统资源
调用idle进程,这个idle进程创建了1号进程kernel_init和其他服务的内核线程
static 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);
410
411 /*
412 * The boot idle thread must execute schedule()
413 * at least once to get things moving:
414 */
415 init_idle_bootup_task(current);
416 schedule_preempt_disabled();
417 /* Call into cpu_idle with preempt disabled */
418 cpu_startup_entry(CPUHP_ONLINE);
419}
以下下是init_task的具体项目:
#define INIT_TASK(tsk) \
174{ \
175 .state = 0, \
176 .stack = &init_thread_info, \
177 .usage = ATOMIC_INIT(2), \
178 .flags = PF_KTHREAD, \
179 .prio = MAX_PRIO-20, \
180 .static_prio = MAX_PRIO-20, \
181 .normal_prio = MAX_PRIO-20, \
182 .policy = SCHED_NORMAL, \
183 .cpus_allowed = CPU_MASK_ALL, \
184 .nr_cpus_allowed= NR_CPUS, \
185 .mm = NULL, \
186 .active_mm = &init_mm,
万辉(与最后申请证书的姓名务必一致) + 《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000