Hi3519v101 kernel学习记录

一、.config讲解
1、通过make menuconfig配置内核命令生成的.config为内核的配置的文件,里面CONFIG_xxx_xxx=y表示该驱动直接编译到内核里面去,CONFIG_xxx_xxx=m/=xxx(某个数值)表示该驱动作为可加载模块编译到内核。
2、CONFIG_xxx_xxx=y、CONFIG_xxx_xxx=m/=xxx(某个数值)经过编译最终会在include/generated/autoconf.h生成#define CONFIG_ZLIB_INFLATE 1的宏定义,此autoconf.h会在代码里面调用;以CONFIG_ZLIB_INFLATE为例,可以通过grep “CONFIG_ ZLIB_INFLATE” * -nwR 命令搜索到。
注意:这里对y、m/xxx(某个数值)没有做区分;
3、在lib/zlib_inflate/Makefile文件所在的Makefile里面可以找到obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o,此处的CONFIG_ZLIB_INFLATE被别的文件定义;在include/config/auto.conf可以找到有CONFIG_ZLIB_INFLATE=y 该定义就会用在Makefile里面,并有y、m/xxx(某个数值)的区分;
说明:内核的子目录Makefile内容很简单,一般为obj-y += xxx.o、obj-m += yyy.o,-y直接编译到内核,编译后的文件类型为.o;-m为可记载模块,编译后的文件类型为.ko。
二、Makefile讲解
1、子目录Makefile内容很简单,一般为obj-y += xxx.o、obj-m += yyy.o,-y直接编译到内核,编译后的文件类型为.o;-m为可记载模块,编译后的文件类型为.ko;
2、make uImage,在顶层Makefile并未搜索到uImage,反而在arch/arm下的Makefile找到,说明该Makefile会被顶层的Makefile所包含。在顶层Makefile也能找到include ( s r c t r e e ) / a r c h / (srctree)/arch/ (srctree)/arch/(SRCARCH)/Makefile
3、在顶层Makefile搜索auto.conf能找到include/config/auto.conf,说明之前.config生产的auto.conf有包含到里面;
4、在arch/arm的Makefile搜索uImage可以看到,生成uImage依赖于vmlinux。在uboot学习可知,uImage由头+真正的内核构成,而vmlinux就是生成这个真正的内核,而vmlinux是在顶层的Makefile生产的;

BOOT_TARGETS	= zImage Image xipImage bootpImage uImage
INSTALL_TARGETS	= zinstall uinstall install

PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS)

$(BOOT_TARGETS): vmlinux
	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@

$(INSTALL_TARGETS):
	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@

5、vmlinux是如何生产的呢?可参考这里
就这这些路径下面的相关文件

ifeq ($(KBUILD_EXTMOD),)
core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/

vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
		     $(net-y) $(net-m) $(libs-y) $(libs-m)))

vmlinux-alldirs	:= $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \
		     $(init-) $(core-) $(drivers-) $(net-) $(libs-))))

init-y		:= $(patsubst %/, %/built-in.o, $(init-y))
core-y		:= $(patsubst %/, %/built-in.o, $(core-y))
drivers-y	:= $(patsubst %/, %/built-in.o, $(drivers-y))
net-y		:= $(patsubst %/, %/built-in.o, $(net-y))
libs-y1		:= $(patsubst %/, %/lib.a, $(libs-y))
libs-y2		:= $(patsubst %/, %/built-in.o, $(libs-y))
libs-y		:= $(libs-y1) $(libs-y2)

# Externally visible symbols (used by link-vmlinux.sh)
export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)
export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y)
export KBUILD_LDS          := arch/$(SRCARCH)/kernel/vmlinux.lds
export LDFLAGS_vmlinux
# used by scripts/pacmage/Makefile
export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Documentation include samples scripts tools virt)

vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)

# Final link of vmlinux
      cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux)
quiet_cmd_link-vmlinux = LINK    $@

# Include targets which we want to
# execute if the rest of the kernel build went well.
vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE
ifdef CONFIG_HEADERS_CHECK
	$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
ifdef CONFIG_SAMPLES
	$(Q)$(MAKE) $(build)=samples
endif
ifdef CONFIG_BUILD_DOCSRC
	$(Q)$(MAKE) $(build)=Documentation
endif
	+$(call if_changed,link-vmlinux)

# The actual objects are generated when descending,
# make sure no implicit rule kicks in
$(sort $(vmlinux-deps)): $(vmlinux-dirs) ;

经过分析内核的
第一个文件位于arch/arm/kernel/head.S
链接脚本位于arch/arm/kernel/vmlinux.lds
head.S 主要配置信息如下:

设置arm工作模式在SVC并关闭FIRQ IRQ
探测processor 类型
解析uboot传进来的atags
__fixup_smp __fixup_pv_table
__create_page_tables
执行由proc_info_list 的__cpu_flush;指定的函数。如__v7_setup
开启MMU
__mmap_switched
b start_kernel 位于init\main.c

三、start_kernel讲解
1、打印内核版本信息
pr_notice("%s", linux_banner);

2、如下函数处理uboot传进来的tag参数,如内存信息、命令行参数
setup_arch(&command_line);
mm_init_cpumask(&init_mm);
setup_command_line(command_line);
3、rest_init();
------kernel_init();// init=1号进程创建、内核驱动模块注册、启动默认控制台/dev/console
----------kernel_init_freeable();//功能:kernel_init_freeable主要功能是,等待内核线程创建完wait_for_completion(&kthreadd_done)、注册内核驱动模块do_basic_setup()、启动默认控制台/dev/console,标准输入输出,错误信息都在这个控制台里。
------------run_init_process();//启动uboot指定的init=xxx运用程序,如果uboot没有指定则,运行程序内部指定的
---------------do_basic_setup();//功能:初始化cpuset子系统、创建khelper线程队列、内核模块驱动注册
--------------------do_initcalls();//功能:初始化initcall_levels,完成编译进内核的驱动模块注册,详见这里

至此,内核的初始化结束,正式进入了用户空间的初始化过程,在kernel_init线程中调用的do_basic_setup()函数会去初始化设备驱动,完成其他驱动程序(直接编译进内核的模块)的初始化。内核中大部分的启动数据输出(都是各设备的驱动模块输出)都是这里产生的。是我们驱动工程师需要重点关注的函数。
用户空间的初始化结束,就会进入根文件系统,运行init第一个运用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值