Linux学习——初浅的Linux内核分析

1.配置内核文件

先把linux-2.6.22.6.tar.bz2以及补丁文件linux-2.6.22.6_jz2440.patch上传到服务器解压缩并打补丁,然后在arch/arm/config找到相似的配置文件:s3c2410_defconfig,然后执行make s3c2410_defconfig,最后执行make menuconfig修改配置项

之后编译内核时,执行make uImage。(uImage是个头部,用于让u-boot引导Linux内核vmLinux启动)

2.配置结果

生成.config文件。以配置项CONFIG_DM9000为例,一共有以下几个文件包含他:

①C源码:CONFIG_DM9000(宏定义)

②子目录Makefile:dirvers/net/Makefile,CONFIG_DM9000在③定义,来源于.config

③include/config/auto.conf,被顶层的Makefile包含

④include/linux/autoconf.h

include/linux/autoconf.h中DM9000被定义为一个宏且值为1,即

#define CONFIG_DM9000 1

注:

a.不管配置项为y或n,在该文件里都把CONFIG_xxx定义为1

b.子目录Makefile:obj -y += xxx.o和obj -m += yyy.o。-y表示xxx.c最后会被编译进内核。-m表示yyy.c最后会被编译为可加载模块(驱动)。

总结:使用命令make uImage会发生

①.config文件被用来创建生成了一个autoconf.h文件,被源代码使用

②.config也被用来创建生成了auto.conf文件,被子目录下的Makefile使用,被顶层Makefile包含

3.分析Makefile

在顶层Makefile中有编译vmLinux的命令:

zImage Image xipImage bootpImage uImage: vmLinux

而vmLinux依赖于:

vmLinux: $(vmLinux-lds) $(vmLinux-init) $(vmLinux-main) $(kallsyms.o) FORCE

这一些文件在顶层Makefile中的

vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds  := arch/$(ARCH)/kernel/vmlinux.lds

①vmlinux-init := $(head-y) $(init-y):

head-y在arch/arm/Makefile里出现:

head-y        := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o

init-y在顶层Makefile里面出现:

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

这两条语句执行完之后即为init-y = init/built-in.o,意思是init目录下涉及到的相关格式的文件会被编译为一个init.o文件

②vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y):

core-y在顶层Makefile里面出现:

core-y          := usr/
core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/
core-y		:= $(patsubst %/, %/built-in.o, $(core-y))

执行完这一些命令后core-y = usr/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,即这些目录下相关格式的文件都会被编译为built-in.o

libs-y在顶层Makefile里面出现:

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

执行完这一些命令之后libs-y = lib/lib.a lib/built-in.o,即这些目录下相关格式的文件都会被编译为built-in.o

drivers-y在顶层Makefile里面出现:

drivers-y	:= drivers/ sound/
drivers-y	:= $(patsubst %/, %/built-in.o, $(drivers-y))

执行完这一些命令之后drivers-y = drivers/built-in.o sound/built-in.o,即这些目录下相关格式的文件都会被编译为built-in.o

net-y在顶层Makefile里面出现:

net-y		:= net/
net-y		:= $(patsubst %/, %/built-in.o, $(net-y))

执行完这一些命令之后net-y = net/built-in.o,即这些目录下相关格式的文件都会被编译为built-in.o

从以上分析可以知道,Linux内核的原材料就是以上这么多文件。这一些是如何链接的?

是通过这些命令来编译的:

ifdef CONFIG_HEADERS_CHECK
	$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
	$(call if_changed_rule,vmlinux__)
	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
	$(Q)rm -f .old_version

4.内核启动

内核的最终目的:运行应用程序,对于Linux来说应用程序在根文件系统,因此需要挂接根文件系统

从arch/arm/keenel/head.S开始分析:

注:若内核编译完之后太大,可以压缩完之后在前面加一段自解压代码

①判断是否支持该CPU(比如S3C2440)

②判断是否支持该板子(比如JZ2440,由u-boot在启动内核时传入的机器ID)

③建立页表

④使能MMU

⑤跳转到start_kernel,是内核的第一个C函数,会做一系列初始化工作,并且会调用                                                                         setup_arch( )、setup_command_line( )解析u-boot传入的启动参数,                                                                                               而后调用rest_init( ),rest_init( )会调用kernel_init( ),kernel_init( )调用prepare_namespace( ),                                                   prepare_namespace( )调用mount_root( ),即挂接根文件系统。

⑥mount_root( )执行完毕之后回到prepare_namespace( ),prepare_namespace( )执行完毕之后回到kernel_init( ),            kernel_init( )再调用init_post( ),init_post( ),会打开/dev/console,然后执行应用程序

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值