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/

 

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

 

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

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

    下面两篇文章是ARM9论坛上的讲解ramdisk文件系统的很不错的文章 今天做了个试验,让Linux2.6.29.4从ramdisk根文件系统启动成功,总结一下. 其中涉及的内容较多,很多东西不再详述 ...

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

    大家好,今天我们学习一下如何从Elrepo或者源代码来安装最新的Linux内核4.0.代号为‘Hurr durr I'm a sheep’的Linux内核4.0是目前为止最新的主干内核.它是稳定版3. ...

  3. 安装 Linux 内核 4.0

    大家好,今天我们学习一下如何从Elrepo或者源代码来安装最新的Linux内核4.0.代号为‘Hurr durr I'm a sheep’的Linux内核4.0是目前为止最新的主干内核.它是稳定版3. ...

  4. linux内核中链表代码分析---list.h头文件分析(一)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...

  5. linux内核中链表代码分析---list.h头文件分析(二)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637598.html linux内核中链表代码分析---list.h头文件分析(二) 16年2月28日16 ...

  6. 从ramdisk根文件系统启动Linux 二

    今天做了个试验,让Linux2.6.29.4从ramdisk根文件系统启动成功,总结一下.其中涉及的内容较多,很多东西不再详述,如需深入研究请查阅相关资料(百度或谷歌一下一大堆). 开发环境:Fedo ...

  7. linux内核链表的移植与使用

    一.  Linux内核链表为双向循环链表,和数据结构中所学链表类似,具体不再细讲.由于在内核中所实现的函数十分经典,所以移植出来方便后期应用程序中的使用. /********************* ...

  8. 小白自制Linux开发板 三. Linux内核与文件系统移植

    上一篇完成了uboot的移植,但是想要愉快的在开发板上玩耍还需要移植Linux内核和文件系统. 1.Linux内核 事实上对于F1C100S/F1C200S,Linux官方源码已经对licheepi ...

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

    学号: 363 本实验来源 https://github.com/mengning/linuxkernel/ 一.实验要求 1.编译内核5.02.qemu -kernel linux-5.0.1/ar ...

随机推荐

  1. 用AJAX自定义日历

    需求分析 在一些购物网站中,都会有促销活动,这些活动都在日历上标注出来,如何通过Ajax让日历 通过读取数据库中的信息,正确的把促销活动标注在日历上,本文通过自定义日历来实现这 个问题. 技术难点 日 ...

  2. Inside Microsoft SQL Server 2008: T-SQL Querying 读书笔记之查询优化

    一. 自顶向下优化方法论 1. 分析实例级别的等待 在实例级找出什么类型的等待占用大部分的时间,通过sys.dm_os_wait_stats select wait_type, --等待类型 wait ...

  3. Django开发网站(四)

    模型: 配置数据库 首先保证数据库已经安装,默认在Ubuntu下已经安装了sqlite3数据库,然后在项目名下的配置文件settings.py修改如下代码: 安装sqlite3 DATABASES = ...

  4. shell调用sqlplus批量执行sql文件

    在最近的工作中,经常需要批量执行一些DML, DDL, PL/SQL语句或导入一些Function, Procedure.因为support的国家比较多,常常需要一个登陆到一个国家的数据库上执行完成后 ...

  5. Qt的gzip模块实现

    一直没找到Qt中方便的gzip模块,于是自己动手,调用zlib模块实现了一份. 目标:  1.gzip的压缩与解压 2.内存中操作 3.方便的Qt接口   实现分析: gzip 压缩算法为 defla ...

  6. 轻仿QQ音乐之音频歌词播放、锁屏歌词-b

    先上效果图 歌词播放界面 音乐播放界面 锁屏歌词界面 一. 项目概述 前面内容实在是太基础..只想看知识点的同学可以直接跳到第三部分的干货 项目播放的mp3文件及lrc文件均来自QQ音乐 本文主要主要 ...

  7. 在工程中添加pch文件

    在Xcode6之前,新建一个工程的时候,系统会帮我们自动新建一个以工程名为名字的pch (precompile header)文件,在开发过程中,可以将那些整个工程都广泛使用的头文件包含在该文件下,编 ...

  8. 使用Yeoman搭建 AngularJS 应用 (11) —— 让我们搭建一个网页应用

    原文地址:http://yeoman.io/codelab/prepare-production.html 让我们发布这个应用 优化产品的文件 为了创建应用的产品版本,我们想做如下的事情 检查你的代码 ...

  9. Xcode 向6.0以后版本添加iOS开发空白模板

    打开finder,找到应用程序,找到xcode 右键显示包内容.按照如下目录进行查找:Contents ▸ Developer ▸ Platforms ▸ iPhoneOS.platform ▸ De ...

  10. MySQL的基本命令

    MySQL的基本命令 启动:net start mySql; 进入:mysql -u root -p/mysql -h localhost -u root -p databaseName; 列出数据库 ...