学习笔记:内核启动流程
来源:互联网 发布:linux运行jar文件 编辑:程序博客网 时间:2024/06/06 14:07
⒈内核的配置:
Ⅰ、cp config_ok .config
Ⅱ、make uImage时:
.config生成include/linux/autoconf.h
.config生成include/config/auto.conf,被顶层Makefile包含,子目录下的Makefile用它。
⒉分析Makefile:
找到第一个文件:提纲挈领,顺藤摸瓜
链接脚本:内核放在那里,里面的东西是怎么排布的
Ⅰ、uImage: vmlinux
zImage Image xipImage bootpImage uImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
Ⅱ、vmlinux: vmlinux-lds vmlinux-init vmlinux-main kallsyms.o
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
⑴、vmlinux-init
vmlinux-init := $(head-y) $(init-y)
①、head-y
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
②、init-y
init-y := init/init-y := $(patsubst %/, %/built-in.o, $(init-y))
⑵、vmlinux-main
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
①、core-y
core-y := usr/core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/core-y := $(patsubst %/, %/built-in.o, $(core-y))
②、libs-y
libs-y := lib/libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))libs-y := $(libs-y1) $(libs-y2)
③、drivers-y
drivers-y := drivers/ sound/drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
④、net-y
net-y := net/net-y := $(patsubst %/, %/built-in.o, $(net-y))
Ⅲ、
vmlinux-all := $(vmlinux-init) $(vmlinux-main)vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.ldsexport KBUILD_VMLINUX_OBJS := $(vmlinux-all)
Ⅳ、在编译uImage时原材料按以下方式组成内核
arm-linux-ld -EL -p --no-undefined -X -o vmlinux -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o arch/arm/kernel/init_task.o init/built-in.o --start-group usr/built-in.o arch/arm/kernel/built-in.o arch/arm/mm/built-in.o arch/arm/common/built-in.o arch/arm/mach-s3c2410/built-in.o arch/arm/mach-s3c2400/built-in.o arch/arm/mach-s3c2412/built-in.o arch/arm/mach-s3c2440/built-in.o arch/arm/mach-s3c2442/built-in.o arch/arm/mach-s3c2443/built-in.o arch/arm/nwfpe/built-in.o arch/arm/plat-s3c24xx/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/built-in.o drivers/built-in.o sound/built-in.o net/built-in.o --end-group .tmp_kallsyms2.o
由此,我们找到了第一个文件:
arch/arm/kernel/head.S
链接脚本:
arch/arm/kernel/vmlinux.lds
3.分析head.S文件
Ⅰ、u-boot的传入参数有
⑴、机器ID
⑵、启动参数
Ⅱ、head.S主要功能:
⑴、判断是否支持这个CPU
bl __lookup_processor_type
⑵、判断是否支持这个单板,机器ID在这步进行匹配
bl __lookup_machine_type
⑶、建立页表
bl __create_page_tables
⑷、使能MMU
adr lr, __enable_mmu
⑸、跳到linux-2.6.22.6\init\main.c:start_kernel函数,启动参数会在linux-2.6.22.6\init\main.c:start_kernel函数中处理
启动参数处理函数:
setup_arch(&command_line); setup_command_line(command_line);
4、挂载根文件系统:(☞☞:调用)
linux-2.6.22.6\init\main.c:asmlinkage void __init start_kernel(void)
☞☞
linux-2.6.22.6\init\main.c:static void noinline __init_refok rest_init(void){ ... kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); ...}
☞☞
linux-2.6.22.6\init\main.c:static int __init kernel_init(void * unused)
☞☞
linux-2.6.22.6\init\do_mounts.c:void __init prepare_namespace(void)
☞☞
linux-2.6.22.6\init\do_mounts.c:void __init mount_root(void)
5、通过以上步骤挂载好根文件系统后调用linux-2.6.22.6\init\main.c:init_post函数执行第一个应用程序
static int noinline init_post(void){ ... if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) ... if (execute_command) { run_init_process(execute_command); printk(KERN_WARNING "Failed to execute %s. Attempting " "defaults...\n", execute_command); } run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh"); ...}
其中execute_command指针地址上得内容如下可得,是命令行参数init的值,宏__setup("init=", init_setup)
会调用linux-2.6.22.6\init\main.c:init_setup函数将命令行参数传到execute_command保存的地址上去:
static char *execute_command;
static int __init init_setup(char *str){ unsigned int i; execute_command = str; /* * In case LILO is going to boot us with default command line, * it prepends "auto" before the whole cmdline which makes * the shell think it should execute a script with such name. * So we ignore all arguments entered _before_ init=... [MJ] */ for (i = 1; i < MAX_INIT_ARGS; i++) argv_init[i] = NULL; return 1;}__setup("init=", init_setup);
宏__setup("init=", init_setup)
在如下定义
linux-2.6.22.6\linux-2.6.22.6\include\linux\init.h:
#define __setup(str, fn) \ __setup_param(str, fn, fn, 0)
#define __setup_param(str, unique_id, fn, early) \ static char __setup_str_##unique_id[] __initdata = str; \ static struct obs_kernel_param __setup_##unique_id \ __attribute_used__ \ __attribute__((__section__(".init.setup"))) \ __attribute__((aligned((sizeof(long))))) \ = { __setup_str_##unique_id, fn, early }
- 学习笔记:内核启动流程
- Linux内核启动流程笔记
- 内核启动学习笔记
- 内核:Linux2.6内核启动流程学习
- 内核:Linux2.6内核启动流程学习
- 内核:Linux2.6内核启动流程学习
- 内核:Linux2.6内核启动流程学习
- 笔记第10课内核启动流程
- Linux2.6内核启动流程学习
- uboot启动内核学习笔记
- 内核启动1-启动流程总述/bootlader学习
- linux内核启动流程
- Linux内核启动流程
- 内核启动流程
- linux内核启动流程
- linux内核启动流程
- 内核启动流程
- linux内核启动流程
- NYOJ-24 素数距离问题
- HDU-1161-Eddy's mistakes
- nginx学习记录
- 我转我转我转:实现一个函数翻转字符串
- 浅析Java虚拟机结构与机制
- 学习笔记:内核启动流程
- win10配置apache24
- 毕业设计之jdk和spring不兼容
- 为Twemproxy 添加 Auth
- C++ Primer Plus编程练习 7.13-2
- Codeforces Round #303 (Div. 2)-D. Queue(优先队列)
- AsyncTask的缺陷和问题
- android VideoView截屏黑屏解决方法
- linux下边搭建redis