小续
第一次接触内核的东西,有点小激动啊
激动归激动,这实验还是要继续做下去,书上三两句话就带过去的,剩下的就留给我们了,着实考验动手能力啊
当编译过内核之后,发现这个过程也不复杂嘛(复杂的是内核的配置),不过对于没接触过的人来说,也能够折腾一段时间的了,所以记下这个过程,其中也有些需要注意的地方,然后给没接触过的人分享下
环境如下
操作系统: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
配置选项出来了有木有啊
<注意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>进行配置就是了
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
简单的翻译一下(外语水平有限哈):
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了,它只是一个微内核,下面还介绍了几个优秀的编译器版本
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#
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'
8.工具啊,你把我害惨了,现在自己来配置一个工具链!