内核

  • Post author:
  • Post category:其他




内核

解压缩、打补丁、配置、编译

配置:直接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



版权声明:本文为qq_43604517原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。