您的位置:首页 > 运维架构 > Linux

Analyse the Booting process of Linux Kernel

2015-03-17 09:41 387 查看
Chapter 1

Ubuntu 14.10

Linux Kernel 3.18.6

Chapter 2 Code and Debug Proccess

Configure for coding:
cd ~/LinuxKernel/
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz xz -d linux-3.18.6.tar.xz
tar -xvf linux-3.18.6.tar
cd linux-3.18.6
make i386_defconfig
make 

cd ~/LinuxKernel/
mkdir rootfs
git clone  https://github.com/mengning/menu.git cd menu
gcc -o init linktable.c menu.c test.c -m32 -static –lpthread
cd ../rootfs
cp ../menu/init ./
find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img

cd ~/LinuxKernel/
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img


Compile the Kernel once again:

make menuconfig
kernel hacking—>
compile-time checks and compile options
[*] compile the kernel with debug info


Sarting to debug:

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S


Open another terminal to run debug:

gdb
(gdb)file linux-3.18.6/vmlinux 
(gdb)target remote:1234 
(gdb)break start_kernel
(gdb)list
I won't copy the code any more, because it is too long to paste it.

http://codelab.shiyanlou.com/xref/linux-3.18.6/init/main.c

I set a plan to analyze the following function:

cpu_startup_entry

page_address_init()

rest_init()

page_alloc_init()

trap_init()

tick_init()

profile_init()

key_init()

security_init()

buffer_init()

init_task 0 process

run_init_process(const char *init_filename) init process

The structure of 0 process init_task:

#define INIT_TASK(tsk)	\
{									\
	.state		= 0,						\
	.stack		= &init_thread_info,				\
	.usage		= ATOMIC_INIT(2),				\
	.flags		= PF_KTHREAD,					\
	.prio		= MAX_PRIO-20,					\
	.static_prio	= MAX_PRIO-20,					\
	.normal_prio	= MAX_PRIO-20,					\
	.policy		= SCHED_NORMAL,					\
	.cpus_allowed	= CPU_MASK_ALL,					\
	.nr_cpus_allowed= NR_CPUS,					\
	.mm		= NULL,						\
	.active_mm	= &init_mm,					\
	.se		= {						\
		.group_node 	= LIST_HEAD_INIT(tsk.se.group_node),	\
	},								\
	.rt		= {						\
		.run_list	= LIST_HEAD_INIT(tsk.rt.run_list),	\
		.time_slice	= RR_TIMESLICE,				\
	},								\
	.tasks		= LIST_HEAD_INIT(tsk.tasks),			\
	INIT_PUSHABLE_TASKS(tsk)					\
	INIT_CGROUP_SCHED(tsk)						\
	.ptraced	= LIST_HEAD_INIT(tsk.ptraced),			\
	.ptrace_entry	= LIST_HEAD_INIT(tsk.ptrace_entry),		\
	.real_parent	= &tsk,						\
	.parent		= &tsk,						\
	.children	= LIST_HEAD_INIT(tsk.children),			\
	.sibling	= LIST_HEAD_INIT(tsk.sibling),			\
	.group_leader	= &tsk,						\
	RCU_POINTER_INITIALIZER(real_cred, &init_cred),			\
	RCU_POINTER_INITIALIZER(cred, &init_cred),			\
	.comm		= INIT_TASK_COMM,				\
	.thread		= INIT_THREAD,					\
	.fs		= &init_fs,					\
	.files		= &init_files,					\
	.signal		= &init_signals,				\
	.sighand	= &init_sighand,				\
	.nsproxy	= &init_nsproxy,				\
	.pending	= {						\
		.list = LIST_HEAD_INIT(tsk.pending.list),		\
		.signal = {{0}}},					\
	.blocked	= {{0}},					\
	.alloc_lock	= __SPIN_LOCK_UNLOCKED(tsk.alloc_lock),		\
	.journal_info	= NULL,						\
	.cpu_timers	= INIT_CPU_TIMERS(tsk.cpu_timers),		\
	.pi_lock	= __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock),	\
	.timer_slack_ns = 50000, /* 50 usec default slack */		\
	.pids = {							\
		[PIDTYPE_PID]  = INIT_PID_LINK(PIDTYPE_PID),		\
		[PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),		\
		[PIDTYPE_SID]  = INIT_PID_LINK(PIDTYPE_SID),		\
	},								\
	.thread_group	= LIST_HEAD_INIT(tsk.thread_group),		\
	.thread_node	= LIST_HEAD_INIT(init_signals.thread_head),	\
	INIT_IDS							\
	INIT_PERF_EVENTS(tsk)						\
	INIT_TRACE_IRQFLAGS						\
	INIT_LOCKDEP							\
	INIT_FTRACE_GRAPH						\
	INIT_TRACE_RECURSION						\
	INIT_TASK_RCU_PREEMPT(tsk)					\
	INIT_TASK_RCU_TASKS(tsk)					\
	INIT_CPUSET_SEQ(tsk)						\
	INIT_RT_MUTEXES(tsk)						\
	INIT_VTIME(tsk)							\
}


Chapter 3 Debug

I set 13 breakpoints:

(gdb)break <function name>
接着输入c进行调试。

流程如下:



Several pictures of debuging:

start_kernel:



page_address_init:



buffer_init:



security_init:



cpu_startup_entry:





run_init_process:



Chapter 4 Conclusion

By this way, we know that what functions involved in the booting process of Linux kernel. The character displayed on the screen represent the busy work in deep. I hope I can learn more about the detail of each function. It's a complex work.

set_task_stack_end_magic set init_task, which is 0 process lately, idle in another words.

Reference: http://blog.chinaunix.net/uid-27767798-id-3577069.html
Check the timer interrupt to let idle process itself, which could create a process. Just like myKernel at last week course.

The idle process will detect whether the new process will work. If the new process is created, it will release the resource. If the process come to an end, system will recycle it.

When the kernel is running the run_init_process, init_process is started.

Appendix

Luxuan + Writen by the author, Please let me know if you want to take it as a reference + Linux Kernel Analyzation a course of MOOC website:http://mooc.study.163.com/course/USTC-1000029000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: