内核
解压缩、打补丁、配置、编译
配置:直接make menuconfig太复杂不用,或者在arch/arm/configs目录下找相似文件s3c2410_defconfig,配置结果保存在.config文件中,或者cp config_厂家 .config,然后在make menuconfig。
配置结果生成.config文件,里面有很多配置项,ynm。
配置项谁使用:
1 c源码 宏
2.子目录Makefile m(模块)、y(进内核)
3.include/config/auto.conf .config生成,生成子目录makefile,被顶层makefile包含
4.include/linux/autoconf.h .config生成,c源码的头文件0或1
编译:make uImage生成的内核有头部,给uboot用。
顶层目录Makefille
arch/arm/Makefile :make uImage ,被顶层目录Makefile包含
子目录Makefile
.config:生成autoconf.h给源码,auto.conf被顶层Makefile包含
makefile分析:
1) 决定编译那些文件:顶层目录、arch/arm/Makefile、各级子目录(auto.conf):
obj-y、obj-m、lib-y、进入下级子目录
2) 怎样编译这些文件:CFLAGS、AFLAGS、LDFLAGS、ARFLAGS
3) 怎样连接这些文件,顺序如何:
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
vmlinux-lds :=arch/arm/kernel/vmlinux.lds
vmlinux-all :=$(vmlinux-init) $( vmlinux-main)
vmlinux-init :=$(head-y) $(init-y)
vmlinux-main :=$(core-y) $(libs-y) $(drivers-y) $(net-y)
分析结果:第一个文件:arch/arm/kernel/head.S
连接脚本:arch/arm/kernel/Vmlinux.lds
内核启动:thekernel(0,机器ID,启动参数基地址)
处理uboot传入的参数
判断是否支持这个CPU
判断是否支持这个单板
建立页表
使能MMU
跳到start_kernel
挂载根文件系统
最终目的:应用程序
start_kernel
setup_arch //解析u-boot传入的启动参数(tags)
setup_command_line //解析u-boot传入的命令行参数bootargs,保存在数组
parse_early_param
do_early-param
从_setup_start到_setup_end,调用early函数
unknow_bootoption
obsolete_checksetup //分析命令行参数
从_setup_start到_setup_end,调用非early函数
rest_init
kernel_init
prepare_namespace
mount_root //挂接根文件系统,由命令行参数root指定
init_post
// 执行应用文件
分区是在代码中写死的: root=/dev/mtdblock3
arch/arm/plat-s3c24xx/common-smdk.c中的smdk_default_nand_part[]数组(.name,.size,.offset)定义的(bootloader,params,kernel,root)。
移植Linux3.4.2
修改Makefile(ARCH、CROSS_COMPILE),选择默认配置(s3c2410_defconfig),make uImage(编译器版本4.3.2)。
1) 启动内核时如果getenv(“machid”)环境变量存在就使用它,否则使用默认的。
在uboot中set machid 16a,save 设置机器ID
2) 串口输出乱码:修改默认晶振
arch\arm\mach-s3c24xx\mach-smdk2440.c中修改s3c24xx_init_clocks(12000000);在uboot里set bootargs console=ttySAC0,115200… save设置波特率
3) 无法挂载根文件系统,修改MTD分区:
在内核中搜索打印信息找到arch\arm\mach-s2c24xx\common-smdk.c文件,里面可以修改分区信息,smdk_default_nand_part数组项是各分区信息。
4) 无法挂载文件系统:制作文件系统busybox-1.20.0(4.3.2库)
5) SIGILL错误,make menuconfig重新配置内核支持EABI(Embedded application binary interface嵌入式应用二进制接口)。
6) 移植yaffs文件系统:压缩的文件系统。git获取源码,打补丁,配置内核支持yaffs,编译使用uImage。
7) 裁剪内核:分区时划分2M,在.config查看y不需要的选项,make menuconfig裁剪
不需要支持的单板,去掉不需要的文件系统ext等,不用的设备鼠标、键盘、USB触摸 屏声卡等设备。
文件系统
linux可以将flash、磁盘等存储设备划分分区,不同分区存放不同类别的文件。在一个分区上存放系统启动所必须的文件,比如内核镜像(单独的分区)、第一个进程init、shell程序、库等。这些必需、基本的文件合称为根文件系统,它们存放在一个分区中。Linux系统启动后首先挂接这个分区,称为挂接根文件系统。其它分区上所有目录、文件的集合称为文件系统。其它分区挂接在某个目录上,这个目录被称为挂接点。分区上存储文件的格式称为文件系统类型yaffs、jffs、ext2、fat32等。
启动第1个应用程序init_post():
init进程
1、打开标准输入\输出\错误设备:
open(/dev/console); sys.dup(0); sys_dup(0) 终端,对应stdin、stdout、stderr;
2、通过run_init_process启动:
命令行传入的init=xxx 或/sbin/init(busybox集成的init程序)、/etc/init、/bin/init、bin/sh
Busybox集成的init程序: 其它进程的发起者和控制者
1) 读取
配置文件
file = fopen(INITTAB, “r”)
2) 解析配置文件
new_init_action 1.创建一个init_action结构,用这些内容填
2.把这个结构放入init_action_list链表
3)执行用户程序
run_actions(SYSINIT); run_actions(WAIT); run_actions(ONCE) 系统运行前期执行
while (1) { run_actions(RESPAWN); run_actions(ASKFIRST) } 系统正常运行时执行
restart, ctrlaltdel, shutdown 系统退出时执行
配置文件:/etc/inittab格式
每个条目来定义一个子进程,并确定它的启动方法。
<id>:<runlevels>:<action>:< process >
id => /dev/id,用作终端:stdin, stdout, stderr : print , scanf ,err(终端是标准输入/出/错误)
runlevels:省略
action :执行时机sysinit, respawn, askfirst, wait, once,restart, ctrlaltdel, shutdown
process :应用程序或脚本
制作根文件系统
所谓制作根文件系统,就是创建各种目录,并且在里面创建各种文件。
最小根文件系统:
1)init=>busybox
2)/dev/console /dev/null
3)/etc/inittab
4)配置文件指定的应用程序
5)C库
/bin,/sbin目录:配置编译busybox:make menuconfig,修改Makefile交叉编译,编译,安装指定安装目录
1)unix命令的集合(ls,cp等),创建/bin和/sbin目录下的可执行文件
2)mdev命令是udev的简化
3)集成的init程序
/dev目录:mknod命令创建console和null设备文件
使用busybox的mdev机制自动创建设备节点,参考 busybox文件:
1)创建etc/
fstab
要自动挂接的文件系统(sysfs、tmpfs减少对flash的读写)
2)etc/
init.d/rcS
(在inittab中系统启动时运行的脚本)中mount -a是根据etc/fstab的内容挂接里面的文件系统,
mdev -s
创建原有设备,支持热拔插(自动创建设备结点)
/etc目录:创建etc/
inittab
文件,里面是执行-/bin/sh等程序 和 脚本rcS。rcS中mount -a,是挂接etc/fstab中/proc(虚拟文件系统)等文件系统
/lib目录:安装C库,把交叉编译工具链的*.so*(动态库和加载器)文件复制到lib目录
创建/proc、/mnt、/tmp、/sys、/root空目录
制作
制作yaffs文件系统:编译出mkyaffs2image工具
mkyaffs2image first_fs first_fs.yaffs2
制作jffs文件系统:安装zlib(压缩的文件系统),编译出mkfs.jffs2工具
mkfs.jffs2 -n -s 2048(页大小)-e 128KiB(块大小) -d first_fs -o first_fs.jffs2
修改bootargs中rootfstype=jffs2制定文件系统类型,默认yaffs
网络文件系统:文件系统放在服务器上
从flash上启动根文件系统再用命令挂接NFS:1)服务器允许那个目录可以被挂接 2)挂接
直接NFS启动:
set bootargs noinitrd root=/dev/nfs nfsroot=192.168.1.190:/work/nfs_root/first_fs
ip=192.168.1.17:192.168.1.190:192.168.1.1:255.255.255.0::eth0:off
单板IP 服务器IP 子网掩码 网卡 自动配置
init=/linuxrc console=ttySAAC0