Linux内核启动源码跟踪-gdb调试篇

内核的编译和环境的搭建过程如图






分析内核源码

#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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值