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

简介:

小续

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

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

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


环境如下

操作系统:ubuntu 12.04LTS

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

开发板:FS2410

linux内核:linux 2.6.14

 
  1. mystery@lcw:~/Downloads$ cat /etc/issue

  2. Ubuntu 12.04.2 LTS \n \l

  3. mystery@lcw:~/Downloads$ arm-linux-gcc -v

  4. Reading specs from /usr/local/arm/bin/../lib/gcc-lib/arm-linux/3.2/specs

  5. 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

  6. Thread model: posix

  7. gcc version 3.2

  8. mystery@lcw:~/Downloads$ ls /home/mystery/Downloads/  

  9. cross-3.2.tar.bz2                      linux-2.6.14

  10. eclipse-cpp-juno-SR2-linux-gtk.tar.gz  linux-2.6.14.tar.bz2

  11. google-chrome-stable_current_i386.deb  wps-office_8.1.0.3724~b1p2_i386.deb

  12. jdk-7u17-linux-i586.tar.gz             wps_symbol_fonts.zip

  13. 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   ?=
修改成

 
  1. 192 ARCH            ?= arm

  2. 193 CROSS_COMPILE   ?= arm-linux-gcc

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

 
  1. mystery@lcw:~/Downloads/linux-2.6.14$ make menuconfig                            

  2. make: *** /home/mystery/Downloads/linux-2.6.14/arch/arm: Is a directory.  Stop.  

  3. mystery@lcw:~/Downloads/linux-2.6.14$ vim Makefile  

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

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

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

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

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

 
  1. 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使用最为广泛,我这里也使用这种哈

 
  1. mystery@lcw:~/Downloads/linux-2.6.14$ make menuconfig

  2. HOSTCC  scripts/basic/fixdep

  3. scripts/basic/fixdep.c: In function ‘traps’:

  4. scripts/basic/fixdep.c:368:2: warning: dereferencing  

  5. ………………………

  6. ………………………

  7. >> Unable to find the Ncurses libraries.

  8. >>

  9. >> You must install ncurses-devel in order

  10. >> to use 'make menuconfig'

  11. make[2]: *** [scripts/lxdialog/ncurses] Error 1

  12. make[1]: *** [menuconfig] Error 2

  13. make: *** [menuconfig] Error 2

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

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

 
  1. >> Unable to find the Ncurses libraries.

  2. >>

  3. >> You must install ncurses-devel in order

  4. >> to use 'make menuconfig'

意思是不能找到Ncurses libraries,你必须在这之前安装ucurses工具,好吧,照做
 
  1. mystery@lcw:~/Downloads/linux-2.6.14$ sudo apt-get install ncurses-dev

  2. [sudo] password for mystery:  

  3. Reading package lists... Done

< 注意3>ncurses用于make menuconfig界面显示
后面我无意间又发现了一个错误
 
  1. mystery@lcw:~/Downloads/linux-2.6.14$ make menuconfig

  2.  HOSTCC  scripts/lxdialog/checklist.o

  3.  HOSTCC  scripts/lxdialog/inputbox.o

  4.  HOSTCC  scripts/lxdialog/lxdialog.o

  5. ……………………

  6. scripts/kconfig/mconf arch/arm/Kconfig

  7. # using defaults found in .config

  8. .config:622: trying to assign nonexistent symbol DEVFS_FS

  9. .config:622: trying to assign nonexistent symbol DEVFS_FS

  10. .config:623: trying to assign nonexistent symbol DEVPTS_FS_XATTR

  11. Your display is too small to run Menuconfig!

  12. It must be at least 19 lines by 80 columns.

  13. make[1]: *** [menuconfig] Error 1

  14. make: *** [menuconfig] Error 2


中间也省略了一些哈,你找到错误说明了吗:
 
  1. Your display is too small to run Menuconfig!

  2. It must be at least 19 lines by 80 columns.


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

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

 
  1. mystery@lcw:~/Downloads/linux-2.6.14$ make menuconfig

  2. scripts/kconfig/mconf arch/arm/Kconfig

  3. #

  4. # using defaults found in .config

  5. #

  6. .config:11: trying to assign nonexistent symbol GENERIC_IOMAP

配置选项出来了有木有啊

221717804.png

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

Y:将该功能编译进内核

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

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

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

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

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

 
  1. Linux Kernel v2.6.14 Configuration                                              

  2. ------------------------------------------------------------------------------  

  3. +----------------------------- General setup -----------------------------+    

  4. |  Arrow keys navigate the menu.  <Enter> selects submenus --->.          |    

  5. |  Highlighted letters are hotkeys.  Pressing <Y> includes, <N> excludes, |    

  6. |  <M> modularizes features.  Press <Esc><Esc> to exit, <?> for Help, </> |    

  7. |  for Search.  Legend: [*] built-in  [ ] excluded  <M> module  <>       |    

  8. | +---------------------------------------------------------------------+ |    

  9. | |()  Local version - append to kernel release                         | |    

  10. | |[*] Automatically append version information to the version string (N| |    

  11. | |[*] Support for paging of anonymous memory (swap)                    | |    

  12. | |[*] System V IPC                                                     | |    

  13. | |[ ] POSIX Message Queues                                             | |    

  14. | |[ ] BSD Process Accounting                                           | |    

  15. | |[*] Sysctl support                                                   | |    

  16. | |[ ] Auditing support                                                 | |    

  17. | |[ ] Support for hot-pluggable devices                                | |    

  18. | +v(+)-----------------------------------------------------------------+ |    

  19. +-------------------------------------------------------------------------+    

  20. |                    <Select><Exit><Help>                     |    

  21. +-------------------------------------------------------------------------+  

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

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

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

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

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

[*]支持匿名分页存储

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

[  ]支持POSIX消息队列

…………

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

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


6. 等配置好了,就把工作交给银行人员吧
 
  1. mystery@lcw:~/Downloads/linux-2.6.14$ make zImage

  2. make: arm-linux-gccgcc: Command not found

  3.  CHK     include/linux/version.h

  4.  UPD     include/linux/version.h

  5.  SPLIT   include/linux/autoconf.h -> include/config/*

  6.  SYMLINK include/asm-arm/arch -> include/asm-arm/arch-s3c2410

  7.  Generating include/asm-arm/mach-types.h

  8.  SYMLINK include/asm -> include/asm-arm

  9.  CC      arch/arm/kernel/asm-offsets.s

  10. /bin/sh: 1: arm-linux-gccgcc: not found

  11. make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 127

  12. make: *** [prepare0] Error 2

 

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

 
  1. make: arm-linux-gccgcc: Command not found

  2.  CHK     include/linux/version.h

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

排错

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

 
  1. root@lcw:/home/mystery/Downloads/linux-2.6.14# echo $PATH

  2. /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了

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

 
  1. 192 ARCH            ?= arm  

  2. 193 CROSS_COMPILE   ?= arm-linux-gcc  

这里明明是arm-linux-gcc,为什么make出来就成了arm-linux-gcc呢?看下Makefile下面一点的东西
 
  1. 195 # Architecture as present in compile.h                                          

  2. 196 UTS_MACHINE := $(ARCH)                                                          

  3. 197                                                                                  

  4. 198 # SHELL used by kbuild                                                          

  5. 199 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \                  

  6. 200           else if [ -x /bin/bash ]; then echo /bin/bash; \                      

  7. 201           else echo sh; fi ; fi)                                                

  8. 202                                                                                  

  9. 203 HOSTCC          = gcc

  10. 204 HOSTCXX         = g++                                                            

  11. 205 HOSTCFLAGS      = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer            

  12. 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只是编译器的前辍,所以把这个错误改正过来,另外后面我为了方便,直接把编译器路径写到里面去了
 
  1. 192 ARCH            ?= arm                                                          

  2. 193 CROSS_COMPILE   ?= /usr/local/arm/bin/arm-linux-  

3) 重新编译
 
  1. root@lcw:/home/mystery/Downloads/linux-2.6.14# make zImage                            

  2.  CHK     include/linux/version.h

  3. make[1]: `include/asm-arm/mach-types.h' is up to date.

  4.  CC      arch/arm/kernel/asm-offsets.s

  5. arch/arm/kernel/asm-offsets.c:38:2: #error Your compiler is too buggy; it is known to miscompile kernels.

  6. arch/arm/kernel/asm-offsets.c:39:2: #error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3

  7. make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1

  8. make: *** [prepare0] Error 2

好吧,错误原因
 
  1. arch/arm/kernel/asm-offsets.c:38:2: #error Your compiler is too buggy; it is known to miscompile kernels.

  2. 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(主要是没找到高版本的,好像要自己配置这个工具链,但是现在我也没配置过,先把这个问题解决掉,然后自己配置)
 
  1. root@lcw:/home/mystery/Downloads/linux-2.6.14# source /etc/bash.bashrc  

  2. root@lcw:/home/mystery/Downloads/linux-2.6.14# echo $PATH

  3. /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

  4. root@lcw:/home/mystery/Downloads/linux-2.6.14# arm-linux-gcc -v

  5. Using builtin specs.

  6. gcc version 2.95.3 20010315 (release)

  7. root@lcw:/home/mystery/Downloads/linux-2.6.14#  

5) 然后配置好环境变量,将前面Makefile中的绝对路径去掉,再试试
 
  1. root@lcw:/home/mystery/Downloads/linux-2.6.14# make zImage

  2.  CHK     include/linux/version.h

  3. make[1]: `include/asm-arm/mach-types.h' is up to date.

  4.  CC      arch/arm/kernel/asm-offsets.s

  5. arm-linux-gcc: installation problem, cannot exec `cpp0': No such file or directory

  6. make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1

  7. make: *** [prepare0] Error 2

错误提示:安装错误 ,以至于找不到文件,查看readme,原来这个版本必须放在固定的位置
 
  1. oot@lcw:/home/mystery/Downloads/linux-2.6.14# cd /usr/local/

  2. root@lcw:/usr/local# ls

  3. 2.95.3  bin  etc  games  include  lib  man  sbin  share  src

  4. root@lcw:/usr/local# mkdir arm

  5. root@lcw:/usr/local# mv 2.95.3/ arm/

  6. root@lcw:/usr/local# ls

  7. arm  bin  etc  games  include  lib  man  sbin  share  src

  8. root@lcw:/usr/local# ls arm/

  9. 2.95.3

6) 再次配置好环境变量
 
  1. root@lcw:/home/mystery/Downloads/linux-2.6.14# make zImage

  2.  CHK     include/linux/version.h

  3. make[1]: `include/asm-arm/mach-types.h' is up to date.

  4.  CC      arch/arm/kernel/asm-offsets.s

  5.  HOSTCC  scripts/conmakehash

  6.  CC      init/version.o

  7.  CC      init/do_mounts.o

  8. CPIO    usr/initramfs_data.cpio

  9.  AS      usr/initramfs_data.o

  10. usr/initramfs_data.S: Assembler messages:

  11. usr/initramfs_data.S:29: Error: Unknown pseudo-op:  `.incbin'

  12. make[1]: *** [usr/initramfs_data.o] Error 1

  13. make: *** [usr] Error 2

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

155525319.png

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

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




本文转自infohacker 51CTO博客,原文链接:http://blog.51cto.com/liucw/1172322

相关文章
|
16天前
|
Linux C语言
Linux内核队列queue.h
Linux内核队列queue.h
|
23天前
|
JSON 机器人 Linux
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
54 3
|
1月前
|
存储 Shell Linux
【Shell 命令集合 系统设置 】Linux 生成并更新内核模块的依赖 depmod命令 使用指南
【Shell 命令集合 系统设置 】Linux 生成并更新内核模块的依赖 depmod命令 使用指南
32 0
|
1月前
|
Shell Linux C语言
【Shell 命令集合 系统设置 】⭐Linux 卸载已加载的内核模块rmmod命令 使用指南
【Shell 命令集合 系统设置 】⭐Linux 卸载已加载的内核模块rmmod命令 使用指南
29 1
|
9天前
|
算法 Linux 调度
深入理解Linux内核的进程调度机制
【4月更文挑战第17天】在多任务操作系统中,进程调度是核心功能之一,它决定了处理机资源的分配。本文旨在剖析Linux操作系统内核的进程调度机制,详细讨论其调度策略、调度算法及实现原理,并探讨了其对系统性能的影响。通过分析CFS(完全公平调度器)和实时调度策略,揭示了Linux如何在保证响应速度与公平性之间取得平衡。文章还将评估最新的调度技术趋势,如容器化和云计算环境下的调度优化。
|
11天前
|
Linux 编译器 测试技术
嵌入式 Linux 下的 LVGL 移植
嵌入式 Linux 下的 LVGL 移植
|
14天前
|
算法 Linux 调度
深度解析:Linux内核的进程调度机制
【4月更文挑战第12天】 在多任务操作系统如Linux中,进程调度机制是系统的核心组成部分之一,它决定了处理器资源如何分配给多个竞争的进程。本文深入探讨了Linux内核中的进程调度策略和相关算法,包括其设计哲学、实现原理及对系统性能的影响。通过分析进程调度器的工作原理,我们能够理解操作系统如何平衡效率、公平性和响应性,进而优化系统表现和用户体验。
20 3
|
21天前
|
负载均衡 算法 Linux
深度解析:Linux内核调度器的演变与优化策略
【4月更文挑战第5天】 在本文中,我们将深入探讨Linux操作系统的核心组成部分——内核调度器。文章将首先回顾Linux内核调度器的发展历程,从早期的简单轮转调度(Round Robin)到现代的完全公平调度器(Completely Fair Scheduler, CFS)。接着,分析当前CFS面临的挑战以及社区提出的各种优化方案,最后提出未来可能的发展趋势和研究方向。通过本文,读者将对Linux调度器的原理、实现及其优化有一个全面的认识。
|
21天前
|
Ubuntu Linux
Linux查看内核版本
在Linux系统中查看内核版本有多种方法:1) 使用`uname -r`命令直接显示版本号;2) 通过`cat /proc/version`查看内核详细信息;3) 利用`dmesg | grep Linux`显示内核版本行;4) 如果支持,使用`lsb_release -a`查看发行版及内核版本。
36 6
|
24天前
|
Linux
嵌入式Linux系统(NUC980)tf卡出错处理errors=remount-ro改为errors=continue
嵌入式Linux系统(NUC980)tf卡出错处理errors=remount-ro改为errors=continue
7 1