嵌入式Linux——编译linux内核

时间:2023-01-23 18:44:22

编译Linux源码是编写嵌入式Linux程序和驱动的必要条件,本篇主要介绍编译Linux for arm内核的过程


宿主机Linux版本:Linux Mate 4.4.0-22-generic #40-Ubuntu SMP Thu May 12 22:03:15 UTC 2016 i686 athlon i686 GNU/Linux
宿主机(x86)gcc版本:gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2.1)
目标机Linux内核版本:Linux (none) 2.6.28.7 #339 Wed Sep 7 14:59:33 PDT 2011 armv4tl unknown
目标机板卡:fl2440
交叉编译工具链版本:gcc version 4.9.1 20140710 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.07 - Linaro GCC 4.9-2014.07)


  1. 准备内核和相关补丁
    linux-2.6.28.7 :
    https://www.kernel.org/pub/linux/kernel/
    给yaff2文件系统打补丁:
    http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=summary
    ./patch-ker.sh c ../linux-2.6.35
  2. 检查交叉编译环境
    arm-linux-gnueabihf-gcc -v
  3. 根据目标机bootloader修改机器码
    (以下如无特殊说明均是在源码主目录下操作的)

嵌入式Linux——编译linux内核

vim arch/arm/tools/mach-types
由于FL2440的机器码是193(其实就是缺省使用S3C2440的相关设置),所以我们需要修改机器码
删掉
机器码为182和193
修改
机器码362为193
嵌入式Linux——编译linux内核
4. 指定目标机的架构及交叉编译工具路径
vim Makefile
改为以下内容

ARCH              ?= arm 
CROSS_COMPILE ?= /opt/arm/bin/arm-linux-gnueabihf-

嵌入式Linux——编译linux内核
5.增加devfs文件管理器的支持
我们所用的文件系统使用的是devfs文件管理器。
vim fs/Kconfig
找到(可以在命令行用/Pseudo查找)
menu "Pseudo filesystems"
添加如下语句:

config DEVFS_FS
bool "/dev file system support (OBSOLETE)"
default y
config DEVFS_MOUNT
bool "Automatically mount at boot"
default y
depends on DEVFS_FS

帮助理解:Kconfig就是对应着内核的配置菜单。假如要想添加新的驱动到内核的源码中,能够修改Kconfig,这样就能够选择这个驱动,假如想使这个驱动被编译,要修改Makefile。
嵌入式Linux——编译linux内核
6.修改晶振频率
vim arch/arm/mach-s3c2440/mach-smdk2440.c

s3c24xx_init_clocks(12000000);/*s3c24xx_init_clocks(16934400);*/  

可解决打印信息乱码问题。
嵌入式Linux——编译linux内核
7. 修改MTD分区
vim arch/arm/plat-s3c24xx/common-smdk.c

static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "Boot",
.size = 0x00100000,
.offset = 0
},
[1] = {
.name = "MyApp",
.size = 0x003c0000,
.offset = 0x00140000,
},
[2] = {
.name = "Kernel",
.size = 0x00300000,
.offset = 0x00500000,
},
[3] = {
.name = "fs_yaffs",
.size = 0x0f000000,
.offset = 0x00800000,
},
[4] = {
.name = "WINCE",
.size = 0x03c00000,
.offset = 0x04400000,
}
};

嵌入式Linux——编译linux内核
8.关闭ECC校验
vim drivers/mtd/nand/s3c2410.c
找到函数:s3c2410_nand_init_chip

chip->ecc.mode = NAND_ECC_NONE;/*chip->ecc.mode = NAND_ECC_SOFT; */

9.修改nandflash驱动,支持K9F2G08的nandflash
vim drivers/mtd/nand/nand_bbt.c
共需要改两处:

static struct nand_bbt_descr largepage_memorybased = {
.options = 0,
.offs = 0,
.len = 2, // 原数值为2,支持2K每页的flash.K9F1G08是1k每页的flash应改为1,K9F2G08是2k每页的flash
.pattern = scan_ff_pattern
};
static struct nand_bbt_descr largepage_flashbased = {
.options = NAND_BBT_SCAN2NDPAGE,
.offs = 0,
.len = 2, // 原数值为2,支持2K每页的flash.K9F1G08是1k每页的flash应改为1,K9F2G08是2k每页的flash
.pattern = scan_ff_pattern
};

嵌入式Linux——编译linux内核

核心板照片如下图:
嵌入式Linux——编译linux内核

10.开始裁剪内核
把s3c2410的缺省配置写入.config文件。

`make s3c2410_defconfig`

附:如果出现以下错误,
嵌入式Linux——编译linux内核

据说是由于老版本的内核不支持最新的make
找到图中的行修改类似于以下的内容:

修改前:config %config: scripts_basic outputmakefile FORCE
修改后:%config: scripts_basic outputmakefile FORCE
修改前:/ %/: prepare scripts FORCE
修改后: %/
: prepare scripts FORCE

11.开始裁剪
make menuconfig
嵌入式Linux——编译linux内核
12. 配置Kernel Feature–使用ARM EABI编译
嵌入式Linux——编译linux内核
配置文件系统选项
配置yaffs2文件系统
修改配置如下:

 File systems  ---> 
[*] Miscellaneous filesystems --->
<*> YAFFS2 file system support
-*- 512 byte / page devices
-*- 2048 byte (or larger) / page devices
[*] Autoselect yaffs2 format
[*] Cache short names in RAM

配置cpu相关选项
修改配置如下:

System Type  ---> 
S3C2440 Machines --->
[*] SMDK2440
[*] SMDK2440 with S3C2440 CPU module
[*] Support ARM920T processor

去掉S3C2400 Machines、S3C2410 Machines、S3C2412 Machines、S3C2442 Machines的所有选项 ,否则会报错。如果现在make编译内核,内核就可以正常通过编译了.
附:出现错误:
嵌入式Linux——编译linux内核

处理方法:

 删除
@val = @{$canned_values{$hz}};
if (!defined(@val)) {
@val = compute_values($hz);
}
output前面加入
$cv = $canned_values{$hz};
@val = defined($cv) ? @$cv : compute_values($hz);