我们已经准备好了,你呢?

2024我们与您携手共赢,为您的企业形象保驾护航!

准备

a) 首先,您需要一台安装了 Linux 的 PC(这不是废话吗?^_^)。

b) 安装GCC(host gcc,用于编译生成在PC上运行的程序)、make等工具。

c) 下载一个干净的Linux内核源码包并解压。

注意,如果你正在为你当前的PC编译内核,最好使用相应Linux发行版的源码包。

内嵌的进阶教程是分门别类的,阅读起来非常方便。由于内容比较多,这里就只拍几张图吧。

内核配置文件在哪个目录_内核配置文件_arm linux内核配置

需要的朋友可以发私信【】领取。

内核学习地址:Linux内核源代码/内存调优/文件系统/进程管理/设备驱动/网络协议栈-学习视频教程-腾讯课堂

但其实这个没有必要,因为我的13上下载了一个标准内核linux-2.6.32.65.tar.xz(其内置内核版本是2.6.33.3),并且成功编译安装,开机重启就OK了,但是我使用的配置文件是13自带内核的配置文件,即/lib//`uname -r`/build/。

d) 如果将Linux移植到嵌入式系统,您还需要下载并安装交叉编译工具链。

比如你的目标板CPU可能是arm或者mips,那么就安装对应的交叉编译工具链,安装完之后需要将工具链路径添加到PATH环境变量中,比如你安装的是arm工具链,那么在shell中执行类似下面的命令,如果有类似的输出,则表示安装成功。

[root@localhost linux-2.6.33.i686]# arm-linux-gcc --version
arm-linux-gcc (Buildroot 2010.11) 4.3.5Copyright (C) 2008 Free Software Foundation,
  Inc.This is free software; see the source for copying conditions. 
  There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

设置构建目标

在配置或者编译内核之前,首先要确定目标CPU的架构,以及编译时要用什么工具链,这是最基础的信息,必须首先确定。

如果您正在为当前使用的PC编译内核,则无需进行任何设置。

否则,应明确设置。

这里我们以arm为例来说明。

有两种设置方法:

a) 修改

打开内核源代码根目录,修改以下两个变量并保存。

ARCH := := arm-linux-

注意这里的设置是假设使用的交叉工具链的 gcc 程序名称是 arm-linux-gcc。如果实际使用的 gcc 名称是 some-thing-else-gcc,那么就填写 some-thing-else-。总之,省略名称中 gcc 的最后三个字母。

b) 每次执行make命令时,这些信息都会通过命令行参数传递进去。

这实际上是通过make工具的命令行参数来指定变量的值。

例如:

注意,其实在编译PC内核时,虽然用户没有明确设置这两项,但并不代表这两项没有配置。因为如果用户没有设置这两项,内核源代码的最顶层(位于源代码根目录)会按照下面的方式生成这两个变量的值。

SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \-e s/arm.*/arm/ -e s/sa110/arm/ \-e s/s390x/s390/ -e s/parisc64/parisc/ \-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \-e s/sh[234].*/sh/ )
ARCH?= $(SUBARCH)CROSS_COMPILE ?=

经过上述代码之后ARCH就变成了PC编译器的arch,也就是说,如果PC上uname -m输出ix86,那么ARCH的值就变成了i386。

的值为,若不配置则为空字符串。这样使用的工具链程序名称就不再有arm-linux-这样的前缀了,相当于在PC上使用gcc。

最后再说几句,ARCH的值需要进一步泛化,因为内核源代码的arch目录下并没有i386目录,也没有这个目录。

因此在最顶层构造一个变量,通过下面的代码生成它的值,这样该变量最终就与内核源代码中arch目录下的某个体系结构名称相匹配。

SRCARCH := $(ARCH)
ifeq ($(ARCH),i386) SRCARCH := x86endif
ifeq ($(ARCH),x86_64) SRCARCH := x86endififeq ($(ARCH),sparc64) SRCARCH := sparcendififeq ($(ARCH),sh64) SRCARCH := shendif

配置内核

内核有这么多的功能,我们需要哪些部分,各个部分被编译成什么形式(编入内核还是编译成模块),各个部分的工作参数又是什么?这些都是可以配置的。因此,在开始编译之前,我们需要先建立一个配置列表,放在内核源代码根目录下,命名为.file,然后根据这个.file编译出我们需要的内核。

但是内核中的配置项实在是太多了,一个个去配置太麻烦了,而且不同的CPU架构,可以配置的配置项也不同,比如是否支持某款CPU的某项功能特性的配置项,就是和CPU架构相关的配置项,因此内核提供了一种简单的配置方法。

以arm为例,具体步骤如下。

a) 根据我们的目标CPU架构,从内核源代码arch/arm/目录下(例如)找到一个与目标系统最接近的配置文件,复制到内核源代码根目录下,并命名为.

注意:如果你正在为当前的PC编译内核,最好将下面的文件复制到内核源码根目录下作为初始配置文件,此文件是编译当前在PC上运行的内核时使用的配置文件。

/lib/modules/`uname -r`/build/.config

对了,这里我再多说几句,PC内核的配置文件有很多选项,你不编辑的话是不会知道的,Linux发行商这么做的目的可能就是为了让他们发布的Linux满足用户的各种需求。

b) 执行 make 对配置进行一些必要的更改。退出时选择 Save,将新配置更新到 .. 文件中。

Note-1,当我们执行这个操作的时候,内核会打开一组配置项供我们配置。这组配置项是由我们前面设置的CPU架构决定的。更具体一点,配置系统会打开 arch/arm/ 文件(make 执行的时候可以看到打印出一行“//mconf arch/arm/”),这个文件里面包含了其他内核子系统的文件(文件名也可能是其他名字),而其他子系统的文件又层层包含了下层的文件,这样就生成了整套配置项。对于每一个配置项,当前的设置值(比如是编译进内核,还是编译成模块,也可能是参数)都是由内核源代码根目录下的 . 文件生成的。

注意-2,即使不需要对配置做任何修改,也请务必在进入配置界面后直接执行make,然后退出并保存。否则,后面的编译可能会出现问题。笔者就遇到过这个问题。笔者推测原因可能是初始配置文件是基于旧版本内核的,而新版本内核可能增加了一些基本的功能项,导致功能项之间的依赖关系发生了改变。比如旧配置文件中选择的某个功能项,在新版本内核中可能依赖更多的其他功能项。因此需要对旧的初始配置文件进行一定的调整,确保满足各个功能项的依赖条件。make之后笔者发现.文件的内容确实发生了改变。

编译内核

编译本身非常简单,对于2.6以上的内核版本,只需执行以下命令即可完成。

我们花一点时间来了解内核编译的机制。

a) 内核如何使用文件

之前生成了一个 . 文件。这是一个文本文件,内容类似以下内容:

CONFIG_YENTA_ENE_TUNE=yCONFIG_YENTA_TOSHIBA=yCONFIG_PD6729=mCONFIG_I82092=m
CONFIG_MTDRAM_ERASE_SIZE=128

可以看出,有的是设置将某个功能编译进内核,有的是设置将某个功能编译成模块,有的是设置某个功能的某个参数。

这个文件的语法其实就是定义变量的语法。没错。

当我们执行make编译内核的时候,编译系统会生成另外一个文件//auto.conf,内容和.差不多,但是内容少一些。

当内核被编译时,最顶层(位于源代码根目录)会包含上述文件。

这样就得到了相应的变量,这样我们就知道如何去编译内核的各个部分了。

从顶层可以看到以下代码:

ifeq ($(dot-),1)# 读入 - //auto.conf

不过我还没搞清楚这两个文件之间的关系,以及会包含哪一个...

b) 内核如何编译各个子系统或模块

通过上一步我们知道,在内核顶层已经通过文件生成了大量的变量。

另一方面,每个子系统或模块都有一个源代码目录,定义了该子系统或模块需要编译的内容。

接下来make工具就可以带着最顶层生成的大量变量,逐层进入各个子系统或者模块所在的目录,对各个目录中定义的内容进行编译。

而且这些目录里的可以说非常简单。

假如一个目录下只有一个模块hello,并且这个模块只有一个.c文件,例如xxx.c,那么它的全部内容就只有一行如下。

obj-$() := hello.o

假如hello模块由三个文件组成:main.c ac bc,那么就只需要两行内容。

obj-$() := hello.o

你好,objs:=main.o ao bo

如果一个目录下包含多个模块的C文件,特别是hello,ac,b。hello模块的组成:main.c a。模块的组成:main2.c a2.c b2。模块的组成:.c这时候只需要5行内容就可以了。

obj-$(CONFIG_HELLO)+= hello.o
obj-$(CONFIG_HELLO2)+= hello2.o
obj-$(CONFIG_HELLO3)+= hello3.o
hello-objs := main.o a.o b.ohello2-objs := main2.o a2.o b2.o

由于最上层的变量非常多,所以子目录中的$()变量在解析之后都会变成y或者m,这样在每个子目录中解析之后就相当于只定义了一个变量,变量名为obj-m或者obj-y。

变量 obj-m 或 obj-y 的值是一个 .o 文件列表,列表中的每一项代表一个函数,如果变量名为 obj-m,则该函数被编译成模块,如果变量名为 obj-y,则该函数被编译进内核。

c) 在内核代码中,如何知道某个函数是否被配置,以及以何种形式配置

当我们执行make开始编译内核的时候,编译系统还会生成一个C语言头文件

include/generated/autoconf.h

该文件包含类似以下内容的内容:

#define CONFIG_DM9000 1
#define CONFIG_DM9000_DEBUGLEVEL 4
#define CONFIG_SND_RAWMIDI_SEQ_MODULE 1

第一行表示用户选择将此驱动编译进内核,第二行是此驱动的一个参数,如果用户选择将其编译成模块,那么第一行的内容就会变成如下形式。

#define CONFIG_DM9000_MODULE 1

有了这个头文件,如果一个内核源码.c文件包含这个头文件,就可以用#ifdef来判断用户是否配置了XXX函数。

好了,关于内核的编译机制就讲到这里^_^

安装内核

a) 安装当前电脑的内核

依次执行下面两个命令,分别完成模块和内核的安装。

make modules_install
make install

然后打开 boot/grub/grub.conf 你会看到一个额外的条目。

将其改为5,这样在启动时就有5秒钟的时间来选择启动哪个内核。

最后重启电脑,出现界面时选择启动新内核。

b) 安装嵌入式系统内核

这不是三言两语就能解释清楚的,具体问题可以去查阅相关资料^_^

对于一般的arm板子,常见的做法是将PC连接板子串口,通过网线连接板子网口,在PC上启动tftp服务器,将内核镜像文件放在tftp下载目录下。重启板子,看到u-boot启动倒计时的时候按任意键进入u-boot交互界面。然后在这个界面下使用相关命令下载内核镜像文件,再使用命令将下载的文件烧录到板子的FLASH中。最后重启板子。

二维码
扫一扫在手机端查看

本文链接:https://by928.com/6660.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线