Linux内核3.0移植并基于Initramfs根文件系统启动

Linux内核移植与启动

Target borad:FL2440

Bootloader:U-boot-2010.09

交叉编译器:buildroot-2012.08

1.linux内核基础知识

首先,磨刀不误砍柴工。在动手进行linux内核移植之前,我们有必要对linux内核进行一定的了解。

1.1 Linux内核启动过程概述

一个嵌入式Linux系统从软件角度看可以分为四个部分: 

引导加载程序(Bootloader),Linux内核,文件系统,应用程序。

其中Bootloader是系统启动或复位以后执行的第一段代码,它主要用来初始化处理器及外设,然后调用Linux内核,linux内核在完成系统的初始化之后需要挂载某个文件系统作为根文件系统(rootfs),根文件系统是linux系统的核心组成部分,也是内核启动时首先要挂载的就是根文件系统。它可以作为linux系统中文件和数据的存储区域,通常它还包括系统配置文件和运行应用程序需要的库,保证了人和内核的信息交互。应用程序则是嵌入式系统所要达到的目标,一切的准备都是为了实现程序。若是没有应用程序,硬件上再精良嵌入式系统都没有实用意义。

Bootloader:在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。Bootloader在它完成CPU和相关硬件的初始化之后,再将操作系统映像或固化的嵌入式应用程序装在到内存中然后跳转到操作系统所在的空间,启动操作系统运行。它最根本的功能就是为了启动linux内核. 为了启动内核Bootloader要依次完成

初始化RAM—初始化串口—检测处理器类型—设置Linux启动参数(bootargs)—调用Linux内核镜像

文件系统:Linux文件系统中的文件是数据的集合,文件系统不仅包含着文件中的数据而且还有文件系统的结构,所有Linux 用户和程序看到的文件、目录、软连接及文件保护信息等都存储在其中。

1.2 编译环境交叉编译器的制作

交叉编译器本节不过多介绍。但我们必须知道若要实现人,虚拟机,开发板之间的信息传递就必须首先制作交叉编译器来帮助我们编译。在做好交叉编译器准备好编译环境之后我们就可以开始进行纯内核移植了。(在此使用的交叉编译器为buildroot-2012.08)

2.Linux内核移植与启动

2.1下载并解压缩linux-3.0.tar.bz2 源代码

首先到 Linux Kernel 官方网站www.kernel.org下载得到 linux-3.0-rc4.tar.bz2 文件,把它放到一个你有权限读写的文件夹,运行下面命令解压缩并进入解压后的文件夹:

$ tar -xjf linux-3.0.tar.bz2

$ cd linux-3.0

2.2配置内核编译参数

1. 首先修改顶层目录的Makefile文件

$ vim  Makefile

这里首要便是交叉编译器环境变量和选择开发平台类型

然后要将生成的zimage拷贝到当前目录,再手动增加mkimage工具来自动把Zimage生成可执行的.bin文。

注:内核编译之后会生成两个文件。一个Image,一个Zimageimage为内核映像文件,而Zimage为内核映像压缩文件。Image大约为4M,而Zimage不到2M

===============================================================================

@@ -192,8 +192,8 @@

 # Default value for CROSS_COMPILE is not to prefix executables

 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile

 export KBUILD_BUILDHOST := $(SUBARCH)

- ARCH       ?= $(SUBARCH)

- CROSS_COMPILE  ?= $(CONFIG_CROSS_COMPILE:"%"=%)

+ARCH       ?= arm

+CROSS_COMPILE?= /opt/buildroot-2012.08.packet/buildroot-2012.08/arm920t/usr/bin/arm-linux-

 

 # Architecture as present in compile.h

 UTS_MACHINE    := $(ARCH)

@@ -557,6 +557,9 @@

 # This allow a user to issue only ‘make‘ to build a kernel including modules

 # Defaults to vmlinux, but the arch makefile usually adds further targets

 all: vmlinux

+  cp arch/arm/boot/zImage . -f

+ mkimage -A arm -O linux -T kernel -C none -a 30008040 -n "Linux Kernel" -d zImage \ linuxrom-s3c2440.bin

+   rm -f zImage

 

 

ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE

 KBUILD_CFLAGS  += -Os

@@ -1201,6 +1204,7 @@

        -o -name ‘.*.rej‘ -o -size 0 \

        -o -name ‘*%‘ -o -name ‘.*.cmd‘ -o -name ‘core‘ \) \

        -type f -print | xargs rm -f

+       @rm -f linuxrom-s3c2440.bin

2.修改晶振频率

因为我使用的是FL2440的开发板,根据datesheet可知晶振频率为12M。所以下一步修改晶振频率。

$ vim arch/arm/mach-s3c2440/mach-smdk2440.c

============================================================================ 

@@ -160,7 +160,7 @@

 static void __init smdk2440_map_io(void)

 {

    s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));

--   s3c24xx_init_clocks(16934400);

+   s3c24xx_init_clocks(12000000);

    s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));

 }

3. 修改驱动的串口

vim drivers/tty/serial/samsung.c

===========================================================================

@@ -54,7 +54,7 @@

 

 /* UART name and device definitions */

 

-- #define S3C24XX_SERIAL_NAME    "ttySAC"

+ #define S3C24XX_SERIAL_NAME    "ttyS"

  #define S3C24XX_SERIAL_MAJOR   204

  #define S3C24XX_SERIAL_MINOR   64

参考mini2440的.config文件作为我们的默认.config文件。改好之后再

$ Make menuconfig

打开文本窗口来选定即将要编译的模块,保存后会将里面的信息保存到同时生成的.config配置文件中。

另外:make menuconfig时出来的文本窗口中的信息是通过读取在内核源代码目录下的Kconfig文件来配置的。根据Makefile文件来编译,而Makefile文件中的变量则通过.config来进行赋值操作。仅仅在Kconfig中添加选项。

4.修改MACHINE ID设备编号

同样因为是做FL2440的内核,所以我们选择三星SMDK2440这个开发板。因为我U-boot中使用的machine id为1999,而且我使用的是s3c2440这个板子。

将mini2440和和s3c2440的machineID对调。

$ vim arch/arm/tools/mach-types

配置就绪之后

Make

显示成功

此时已经会生成一个linux-s3c2440.bin的可执行二进制文件。

5.对nandflash进行分区

=========================================================================================================

@@ -106,49 +106,39 @@

},

};

-/* NAND parititon from 2.4.18-swl5 */

+/* NAND parititon from 2.4.18-swl5,modify by Handy 2014.11.30 */

static struct mtd_partition smdk_default_nand_part[] = {

[0] = {

-       .name   = "Boot Agent",

-       .size   = SZ_16K,

+       .name   = "bootloader",

+       .size   = SZ_1M,

.offset = 0,

},

[1] = {

-       .name   = "S3C2410 flash partition 1",

-       .offset = 0,

-       .size   = SZ_2M,

+       .name   = "linux",

+       .offset = MTDPART_OFS_NXTBLK,

+       .size   = SZ_1M*15,

},

[2] = {

-       .name   = "S3C2410 flash partition 2",

-       .offset = SZ_4M,

-       .size   = SZ_4M,

+       .name   = "rootfs",

+       .offset = MTDPART_OFS_NXTBLK,

+       .size   = SZ_1M*40,

},

[3] = {

-       .name   = "S3C2410 flash partition 3",

-       .offset = SZ_8M,

-       .size   = SZ_2M,

+       .name   = "apps",

+       .offset = MTDPART_OFS_NXTBLK,

+       .size   = SZ_1M*50,

},

[4] = {

-       .name   = "S3C2410 flash partition 4",

-       .offset = SZ_1M * 10,

-       .size   = SZ_4M,

+       .name   = "data",

+       .offset = MTDPART_OFS_NXTBLK,

+       .size   = SZ_1M*50,

},

[5] = {

-       .name   = "S3C2410 flash partition 5",

-       .offset = SZ_1M * 14,

-       .size   = SZ_1M * 10,

-   },

-   [6] = {

-       .name   = "S3C2410 flash partition 6",

-       .offset = SZ_1M * 24,

-       .size   = SZ_1M * 24,

-   },

-   [7] = {

-       .name   = "S3C2410 flash partition 7",

-       .offset = SZ_1M * 48,

+       .name   = "backup",

+       .offset = SZ_1M * 100,

.size   = MTDPART_SIZ_FULL,

-   }

+   },

};

板子上nandflash256M,给bootloader1M用来启动,内核15M以及40M的根文件系统。其他自由分配。

注意:此时若要再进行分区就要选择相应的文件系统。Nandflash比较常用的有yaffs2,ubifs,cramfs以及initramfs等等。

$  make

此时能编译成功,但是生成的linux-s3c2440.bin文件依旧不能在板子上跑起来。

因为内核启动时首先挂载的是根文件系统,我们还没有做根文件系统给予内核支持,系统会出错而退出启动。

3. 添加根文件系统支持

1、根文件系统简介

文件系统是对一个存储设备上的数据和元数据进行组织的机制。这种机制有利于用户和操作系统的交互。而根文件系统则是所有文件系统的根,我理解的是所有文件系统都是由根文件系统扩展开来的。而若是没有根文件系统则谈不上其他的文件系统。根文件系统它包含系统引导以及其他文件系统所能挂载的必要文件。

 

什么是根文件系统首先是一种文件系统,但是相对于普通的文件系统,它的特殊之处在于,它是内核

启动时所mount的第一个文件系统。

 而Linux又支持多种文件系统,包括ext2ext3vfatntfsiso9660jffsromfsnfs等,为了对各类文件系统 进行统一管理,Linux引入了虚拟文件系统VFS(Virtual File System),为各类文件系统提供一个统一的操作界面和应用编程接口。Linux启动时,第一个必须挂载的是根文件系统;若系统不能从指定设备上挂载根文件系统,则系统会出错而退出启动。之后可以自动或手动挂载其他的文件系统。因此,一个系统中可以同时存在不同的文件系统。

 不同的文件系统类型有不同的特点,因而根据存储设备的硬件特性、系统需求等有不同的应用场合。在嵌入式Linux应用中,主要的存储设备为 RAM(DRAM, SDRAM)和ROM(常采用FLASH存储器),常用的基于存储设备的文件系统类型包括:jffs2, yaffs, cramfs, romfs, ramdisk, ramfs/tmpfs等。

2、根文件系统支持

本文主要写内核的移植与启动,所以选择了制作很简单的initramfs文件系统作为根文件系统,它能伴随内核编译时同时与内核生成一个镜像而能与之一起启动。

$ Make menuconfig

进去选择General setup编译模块

在下面选择Initial RAM filesystem .....即initramfs文件系统,然后选择支持initramfs的源文件系统包所处位置。这里为../../rootfs/rootfs_tree/

 

在选择保存后即可连接开发板。重新编译内核后下载到板子上便可以启动了!

 

时间: 2024-08-06 11:55:52

Linux内核3.0移植并基于Initramfs根文件系统启动的相关文章

从ramdisk根文件系统启动Linux成功,及使用initramfs启动linux

下面两篇文章是ARM9论坛上的讲解ramdisk文件系统的很不错的文章 今天做了个试验,让Linux2.6.29.4从ramdisk根文件系统启动成功,总结一下. 其中涉及的内容较多,很多东西不再详述,如需深入研究请查阅相关资料(百度或谷歌一下一大堆).开发环境:Fedora 9交叉编译工具链:arm-linux-gcc 4.3.2 with EABI嵌入式Linux内核版本:2.6.29.4-FriendlyARM.昨天写贴子的时候具体记不清了,今天起来启动开发板用uname -r查一下,就是

Linux内核,文件系统移植过程中出现的一些问题与解决办法

1.bootm地址和load address一样 此种情况下,bootm不会对uImage header后的zImage进行memory move的动作,而会直接go到entry point开始执行.因此此时的entry point必须设置为load address + 0x40.如果kernel boot过程没有到uncompressing the kernel,就可能是这里设置不对. boom address == load address == entry point - 0x40 2.

安装 Linux 内核 4.0

大家好,今天我们学习一下如何从Elrepo或者源代码来安装最新的Linux内核4.0.代号为‘Hurr durr I'm a sheep’的Linux内核4.0是目前为止最新的主干内核.它是稳定版3.19.4之后发布的内核.4月12日是所有的开源运动爱好者的大日 子,Linux Torvalds宣布了Linux内核4.0的发布,它现在就已经可用了.由于包括了一些很棒的功能,例如无重启补丁(实时补丁),新的升级驱动,最新的 硬件支持以及很多有趣的功能都有新的版本,它原本被期望是一次重要版本.但是实

如何在Ubuntu/CentOS上安装Linux内核4.0

大家好,今天我们学习一下如何从Elrepo或者源代码来安装最新的Linux内核4.0.代号为‘Hurr durr I'm a sheep’的Linux内核4.0是目前为止最新的主干内核.它是稳定版3.19.4之后发布的内核.4月12日是所有的开源运动爱好者的大日 子,Linux Torvalds宣布了Linux内核4.0的发布,它现在就已经可用了.由于包括了一些很棒的功能,例如无重启补丁(实时补丁),新的升级驱动,最新的 硬件支持以及很多有趣的功能都有新的版本,它原本被期望是一次重要版本.但是实

从ramdisk根文件系统启动Linux 二

今天做了个试验,让Linux2.6.29.4从ramdisk根文件系统启动成功,总结一下.其中涉及的内容较多,很多东西不再详述,如需深入研究请查阅相关资料(百度或谷歌一下一大堆). 开发环境:Fedora 9交叉编译工具链:arm-linux-gcc 4.3.2 with EABI嵌入式Linux内核版本:2.6.29.4-FriendlyARM.昨天写贴子的时候具体记不清了,今天起来启动开发板用uname -r查一下,就是叫做2.6.29.4-FriendlyARM,帖子已经改好了.本文就是友

linux内核链表的移植与使用

一.  Linux内核链表为双向循环链表,和数据结构中所学链表类似,具体不再细讲.由于在内核中所实现的函数十分经典,所以移植出来方便后期应用程序中的使用. /*********************************** 文件名:kernel link list of linux.h 作者:Bumble Bee 日期:2015-1-31 功能:移植linux内核链表 ************************************/ /*链表结点数据结构*/ struct lis

2019-举例跟踪分析Linux内核5.0系统调用处理过程

简介 学号520 实验环境基于ubuntu18.04 选择系统调用号20 getpid()分析 实验目的 学会使用gdb工具跟踪linux内核函数调用 学会使用C代码和嵌入式汇编使用系统中断 分析system_call中断处理过程 实验步骤 1.下载linux5.0.1内核并编译 wget https://mirrors.aliyun.com/linux-kernel/v5.x/linux-5.0.1.tar.xz xz -d linux-5.0.1.tar.xz tar -xvf linux-

Linux内核编程-0:来自内核的 HelloWorld

Linux内核编程一直是我很想掌握的一个技能.如果问我为什么,我也说不上来. 也许是希望有一天自己的ID也出现在内核开发组的邮件列表里?或是内核发行文件的CREDITS文件上? 也许是吧.其实更多的,可能是对于底层的崇拜,以及对于内核的求索精神. 想到操作系统的繁杂,想到软件系统之间的衔接,内心觉得精妙的同时,更是深深的迷恋. 所以从这篇文章开始,我要真正的走进Linux内核里了,让代码指引我,去奇妙的世界一探究竟. 在这篇文章中,一起来对内核说Hello World. 本次的编程环境: Cen

分析Linux内核5.0系统调用处理过程

学号: 363 本实验来源 https://github.com/mengning/linuxkernel/ 一.实验要求 1.编译内核5.02.qemu -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img3.选择系统调用号后两位与您的学号后两位相同的系统调用进行跟踪分析https://github.com/mengning/menu4.给出相关关键源代码及实验截图,撰写一篇博客(署真实姓名或学号最后3位编号),并在博客文章中