【嵌入式】S3C2410平台移植linux 2.6.14内核

时间:2023-07-27 09:57:20

小续

第一次接触内核的东西,有点小激动啊

激动归激动,这实验还是要继续做下去,书上三两句话就带过去的,剩下的就留给我们了,着实考验动手能力啊

当编译过内核之后,发现这个过程也不复杂嘛(复杂的是内核的配置),不过对于没接触过的人来说,也能够折腾一段时间的了,所以记下这个过程,其中也有些需要注意的地方,然后给没接触过的人分享下


环境如下

操作系统:ubuntu 12.04LTS

交叉编译工具:arm-linux-gcc 3.2

开发板:FS2410

linux内核:linux 2.6.14

mystery@lcw:~/Downloads$ cat /etc/issue
Ubuntu 12.04.2 LTS \n \l
mystery@lcw:~/Downloads$ arm-linux-gcc -v
Reading specs from /usr/local/arm/bin/../lib/gcc-lib/arm-linux/3.2/specs
Configured with: ./configure --target=arm-linux --prefix=/usr/local/arm/ --with-headers=/home/sylam/armbuild/src/linux/include --disable-shared --disable-threads --enable-languages=c : (reconfigured) ./configure --target=arm-linux --prefix=/usr/local/arm/ --with-headers=/home/sylam/armbuild/src/linux/include
Thread model: posix
gcc version 3.2 mystery@lcw:~/Downloads$ ls /home/mystery/Downloads/
cross-3.2.tar.bz2 linux-2.6.14
eclipse-cpp-juno-SR2-linux-gtk.tar.gz linux-2.6.14.tar.bz2
google-chrome-stable_current_i386.deb wps-office_8.1.0.3724~b1p2_i386.deb
jdk-7u17-linux-i586.tar.gz wps_symbol_fonts.zip
mystery@lcw:~/Downloads$

准备工作

决定在哪里编译你的内核
你需要决定你要在哪里编译你的ARM Linux内核。一个比较好的位置就是在你的home目录,我这里直接下载了解压后就编译了,所以就在download目录下进行的

决定内核的版本号
你需要决定你想要编译哪个版本的linux内核。大多数然想要编译最新版本的稳定内核。有一套表示版本号的机制,可以帮助你决定识别一个特定的发行版本。
对于任何的内核版本x.y.z,
* x -这个是主版本号
* y -这个是次版本号,这里:
偶数表示“稳定的”内核发行
奇数表示"开发"或者"beta"内核发行版本,相对来说不稳定。
* z -这是这个内核的补丁级别。
这个版本号表示了内核版本的主线。我这里按照书上的,选择了linux 2.6.14的内核,大家在www.kernel.org可以找到下载地址哈。


开始工作

1. 首先,我们需要修改目录树根下的Makefile,指明交叉编译器,找银行也要先说明去哪家银行嘛,哈哈

找到

ARCH            ?= $(SUBARCH)
CROSS_COMPILE ?=

修改成

192 ARCH            ?= arm
193 CROSS_COMPILE ?= arm-linux-gcc

<注意1>这里我开始出现了一个错误,在打arm的时候后面多打了一个空格,结果后面编译的时候出现

mystery@lcw:~/Downloads/linux-2.6.14$ make menuconfig
make: *** /home/mystery/Downloads/linux-2.6.14/arch/arm: Is a directory. Stop.
mystery@lcw:~/Downloads/linux-2.6.14$ vim Makefile

好吧,第一次还是老实的慢慢打代码,切勿多出空格来了

2. 然后我们需要设置一下环境变量,知道去哪家银行取钱,然后需要知道银行在哪里啊

mystery@lcw:~/Downloads/linux-2.6.14$ export  PATH=$PATH:/usr/local/arm/bin/

这个路径当然是交叉编译器的位置了,在配置交叉编译器的时候,其实就已经把这个路径写入到配置文件去了,这里主要是说明需要指明银行的地点哈

3. 去银行总得有点事做吧,现在就来配置下这个清单,我也是第一次哈,所以内核产生文件就直接复制了

mystery@lcw:~/Downloads/linux-2.6.14$ cp arch/arm/configs/smdk2410_defconfig .config

<注意2>这里的.config文件应该由配置得到的,但是这之前,我也不知道怎么才算配置成功,对吧,所以先看结果,再回过头来学习,就容易多了,不过这过程还是要说清楚

4. 知道要去银行干什么了,下面就直接去银行与工作人员交涉吧。输入内核配置命令,进行内核选项的选择

内核支持4种不同的配置方法,这几种方法只是与用户交互的界面不同,其实现的功能是一样的;四种方法都是通过读取上面的配置文件“.config”隐藏文件,4种方法如下

make config : 基于文本的最为传统的配置界面,不推荐使用  make menuconfig : 基于文本选单的配置界面,字符终端下推荐使用  make xconfig : 基于图形窗口模式的配置界面,X-Window下推荐使用  make oldconfig : 自动读入“.config”配置文件,并且只要求用户设定上一次没有设定 过的选项

在这4种模式中,make menuconfig使用最为广泛,我这里也使用这种哈

mystery@lcw:~/Downloads/linux-2.6.14$ make menuconfig
HOSTCC scripts/basic/fixdep
scripts/basic/fixdep.c: In function ‘traps’:
scripts/basic/fixdep.c:368:2: warning: dereferencing
………………………
………………………
>> Unable to find the Ncurses libraries.
>>
>> You must install ncurses-devel in order
>> to use 'make menuconfig'
make[2]: *** [scripts/lxdialog/ncurses] Error 1
make[1]: *** [menuconfig] Error 2
make: *** [menuconfig] Error 2

代码有点长,中间省略了。

呃,出错了,不要急,看看错误原因:

>> Unable to find the Ncurses libraries.
>>
>> You must install ncurses-devel in order
>> to use 'make menuconfig'

意思是不能找到Ncurses libraries,你必须在这之前安装ucurses工具,好吧,照做

mystery@lcw:~/Downloads/linux-2.6.14$ sudo apt-get install ncurses-dev
[sudo] password for mystery:
Reading package lists... Done

<注意3>ncurses用于make menuconfig界面显示

后面我无意间又发现了一个错误
mystery@lcw:~/Downloads/linux-2.6.14$ make menuconfig
HOSTCC scripts/lxdialog/checklist.o
HOSTCC scripts/lxdialog/inputbox.o
HOSTCC scripts/lxdialog/lxdialog.o
……………………
scripts/kconfig/mconf arch/arm/Kconfig
# using defaults found in .config
.config:622: trying to assign nonexistent symbol DEVFS_FS
.config:622: trying to assign nonexistent symbol DEVFS_FS
.config:623: trying to assign nonexistent symbol DEVPTS_FS_XATTR
Your display is too small to run Menuconfig!
It must be at least 19 lines by 80 columns.
make[1]: *** [menuconfig] Error 1
make: *** [menuconfig] Error 2

中间也省略了一些哈,你找到错误说明了吗:

<注意4>意思是说你的显示屏太小了,容不下Menuconfig,至少需要19*80的空间,好吧,照做

5. 下面就开始和银行人员交涉吧

mystery@lcw:~/Downloads/linux-2.6.14$ make menuconfig
scripts/kconfig/mconf arch/arm/Kconfig
#
# using defaults found in .config
#
.config:11: trying to assign nonexistent symbol GENERIC_IOMAP

配置选项出来了有木有啊

【嵌入式】S3C2410平台移植linux 2.6.14内核

<注意5>在各级子菜单项中,选择相应的配置时,有3种选择,它们代表的含义分别如下

Y:将该功能编译进内核

N:不将该功能编译进内核

M:将该功能编译成可以在需要时动态插入到内核中的模块

在编译内核的过程中,最麻烦的事情就是配置这步工作了,初次接触linux内核的开发者还真弄不清楚如何选取这些选项,还好这些配置大部分选项都可以使用其默认值,只有一小部分需要根据用户不同的需要选择

<注意6>选择的原则就是:将与内核其它部分关系较远且不经常使用的部分功能编译成为可加载模块,这有利用减小内核的长度,减小内核消耗的内核,简化该功能相应的环境改变时对内核的影响,不需要的功能就不要选,与内核关系紧密而且经常使用的部分功能代码直接编译到内核中

我们进入第二项“通用设置”看看

Linux Kernel v2.6.14 Configuration
------------------------------------------------------------------------------
+----------------------------- General setup -----------------------------+
| Arrow keys navigate the menu. <Enter> selects submenus --->. |
| Highlighted letters are hotkeys. Pressing <Y> includes, <N> excludes, |
| <M> modularizes features. Press <Esc><Esc> to exit, <?> for Help, </> |
| for Search. Legend: [*] built-in [ ] excluded <M> module <> |
| +---------------------------------------------------------------------+ |
| |() Local version - append to kernel release | |
| |[*] Automatically append version information to the version string (N| |
| |[*] Support for paging of anonymous memory (swap) | |
| |[*] System V IPC | |
| |[ ] POSIX Message Queues | |
| |[ ] BSD Process Accounting | |
| |[*] Sysctl support | |
| |[ ] Auditing support | |
| |[ ] Support for hot-pluggable devices | |
| +v(+)-----------------------------------------------------------------+ |
+-------------------------------------------------------------------------+
| <Select><Exit><Help> |
+-------------------------------------------------------------------------+

<注意7>大家注意到了吧,这里选择前面有中括号和圆括号,其实还有个尖括号。用空格键选择相应的选项时会发现中括号中要么是空,要么是“*”;尖括号中可能是空/“*”和“M”,分别表示包含选项/不包含选项和编译成模块;圆括号的内容是要求用户在所提供的几个选项中选择一项。

上面是什么意思呢?我解释下哈。

第一个是圆括号,就是让你从下面的选项中进行选择;我简单的翻译下哈:

( )本地版本-添加到内核发行版

[*]自动添加版本信息到原版本信息后面

[*]支持匿名分页存储

[*]支持系统V IPC通信机制

[  ]支持POSIX消息队列

…………

下面很多,就不看了哈,上面的意思就是:把(中括号中选择了的)自动添加版本信息到原版本信息后面/支持匿名分页存储/支持系统V IPC通信机制等等添加到新的内核版本中去,这下应该懂了吧;至于尖括号选项,就是前面说的Y/N/M,这里就不多说了啊

配置内核主要是根据你需要哪些功能,大家按照<注意6>进行配置就是了

6. 等配置好了,就把工作交给银行人员吧
mystery@lcw:~/Downloads/linux-2.6.14$ make zImage
make: arm-linux-gccgcc: Command not found
CHK include/linux/version.h
UPD include/linux/version.h
SPLIT include/linux/autoconf.h -> include/config/*
SYMLINK include/asm-arm/arch -> include/asm-arm/arch-s3c2410
Generating include/asm-arm/mach-types.h
SYMLINK include/asm -> include/asm-arm
CC arch/arm/kernel/asm-offsets.s
/bin/sh: 1: arm-linux-gccgcc: not found
make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 127
make: *** [prepare0] Error 2

不是吧,这什么人品啊,又是Error,看下错误原因

make: arm-linux-gccgcc: Command not found
CHK include/linux/version.h

arm-linux-gccgcc命令没有找到,为什么是arm-linux-gccgcc ?

排错

1) 命令没有找到?首先看下环境配置,这里我还特意用root权限来看的,可以看到环境变量是对的

root@lcw:/home/mystery/Downloads/linux-2.6.14# echo $PATH
/opt/eclipse:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/jdk1.7.0_17/bin:/usr/local/arm/bin

2) 环境变量没错,那就是配置命令错了,这个arm-linux-gccgcc命令从哪里来的呢?肯定是Makefile了

这是我们之前第一步配置的

192 ARCH            ?= arm
193 CROSS_COMPILE ?= arm-linux-gcc

这里明明是arm-linux-gcc,为什么make出来就成了arm-linux-gcc呢?看下Makefile下面一点的东西

195 # Architecture as present in compile.h
196 UTS_MACHINE := $(ARCH)
197
198 # SHELL used by kbuild
199 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
200 else if [ -x /bin/bash ]; then echo /bin/bash; \
201 else echo sh; fi ; fi)
202
203 HOSTCC = gcc
204 HOSTCXX = g++
205 HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
206 HOSTCXXFLAGS = -O2

简单的翻译一下(外语水平有限哈):

第一句是注释,说的是:当前compile.h中体系结构
第二句,指明我们的硬件平台,machine认识吧,机器
下面一段是编译时使用到的shell语句,是指明编译时用的bash,命令行解释工具
最后红色的是重点!可以看到它们是由HOST+**构成,从后面的赋值来看,我的理解是:
HOST即宿主机
CC即C编译器
CXX即C++编译器(这里可能指面向对象的编译器,通俗的就是C++了)
FLAGS即标志,这里指明的是编译标志,如Wall就是警告一类的,O2是优化一类的
<注意8>现在应该知道为什么是arm-linux-gccgcc而不是arm-linux-gcc了吧,CROSS_COMPILE只是编译器的前辍,所以把这个错误改正过来,另外后面我为了方便,直接把编译器路径写到里面去了
192 ARCH            ?= arm
193 CROSS_COMPILE ?= /usr/local/arm/bin/arm-linux-

3) 重新编译

root@lcw:/home/mystery/Downloads/linux-2.6.14# make zImage
CHK include/linux/version.h
make[1]: `include/asm-arm/mach-types.h' is up to date.
CC arch/arm/kernel/asm-offsets.s
arch/arm/kernel/asm-offsets.c:38:2: #error Your compiler is too buggy; it is known to miscompile kernels.
arch/arm/kernel/asm-offsets.c:39:2: #error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3
make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1
make: *** [prepare0] Error 2

好吧,错误原因

arch/arm/kernel/asm-offsets.c:38:2: #error Your compiler is too buggy; it is known to miscompile kernels.
arch/arm/kernel/asm-offsets.c:39:2: #error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3

意思是说:你的编译器有太多的bug了,它只是一个微内核,下面还介绍了几个优秀的编译器版本

4) 好吧,我的版本是3.2的,无语之下,重新下载一个2.95.3(主要是没找到高版本的,好像要自己配置这个工具链,但是现在我也没配置过,先把这个问题解决掉,然后自己配置)
root@lcw:/home/mystery/Downloads/linux-2.6.14# source /etc/bash.bashrc
root@lcw:/home/mystery/Downloads/linux-2.6.14# echo $PATH
/opt/eclipse:/opt/eclipse:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/jdk1.7.0_17/bin:/usr/local/arm/bin:/opt/jdk1.7.0_17/bin:/usr/local/2.95.3/bin
root@lcw:/home/mystery/Downloads/linux-2.6.14# arm-linux-gcc -v
Using builtin specs.
gcc version 2.95.3 20010315 (release)
root@lcw:/home/mystery/Downloads/linux-2.6.14#
5) 然后配置好环境变量,将前面Makefile中的绝对路径去掉,再试试
root@lcw:/home/mystery/Downloads/linux-2.6.14# make zImage
CHK include/linux/version.h
make[1]: `include/asm-arm/mach-types.h' is up to date.
CC arch/arm/kernel/asm-offsets.s
arm-linux-gcc: installation problem, cannot exec `cpp0': No such file or directory
make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1
make: *** [prepare0] Error 2

错误提示:安装错误 ,以至于找不到文件,查看readme,原来这个版本必须放在固定的位置

oot@lcw:/home/mystery/Downloads/linux-2.6.14# cd /usr/local/
root@lcw:/usr/local# ls
2.95.3 bin etc games include lib man sbin share src
root@lcw:/usr/local# mkdir arm
root@lcw:/usr/local# mv 2.95.3/ arm/
root@lcw:/usr/local# ls
arm bin etc games include lib man sbin share src
root@lcw:/usr/local# ls arm/
2.95.3

6) 再次配置好环境变量

OK,能编译了,然后Error: Unknown pseudo-op:  `.incbin'

好吧,这个编译工具还不能识别它,再一次以“编译工具版本过低”失败
7) 再然后,我去CSDN下了一个3.3.2版本的编译工具,OK,正在编译中

【嵌入式】S3C2410平台移植linux 2.6.14内核

然后系统就开始编译了,等吧
如果按照默认的配置,没有改动的话,编译后系统会在arch/arm/boot目录下生成一个zImage文件,这个文件就是刚刚生成的内核文件。
7. 现在我们就可以把它下载到开发板中进行验证啦,至于怎么下载,我前面的文章已经介绍过了哈

8.工具啊,你把我害惨了,现在自己来配置一个工具链!