通过编译升级内核

第二次作业(二)

编译升级内核

准备工作

下载安装虚拟机VMWare Workstation;在虚拟机中安装Centos:
请添加图片描述

请添加图片描述

确认内核及版本信息:

[root@compute ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core) 
[root@compute ~]# uname -r
3.10.0-862.el7.x86_64
1. 给出Linux内核源码下载的地址,以及内核源码版本号?

到www.kernel.org网站上下载对应版本的内核文件,也可到开源镜像站中去下载,如163的镜像站:
http://mirrors.163.com/kernel/v3.x/
请添加图片描述

官网上只有
linux-4.19.260linux-4.14.295两个版本的内核,因此选择这两个版本的内核

2. 内核主要源代码目录包括什么,每个目录下主要实现什么资源管理?

Linux源代码目录结构示意图:
请添加图片描述

linux-4.14.295的源代码目录主要包括以下几个文件
请添加图片描述

/arch目录包括了所有和体系结构相关的核心代码。它下面的每一个子目录都代表一种Linux支持的体系结构,例如i386就是Intel CPU及与之相兼容体系结构的子目录。PC机一般都基于此目录。

请添加图片描述

每种体系结构,都有相应的子目录,如 arm,arm64分别是arm 32位和64位平台。

/block目录里面包括了块设备驱动程序I/O调度;

/certs 目录中存储了认证和签名相关代码;

/crypto目录中存储了内核中常用的加密,压缩等算法相关代码;

/Documentation 目录中存储了内核中常用的协议规范,功能模块相关代码;

/Drivers目录中存储了驱动程序(USB总线,PCI总线,显卡驱动)相关代码;它又进一步划分成几类设备驱动,每一种有对应的子目录,如声卡的驱动对应于drivers/sound; block 下为块设备驱动程序,比如ide(ide.c)。

/firmware 目录中主要是一些二进制的固件相关代码;

/fs 目录存放Linux支持的文件系统代码和各种类型的文件操作代码。每一个子目录支持一个文件系统,包括我们常用的文件系统类型:Ext2、Ext3、Ext4、 Proc、Fat和Nfs。其中Ext3文件系统对应的就是/fs/ext3目录。

/include 这个目录包含linux源代码目录树中绝大部分头文件,每个体系架构都在该目录下对应一个子目录,该子目录中包含了给定体系结构所必需的宏定义和内联函数。这些内联函数很多都是适用汇编语言实现的,而且在编译内核的过程中,首先会建立一个名称为include/asm的符号链接,该链接指向目标体系结构在该目录中的子目录,使得与体系结构无关内核代码可以使用如下简洁的形式来引用语体系结构相关的代码为:

#include Linux/asm/xxx.h

除了与体系结构相关的头文件之外,该目录还用与存放于体系架构无关的内核模块的头文件,这些头文件都是某一个内核模块对外提供的接口,供内核其他模块使用。这些接口主要包含进程管理访问接口、内存管理访问接口、文件操作访问接口、网络访问接口等,这些接口函数通常用于内核模块的编写,如编写设备驱动程序或者设计一个新的文件系统等。

/init 目录中存储了内核初始化代码,联系到内存各组件入口相关代码,start_kernel就是在该目录下的文件main.c内实现的。内核初始化入口函数start_kernel负责调用其它模块的初始化函数,完成系统的初始化工作。该目录种存放的代码还负责测试CPU性能,算出系统处理器的BogoMIps值,该值代表了处理器在一定时间执行循环操作的次数。除此之外,该目录还负责完成根文件系统初始化过程中的相关工作。

/ipc 目录中存储了进程间通信实现.例如:共享内存,信号量,匿名管道等相关代码;

/kernel 该目录存放的是linux内核的最核心代码,用于实现系统的核心模块,这些模块包括进程管理、进程调度器、中断处理、系统时钟管理、同步机制等。该目录中的代码实现了这些核心模块的主体框架,独立于具体的平台和系统架构。核心模块与平台相关代码存放在目录arch中,具体看后面对该目录的介绍;

/lib 该目录主要分两部分:gnuzip加压缩算法,用于在系统启动过程中将压缩的内核镜像解压缩;剩余的文件用于实现一个C库的子集,主要包括字符串和内存操作等相关函数;

/mm 该目录主要包含了和体系结构无关的内存管理代码,包括通用的分页模型的框架、伙伴算法的实现和对象缓冲器slab的实现代码。这些代码最终依赖具体的平台完成相关操作;
/net 目录中存储了网络协议代码,比如TCP,IPV6,WIFI,以太网实现等相关代码;
/samples 目录中存储了内核实列代码相关代码;
/scripts 目录中存储了编译和配置内核所需的脚本,例如perl,bash相关代码;
/security 目录中存储了内核安全模型相关代码.例如selinux相关代码;
/sound 目录中存储了声卡驱动源码相关代码;
/tools 目录中存储了与内核交互相关代码;
/usr 目录中存储了用户打包和压缩内核的实现源码相关代码;
/virt 目录中存储了/kvm虚拟化目录相关支持的实现相关代码;

3. 内核升级必要的软件包需要那些?

功能上为虚拟机装配如git、fakeroot(虚拟环境打包工具)、ncurees-dev(为终端base-on-txt提供API编程库)等的资源包,支持某些功能或者便于后续,使用按照功能来看,这一步对某些版本升级可能并不必要,并且发现缺失,可以补装

  • git:跟踪并记录源代码开发过程中的所有更改,并允许恢复更改。
  • fakeroot:制作虚拟环境的打包工具。
  • build-essential:安装开发工具,如C、C+、gcc和g+。
  • ncurses-dev:为基于文本的终端提供API的编程库。
  • xz-utils:提供快速文件压缩和解压缩。
  • libssl-dev:支持SSL和TSL加密数据并确保internet连接安全。
  • bc:一种支持语句交互执行的数学脚本语言。
  • flex:生成将字符转换为标记的词法分析器。
  • libelf-dev:发布用于管理可执行文件、核心转储和目标代码的共享库
  • bison:GNU语法分析器生成器,将语法描述转换为C程序。
  • dwarves:Linux BTF功能依赖pahole工具。
  • perl:一种功能丰富的计算机程序语言,运行在超过100种计算机平台上,适用广泛,从大型机到便携设备,从快速原型创建到大规模可扩展开发。
4.编译内核的步骤是什么?
1. 将linux内核文件解压并进入该目录
[root@localhost ~]# # cp linux-4.14.295.tar.xz /usr/src/
[root@localhost ~]# # cd /usr/src/
[root@localhost src]# # tar -xf linux-4.14.295.tar.xz -C /usr/src/kernels
[root@localhost src]# cd kernels/linux-4.14.295
[root@localhost linux-4.14.295]#
2. 添加配置文件

.config文件的内容是内核编译的参考文件,决定了那些驱动会被编译到内核中去,一般采用的策略是拷贝当前内核的配置更好的适应机器环境

[root@localhost linux-4.14.295]# cp -v /boot/config-$(uname -r) .config
3. 命令启动配置界面

关于配置界面,有如下几个选项

#make config(基于文本的最为传统的配置界面,不推荐使用) 
#make menuconfig(基于文本选单的配置界面,字符终端下推荐使用) 
#make xconfig(基于图形窗口模式的配置界面,Xwindow下推荐使用) 
#make oldconfig(如果只想在原来内核配置的基础上修改一些小地方,会省去不少麻烦)

本文选择make menuconfig

[root@localhost linux-4.14.295]# make menuconfig

进入配置界面
请添加图片描述

该命令会出现一个简陋的菜单,类似bios菜单,其中可以进行功能挑选,可以配置相关的模块参数,如果对于不熟悉的情况,可以直接采用默认的形式。

4. 编译并安装内核

首先我们要先清除内核编译的目标文件,然后才能编译新的内核;使用make bzImage或make zImage生成内核文件,make modules和make modules_install分别生成相应的模块和把模块拷贝到需要的目录中。最后编译安装内核。

//按顺序执行即可
# make clean          // 清除下内核编译的目标文件
# make bzImage    // 生成内核文件
# make modules    // 编码模块
# make modules_install // 安装模块
# make install         // 安装

当然直接make也是可以的,会自动完成上面的操作,而且进入编译时可以分配多线程来进行:

#make -j x //分配x个线程进行编译
5.完成后重新启动

选择新内核
请添加图片描述
查看当前linux内核版本
请添加图片描述

4. 在编译过程中通常会遇到的问题有哪些,解决的办法是什么?
错误一、 编译时出现错误提示
In file included from /usr/include/sys/time.h:31,
                 from /usr/include/linux/input.h:12,
                 from samples/hidraw/hid-example.c:14:
/usr/include/sys/select.h:78: error: conflicting types for 'fd_set'
/usr/include/linux/types.h:12: error: previous declaration of 'fd_set' was here
In file included from /usr/include/linux/input.h:14,
                 from samples/hidraw/hid-example.c:14:
/usr/include/sys/types.h:46: error: conflicting types for 'loff_t'
/usr/include/linux/types.h:30: error: previous declaration of 'loff_t' was here
/usr/include/sys/types.h:62: error: conflicting types for 'dev_t'
/usr/include/linux/types.h:13: error: previous declaration of 'dev_t' was here
In file included from /usr/include/sys/types.h:133,
                 from /usr/include/linux/input.h:14,
                 from samples/hidraw/hid-example.c:14:
/usr/include/time.h:105: error: conflicting types for 'timer_t'
/usr/include/linux/types.h:22: error: previous declaration of 'timer_t' was here
In file included from /usr/include/linux/input.h:14,
                 from samples/hidraw/hid-example.c:14:
/usr/include/sys/types.h:198: error: conflicting types for 'int64_t'
/usr/include/linux/types.h:98: error: previous declaration of 'int64_t' was here
/usr/include/sys/types.h:204: error: conflicting types for 'u_int64_t'
/usr/include/linux/types.h:97: error: previous declaration of 'u_int64_t' was here
In file included from /usr/include/linux/input.h:14,
                 from samples/hidraw/hid-example.c:14:
/usr/include/sys/types.h:235: error: conflicting types for 'blkcnt_t'
/usr/include/linux/types.h:114: error: previous declaration of 'blkcnt_t' was here
samples/hidraw/hid-example.c:15:26: error: linux/hidraw.h: No such file or directory
samples/hidraw/hid-example.c: In function 'main':
samples/hidraw/hid-example.c:48: error: storage size of 'rpt_desc' isn't known
samples/hidraw/hid-example.c:49: error: storage size of 'info' isn't known
samples/hidraw/hid-example.c:65: error: 'HIDIOCGRDESCSIZE' undeclared (first use in this function)
samples/hidraw/hid-example.c:65: error: (Each undeclared identifier is reported only once
samples/hidraw/hid-example.c:65: error: for each function it appears in.)
samples/hidraw/hid-example.c:73: error: 'HIDIOCGRDESC' undeclared (first use in this function)
samples/hidraw/hid-example.c:84: warning: implicit declaration of function 'HIDIOCGRAWNAME'
samples/hidraw/hid-example.c:91: warning: implicit declaration of function 'HIDIOCGRAWPHYS'
samples/hidraw/hid-example.c:98: error: 'HIDIOCGRAWINFO' undeclared (first use in this function)
samples/hidraw/hid-example.c:49: warning: unused variable 'info'
samples/hidraw/hid-example.c:48: warning: unused variable 'rpt_desc'
samples/hidraw/hid-example.c: In function 'bus_str':
samples/hidraw/hid-example.c:171: error: 'BUS_VIRTUAL' undeclared (first use in this function)
make[2]: *** [samples/hidraw/hid-example] Error 1
make[1]: *** [samples/hidraw] Error 2
make: *** [vmlinux] Error 2
解决方案:
# cp include/linux/hidraw.h /usr/include/linux/
# cp include/linux/hid.h /usr/include/linux/
# vim samples/hidraw/hid-example.c

在Linux下编译程序有时会遇到这种问题,这貌似是一个Linux历史遗留问题:把所有#include 都提到最前面,把#include 的包含放在其后,就可以编译通过了,之所以出现面的问题是存在循环引用所致。

错误二:

错误提示:Kernel panic—not syncing :vfs:unable to mount root fs on unkown—block (0,0)
错误分析:initrd-..img文件有问题;未能成功挂载真正的根文件系统。
解决方法:请你确认执行了make install 命令,我就因为没有执行这条命令而浪费了一周时间

错误三:

错误提示:Enforcing mode requested but no policy loaded. Halting now.
kernel panic - not syncing: Attenpted to kill init!
错误分析:原内核中启用了selinux,新内核未选择selinux的选项,不能成功启动。
解决方法:修改grub.conf文件,在root=LABEL=/ 后加入 enforcing=0

错误四:

错误提示:/bin/sh: perl: 未找到命令
错误分析:软件依赖包没有安装全,把perl包安装然后重新编译就好了

5. 你在编译过程中实际遇到什么问题,最后解决办法是什么?收获是什么?

编译太慢了,我吃个饭还没编译好
解决方法:再吃一会儿
收获:饱腹感

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值