1、上章回顾,U-Boot的移植 U-Boot中添加一个命令的方法,Linux内核分析,第6章,预习检查,简单介绍下Linux版本和特点? Makefile的作用? Kconfig的作用? 简述Linux内核的启动流程?,Page 4/40,本章目标,了解Linux内核源码的组织结构 掌握Linux内核的编译及启动,本章结构,Linux内核配置,Linux内核分析,内核源码结构及Makefile分析,Linux内核配置选项,内核的Kconfig分析,Linux版本及特点,Linux内核启动流程分析,Linux内核启动过程概述,编译、烧写、启动内核,修改内核以支持S3C2440开发板,获取内核源,U
2、nix有多遥远?,Unix诞生于失败的项目:Multics1969年,Ken Thomspon在PDP-7上实现1973年,Dennis Ritche实现了C语言版的Unix1983年,AT&T推出System V19791993年,3BSD,到最后一个4.4BSD商业的Unix版本: HP UX Sun solaris IBM AIX,Unix的优势,简洁,系统调用仅百余个在Unix,所有的东西被当作文件看待Unix的内核和相关的系统工具软件都是C开发的 惊人的移植能力 fork()迅速简单而又稳定的通信原语,追寻Linus的足迹,1991年,linus为intel 80386开发的unix
3、操作系统Linux内核遵循GPL,是Free softwareLinux 是unix-like的操作系统内核Linux系统的基础 内核 C库 GCC 系统的基本工具,Linux的发行版,Debian GNU/Linux Fedora Gentoo Linux Mandriva Linux Redhat Enterprise Linux(RHEL) Slackware Linux OpenSuSE SuSE Linux Enterprise Server Ubuntu,操作系统VS内核,一般理解的操作系统 完成最基本功能,和系统管理的那些部分 内核,驱动,启动引导程序,命令行shell以及其他的
4、一些界面现在理解的操作系统,指内核 内核才是操作系统的核心 负责响应中断服务程序 负责管理多个进程从而分享处理器时间的调度程序 负责管理进程地址空间的内存管理程序 网络,和进程间通信 运行于系统态,以及受保护的内存空间,称之为内核空间,处理器的上下文环境,运行于内核空间,处于进程上下文,代表某个进程执行运行于内核空间,处于中断上下文,与进程无关运行于用户空间,执行用户进程CPU空闲时。内核运行一个空进程,处于进程上下文,运行于内核空间,Linux内核 VS 传统UNIX的内核,都是单体内核,Linux支持动态加载模块Linux内核支持preemptiveLinux提供了面向对象的设备模型,ho
5、tplug等虚拟文件系统内核线程,安装内核源码,两种形式的压缩GNU zip #tar xzvf linux-x.y.z.tar.gzBzip2 #tar xvjf linux-x.y.z.tar.bz2,Linux的源代码结构,目录描述,Linux内核源码层次结构,arch/arm/的目录,include/asm的头文件目录,1,asm是一个symbolic link, 因为众多的文件都需要包含asm-XXX/目录下的某个头文件,使用asm的链接之后,在不同的平台下指向不同的目录,这样,增加了软件的可移植性。,include/linux/头文件目录,与平台无关的头文件一般放在linux这个目
6、录下如linux/mtd/,Linux Makefile分析,Makefile的作用: 决定编译哪些文件。 怎样编译这些文件? 怎样连接这些文件,最重要的是它们的顺序如何?,Linux内核Makefile文件分类,Makefile的作用,决定编译哪些文件 怎样编译这些文件 怎样连接这些文件,它们的顺序如何,Makefile的作用(1),决定编译哪些文件1) 顶层Makefile决定内核根目录下哪些子目录将被编迸内核。 2) arch/$(ARCH)/Makefile决定arch/$(ARCH)目录下哪些文件、哪些目录将被编进内核。 3) 各级子目录下的Makefile决定所在目录下哪些文件将被
7、编进内核,哪些文件将被编成模块(即驱动程序),进入哪些子目录继续调用它们的Makefile。,Makefile的变量,在include/config/auto.conf文件中,变量的值主要有两类:“y ”和“m”)。各级子目录的 Makefile使用这些变量来决定哪些文件被编进内核中,哪些文件被编成模块(即驱动程序), 要进入哪些下一级子目录继续编译objy用来定义哪些文件被编进( built-in)内核 obj-m用来定义哪些文件被编译成可加载模块( Loadable module ) lib-y用来定义哪些文件被编成库文件 obj-y、obj-m还可以用来指定要进入的下一层子目录,Make
8、file的作用(2),怎样编译这些文件即编译选项、连接选项是什么 选项分3类: 全局的,适用于整个内核代码树; 局部的,仅适用于某个Makefile中的所有文件; 个体的,仅适用于某个文件,Makefile的作用(3),怎样连接这些文件,它们的顺序如何 arch/arm/Makefile:顶层Makefile:,Makefile的作用(3),顶层Makefile中,再往下看:顶层Makefile按照一定的顺序组织文件,根据连接脚本arc/$(ARCH)/ kernel/ vmlinux.lds生成内核映象文件vmlinux,对Makefile的总结,(1)配置文件.config中定义了一系列的
9、变量,Makefile将结合它们釆决定哪些文件被编 进内核、哪些文件被编成模块、涉及哪些子目录。 (2)顶层Makefile和arch/$(ARCH)/Makefile决定根目录下哪些子目录,arc/$(ARCH) 目录下哪些文件和目录将被编迸内核。 (3)最后,各级子目录下的Makefile决定所在目录下哪些文件将被编进内核,哪些文件 将被编成模块(即驱动程序),进入哪些目录继续调用它们的Makefile 。 ( 4)顶层Makefile和arch/$(ARCH)/Makefile设置了可以影响所有文件的编译、连接选 项:CFLAGS、MLAGS、LDFLAGS、ARFLAGS。 (5)各级
10、子目录下的Makefile中可以设置能够影响当前目录下所有文件的编译、连接选 项:EXTRA_CFLAGS、EXTRA_AFLAGS、EXTRA_LDFLAGS、EXTRA_ARFLAGS;还可以设置可以影响某个文件的编译选项:CFLAGS_$,AFLAGS_$ 。 ( 6)顶层Makefile按照一定的顺序组织文件,根据连接脚本arc/$(ARCH)/ kernel/ vmlinux.lds生成内核映象文件vmlinux。,内核的Kconfig分析,所有配置工具都是通过读取arc/$(ARCH)/Kconfig文件来生成配置界面 这个文件是所有配置文件的总入口,它会包含其他目录的Kconfi
11、g文件。 make menuconfig,得到配置界面如下图所示:,内核的Kconfig分析,内核源码每个子目录中,都有一个Makefile文件和Kconfig文件 Kconfig用于配置内核,它就是各种配置界面的源文件。 内核的配置工具读取各 个Kconfig文件,生成配置界面供开发人员配置内核,最后生成配置文件.config。 内核的配置界面以树状的菜单形式组织,主菜单下有若干个子菜单,子菜单下又有子菜 单或配置选项。每个子菜单或选项可以有依赖关系,这些依赖关系用来确定它们是否显示。 只有被依赖项的父项已经被选中,子项才会显示。,Kconfig文件基本要素:config条目,config条
12、目用来配置一个选项,它用于生成一个变量,这个变量会连同它的 值一起被写入配置文件.config中。 config出现的三种配置结果:,CONFIG_LEDS_S3C24XX=y #对应的文件被编进内核 CONFIG_LEDS_S3C24XX=m #对应的文件被编成模块 CONFIG_LEDS_S3C24XX #对应的文件没有被使用,config条目格式,config关键字,表示一个配置选项的开始。 config变量类型: bool tristate string hex int,注意:prompt关键字可以省略,条件判断,“if expr” “prompt” “if” ,注意:省略了前缀 “C
13、ONFIG_”,config条目格式,依赖关系:缺省值定义:选择选项:帮助信息:,“depends on”/ “requires” ,“default” “if” ,“select” “if” ,“help” or “-help-”,config条目实例分析,Kconfig文件基本要素:menu条目,menu条目用于生成菜单,格式如下:,“menu” “endmenu”,menu “Floating point emulation” config FPE_NWFPE config FPE_NWFPE_XP endmenu,Kconfig文件基本要素:choice条目,choice条目将多个类似
14、的配置选项组合在一起,供用户单选或多选,格式如下:,“choice”“endchoice”,choice prompt “ARM system type”default ARCH_VERSATILE config ARCH_AAEC2000 config ARCH_INTEGRATOR endchoice,Kconfig文件基本要素:comment条目,comment条目用于定义一些帮助信息,它在配置过程中出现在界面的第一行.并且这些 帮助信息会出现在配置文件中(作为注释),格式如下:,“comment” ,menu “Floating point emulation”comment “At
15、least one emulation must be selected”,Kconfig文件基本要素:source条目,source条目用于读入另一个Kconfig文件, 格式如下:配置界面操作方法 配置界面中,以*、或开头的选项表示相应功能的文件被编译进内核中、被编译 成一个模块,或者没有使用。尖括号表示相应功能的文件可以被编译成模块。 按Y键选择将它编译进内核,按M键选择 将它编译成模块,按键将不使用它。也可以按空格键进行循环选择,例如:YNMY。 上/下方向键 空格键,“source” ,source “net/Kconfig”,编译内核的步骤,Step1: 拷贝config_n35为
16、文件.config #cp config_n35 .config Step2: 修改内核目录下的Makefile,修改CROSS_COMPILE ?= arm-linux-Step3: 执行make menuconfig,并保存,如果有问题,以root权限执行 #make menuconfigStep4: 编译内核 #make zImage 编译完成后,zImage放在/arch/arm/boot/zImage,Linux内核配置选项,make menuconfig 配置界面主菜单的类别,配置界面主菜单的类别,“system Type”菜单:系统类型,“Device Drivers”菜单:设备
17、驱动程序,阶段总结,Makefile作用 Kconfig作用 内核配置编译,Linux内核启动过程概述,Linux的启动过程可以分为两部分; 架构/开发板相关的引导过程 后续的通用启动过程,Linux内核启动过程概述,第一阶段:引导阶段 引导阶段通常使用汇编语言编写,它首先检查内核是否支持当前架构的处理器,然后检 查是否支持当前开发板。通过检查后,就为调用下一阶段的start_kernel函数作准备了。这主要分如下两个步骤。 (1)连接内核时使用的虚拟地址,所以要设置页表、使能MMU。 (2)调用C函数start_kernel之前的常规工作,包括复制数据段、清除BSS段、调用start_ker
18、nel函数,Linux内核启动过程概述,编译内核的步骤,Step1: 拷贝config_n35为文件.config #cp config_n35 .config Step2: 修改内核目录下的Makefile,修改CROSS_COMPILE ?= arm-linux-ARM ?= armStep3: 执行make menuconfig,并保存,如果有问题,以root权限执行 #make menuconfigStep4: 编译内核 #make zImage 编译完成后,zImage放在/arch/arm/boot/zImage,引导阶段代码分析,arch/arm/kernel/head.S是内核
19、执行的第一个文件,78 ENTRY(stext) 79 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC ensure svc mode 80 and irqs disabled 81 bl _lookup_processor_type r5=procinfo r9=cpuid 82 movs r10, r5 invalid processor (r5=0)? 83 beq _error_p yes, error p 84 bl _lookup_machine_type r5=machinfo 85 movs r8, r5 invalid machin
20、e (r5=0)? 86 beq _error_a yes, error a ,CPU类型ID,arch/arm/kernel/head.S中执行的两个重要工作: 校验CPU ID 校验机器类型ID CPU ID调用_lookup_processor_type函数,确定内核是否支持当前cpu 位于arch/arm/kernel/head-common.S,机器类型ID,_lookup_ machine_type函数 machine_ desc结构中的nr成员 校验CPU ID 校验机器类型ID arch/arm/mach-s3c2440/mach-smdk2440.c,192 MACHINE_
21、START(S3C2440, “SMDK2440“)/* Maintainer: Ben Dooks */.phys_io = S3C2440_PA_UART,.io_pg_offst = (u32)S3C24XX_VA_UART) 18) & 0xfffc,.boot_params = S3C2440_SDRAM_PA + 0x100,.init_irq = s3c24xx_init_irq,.map_io = smdk2440_map_io,.init_machine = smdk2440_machine_init,.timer = &s3c24xx_timer, 202 MACHINE_
22、END,机器类型ID,宏MACHINE_ START、MACHINE_ END在include/asm-arm/mach/arch.h文件中定义上一段代码扩展开,#define MACHINE_START(_type,_name) const struct machine_desc _mach_desc_#_type _attribute_(_section_(“.arch.info“) = .nr = MACH_TYPE_#_type, .name = _name,#define MACHINE_END ;,static const struct machine_desc _mach_des
23、c_S3C2440 _used_attribute_(_section_(“.arch.info.init“) = .nr = MACH_TYPE_S3C2440, .name = “SMDK2440”,start_kernel函数部分代码分析,第二阶段第一个C函数:start_kernel函数 定义在init/main.c中 U-Boot传给内核的参数有两类: 预先存在某个地址的tag列表 调用内 核时在r1寄存器中指定的机器类型ID其中setup_arch函数 是重要初始化函数,setup_arch函数分析,在arch/arm/kernel/setup.c中定义,内核第二阶段启动过程分析,
24、编译内核,解压内核 配置、编译内核,cd /home/student tar xvzf linux-2.6.29.tgz,cp config_mini2440_n35 .config make menuconfig make zImage,烧写、启动内核,烧写内核 启动内核,tftp 0x32000000 uImage nand erase 0x50000 0x200000 nand write.jffs2 0x32000000 0x50000 0x200000,bootm 0x32000000,本章结构,Linux内核配置,Linux内核分析,内核源码结构及Makefile分析,Linux内核配置选项,内核的Kconfig分析,Linux版本及特点,Linux内核启动流程分析,Linux内核启动过程概述,编译、烧写、启动内核,修改内核以支持S3C2440开发板,获取内核源,如何配置、编译内核,分析内核的启动流程,实验,任务一、Linux内核的编译与下载,