Linux内核移植

33 篇文章 0 订阅
16 篇文章 2 订阅

Linux内核移植

忙于论文,都没有时间写博客记录笔记了,趁着周五不想搞论文,记录以下最近看的Linux内核书

Linux内核启动过程

在移植Linux之前,先了解它的启动过程。Linux的启动过程分为两部分:架构/开发板相关的引导过程、后续的通用启动过程。如下图所示是ARM架构处理器上Linux内核vmlinux的启动过程。之所以强调是vmlinux,是因为其他格式的内核在进行与vmlinux相同的例如流程之前会有一些独特的操作。比如对应压缩格式的内核zImage,它首先自解压得到vmlinux,然后执行vmlinux开始“正常的”启动流程。
引导阶段通常使用汇编语言编写,它首先检查内核是否支持当前架构的处理器,然后检查是否支持当前开发板。通过检查后,就为调用下一阶段的start_kernel 函数作准备了。这主要分如下两个步骤:

  • (1)连接内核时使用的虚拟地址,所以要设置页表、使能MMU。
  • (2)调用C函数 start_kernel 之前的常规工作,包括复制数据段、清除BSS段、调用 start_kernel 函数。
    第二阶段的关键代码主要使用C语言编写。它进行内核初始化的全部工作,最后调用 rest_init 函数启动 init 过程,创建系统第一个进程:init 进程。在第二阶段,仍有部分架构/开发板相关的代码。如下图中 setup_arch 函数用于进行架构/开发板相关的设置(比如重新设置页表,设置系统时钟、初始化串口等)。
    在这里插入图片描述

修改内核以支持 S3C2410/S3C2440 开发板

  • 首先配置、编译内核,确保内核可以正确编译。得到内核源码后,先修改顶层 Makefile
185 ARCH ?= $(SUBARCH)
186 CROSS_COMPILE ?=
改为
185 ARCH ?= arm
186 CROSS_COMPILE ?= arm-linux-
  • 然后执行如下命令,使用arch/arm/configs/S3C2410_defconfig 文件来配置内核,它生成 .config 配置文件,以后就可以直接使用 “ make menuconfig” 修改配置
make smdk2401_defconfig
  • 最后编译生成内核,执行 “make” 将顶层目录下生成内核映像文件 vmlinux;执行 “make uImage” 除生成 vmlinux 外,还在 arch/arm/boot/ 目录下生成 U-Boot 格式的内核映像文件 uImage 。我们使用 ”make uImae“
  • 对于 S3C2410 开发板,上面生成 uImage 是可以使用的。在U-Boot 控制界面中使用如下命令下载 uImage 并启动它:
tftp 0x32000000 uImage 或 nfs 0x30000000 192.168.10.109:/work/nfs_root/uImage
bootm 0x32000000
  • 但是对于S3C2410 开发板,使用同样的命令启动 uImage ,在打印如下信息之后(注意,这些信息是内核的misc.c文件解压内核时打印的),就出现了一大堆乱码,如下所示:
Start kernel........
Uncompressing Linux..................................done
,booting the kernel

所以,Linux2.6.22.6 还不支持本书所用的 S3C2440 开发板,需要进行一些修改,至于要修改哪些文件,需要了解内核的启动代码。

内核启动第二阶段的函数调用过程(以S3C2440开发板为例),相同缩进的函数表示它们是在同一个函数中被调用:

start_kernel ->
	setup_arch ->
		setup_processor
		setup_machine
		...
		parse_tags
		...
		parse_cmdline
		paging_init ->
			devicemaps_init ->
				mdesc->map_io() ->
					s3c24xx_init_io
					s3c24xx_init_clocks
					s3c24xx_init_uarts
		...
		console_init ->
			s3c24xx_serial_initconsole
				register_console(&s3c24xx_serial_console)
				...

修改内核

  • 在 arch/arm/mach-s3c2440/mach-smdk2440.c 做如下修改:
//修改前
s3c24xx_init_clocks(16934400);

//修改后
s3c24xx_init_clocks(12000000);

  • 然后执行 make uImage ,生成 uImage。对于S3C2410,S3CC2440开发板,上面生成的 uImage 都可以使用了。
    把 uImage 放到tftp 服务器目录下,或者放到 Linux 中/work/nfs_root 目录下,然后在 U-Boot 控制界面中使用如下命令下载 uImage 并启动它。
tftp 0x32000000 uImage 或 nfs 0x30000000 192.168.10.109:/work/nfs_root/uImage
bootm 0x32000000
  • 可以看到内核的启动信息,最后出现 panic 信息(这需要修改 mtd 分区、增加对 yaffs 文件系统的支持)

修改MTD分区

MTD(Memory Technology Device),即内存技术设备,是LInux中对ROM,NOR Flash,NAND Flash 等存储设备抽象出来的一个设备层,它向上提供统一的访问接口:读、写、擦除等;屏蔽了底层硬件的操作、各类存储设备的差别。得益于 MTD 设备的作用,重新划分 NAND Flash 的分区很简单。

驱动对设备的识别过程

驱动对设备识别时,有以下两种方法:
(1)驱动程序本身带有设备的信息,比如开始地址、中断号等;加载驱动程序时,就可以根据这些信息来识别设备
(2)驱动程序本身没有设备的信息,但是内核中已经(或以后)根据其他方式确定了很多设备的信息;加载驱动程序时,将驱动程序与这些设备逐个比较,确定两者是否匹配(mach)。如果驱动程序与某个设备匹配,就可以通过该驱动操作这个设备了。
内核中常使用第二种方法来识别设备,这可以将设备集中在一个文件中管理,当开发板的配置改变时,便于修改代码
在内核文件 include/linux/platform_device.h 中,定义了两个数据结构来表示这些设备和驱动程序:platform_device 结构用来描述设备的名称、ID、所占用的资源(比如内存地址/大小,中断号)等;platform_driver 结构用来描述各种操作函数,比如枚举函数、移除设备函数、驱动的名称等。
内核启动后,首先构造链表将描述设备的 platform_device 结构组织起来,得到一个设备的列表;当加载某个驱动程序的 platform_driver 结构时,使用一些匹配函数来检查驱动程序能否支持这些设备,常用的检查方法很简单:比较驱动程序和设备的名称。

修改MTD分区

要改变分区时,修改 arch/arm/plat-s3c24xx/common-smdk.c 文件中的 smdk_default_nand_part 结构即可。在此将 NAND Flash 和划分为3个分区,前 2MB 用于存放内核,接下来的 8MB 用于存放 JFFS2 文件系统,剩下的用来存放 YAFFS 文件系统。

static struct mtd_partition smdk_default_nand_part[] = {
    [0] = {
        .name   = "kernel",
        .size   = SZ_2M,
        .offset = 0,
    },  
    [1] = { 
        .name   = "jffs2",
        .offset = MTDPART_OFS_APPEND,
        .size   = SZ_8M,
    },  
    [2] = { 
        .name   = "yaffs",
        .offset = MTDPART_OFS_APPEND,
        .size   = MTDPART_SIZ_FULL,
    },  
};

其中的 MTDPART_OFS_APPEND 表示当前分区紧接着上一个分区,MTDPART_SIZ_FULL 表示当前分区的大小为剩余的Flash空间。
之后执行 make uImage 重新生成内核

移植 YAFFS 文件系统

YAFFS(yet another flash file system)是一种类似脚本于 JFFS/JFFS2 、专门为 NAND Flash 设计的嵌入式系统,适用于大容量的存储设备。

移植 yaffs 分两个步骤:

  • 将 yaffs2 代码加入内核。
    这可以通过yaffs2 目录下的脚本文件 patch-ker.sh 来给内核打补丁
  • 配置、编译内核

最后执行 make uImage 编译内核

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值