linux内核设计与实现---从内核出发

获取、编译、安装内核

  • 1 获取内核源码
    • 安装内核源代码
      • 何处安装源码
    • 使用补丁
  • 2 内核源码树
  • 3 编译内核
    • 减少编译的垃圾信息
    • 衍生多个编译作业
    • 安装内核
      • 启用指定内核作为引导
  • 4 内核开发的特点
    • 没有libc库
      • 头文件
    • 没有内存保护机制
    • 容积小而固定的栈

1 获取内核源码

在linux内核官方网站http://www.kernel.org,可以获得当前最新版本Linux源码码。如果想找一些老版本的源代码,可以:https://mirrors.edge.kernel.org/pub/linux/kernel/下载。

安装内核源代码

内核压缩以GNU zip(gzip)和bzip2两种形式发布。以bzip2形式发布的Linux内核叫做linux-x.y.z.tar.bz2,这里x.y.z是内核源码的具体版本。如果压缩形式是bzip2,则运行:

tar rvjf linux-x.y.z.tar.bz2

如果压缩形式是GNU的zip,则运行:

tar xvzf linux-x.y.z.tar.gz

何处安装源码

内核源码一般安装在/usr/src/具体linux版本 目录下。不要以root身份对内核进行修改,而应当是,建立自己的主目录。仅以root身份安装新内核,即使在安装新内核时,/usr/src/linux目录都应当原封不动。

使用补丁

在linu内核社区中,补丁是通用语。你可以以补丁的形式发布对代码的修改,也可以以补丁的形式接收其他人所做的修改。内核版本不断更新,增量补丁可以作为版本转移的桥梁。你不在需要下载内核源码的全部压缩,而只需给旧版本打上一个增量补丁,让其旧貌换新颜,更新内核版本。只需运行:

patch-p1 < ../patch-x.y.z

一般来说,一个给定版本的内核补丁总是打在前一个版本上。

2 内核源码树

内核源码树由很多目录组成,而大多数目录又包含更多子目录。源码树的根目录及其子目录如下表:

目录描述
arch特定体系结构的源码
cryptoCrypto API
Documentation内核源码文档
drivers设备驱动程序
fsVFS和各种文件系统
include内核头文件
init内核引导和初始化
ipc进程间通信代码
kernel像调度程序这样的核心子系统
lib通用内核函数
mm内存管理子系统和VM
net网络子系统
scrripts编译内核所用的脚本
securityLinux安全模块
sound语音子系统
usr早期用户空间代码

在源码树根目录中,COPYING是内核许可证,CREDITS是开发者列表。MAINTAINERS是维护者列表,维护内核子系统和驱动程序。最后,Makefile是Makefile内核的基础

3 编译内核

在编译内核之前,首先你必须配置它。可以配置的各种选项,以CONFIG_FEATURE形式表示,其前缀为CONFIG。例如,对称处理器(SMP)的配置选项为CONFIG_SMP。如果设置了该选项,则SMP启用,否则,SMP不起作用。
这些配置项要么是二选一,要么是三选一。二选一就是yes或no。三选一可以是yes、no或module。module意味着该配置项被选定了,但编译的时候这部分功能的实现代码是以模块(一种可以动态安装的独立代码段)的形式生成。在三选一的情况下,yes表示把代码编译进内核映射中,而不是作为一个模块。

内核提供了各种不同的工具来简化内核配置。最简单的一种是基于文本的命令行工具:

make config

该工具会挨个遍历所有配置项,要求用户选择yes、no或module。
在这里插入图片描述
如果该命令不能执行,说明没有安装一些工具,可以根据提示安装,我的需要安装make、gcc、bison、flex

sudo apt-get install make gcc bison flex

这个过程很耗费时间,所以,除非你的工作是按小时计费的,否则你应该多利用基于ncuse编译的图形界面工具。

make menuconfig

或者基于X11的图形工具

make xconfig

或用基于gtk+图形工具

make gconfig

这三种工具将所有配置项分门别类放置,比如按处理器类别和特点,你可以按类移动、浏览内核选项,当然也可以修改其值。
命令:

make defconfig

通过这条命令为你的体系结构创建一个默认的配置。尽管这些默认值有点随意性,但是,如果你从未配置过内核,那就会提供一个良好的开端。
在这里插入图片描述
执行完,帮我配置的是x86_64_defconfig。这些配置项会存放在内核代码树根目录下的.config文件中,我们也可修改它,打开看看
在这里插入图片描述
再修改过配置文件之后,或者在用旧的配置文件配置新的代码树的时候,应该验证和更新配置:

make oldconfig

一旦内核配置好了,就可以编译它了,执行命令:

make

在这里插入图片描述

减少编译的垃圾信息

我们希望在编译时看到错误和警告消息,但对匆匆掠过屏幕的垃圾信息不感兴趣,可以使用如下命令

make > /dev/null

就可以把无用的输出信息重定向到永无返回值的黑洞/dev/null

衍生多个编译作业

多个作业独立并发运行,可以提高处理器系统上的编译过程。默认情况下,make只衍生一个作业。为了可以以多个作业编译内核,使用一下命令:

make -jn

n是要衍生的作业数,在实际中,每个处理器一般衍生一个或者两个作业。例如,在一个双处理器上,可以输入如下命令:

make -j4

安装内核

在内核编译好了之后,还需要安装它。怎么安装就和体系架构以及启动引导工具(boot loader)息息相关了—查阅启动引导工具的说明,按照它的指导将内核映像拷贝到合适的位置,并且按照启动要求安装它。一定要保证随时有一个或两个可以启动的内核,以放新编译的内核出现问题。
安装命令:

sudo  make install

模块的安装是自动的,也是独立于体系结构的。以root身份,只要运行:

sudo make modules_install

就可以把所有编译号的模块安装到正确的主目录/lib下
在这里插入图片描述
在这里插入图片描述
可以看到,编译的内核版本号是5.0.0
在这里插入图片描述
同时也列出了还有那个内核
在这里插入图片描述
查看现在使用的内核版本
在这里插入图片描述

启用指定内核作为引导

输入下列命令将内核作为引导,将数字更改为你自己编译的版本号:

sudo  update-initramfs -c -k 5.0.0

在这里插入图片描述
跟新一下grub:

sudo update-grub

在这里插入图片描述
之后重启即可在启动界面选择需要重启的内核。如果看不到重启选择界面,执行以下操作。
输入命令:

sudo  vim /etc/default/grub

注释掉hidden那一行,将timeout更改为较大值,这里改为了10
在这里插入图片描述
之后执行

sudo update-grub

重启即可看到下面此单,选择高级选项,进入后选择编译安装好的内核进入即可,
在这里插入图片描述
选择我们刚刚编译好的内核,5.0.0,倒数第二个
在这里插入图片描述
可以看到是我们编译的内核
在这里插入图片描述

4 内核开发的特点

没有libc库

与用户空间的应用程序不同,内核不能链接使用标准C函数库。最主要的原因是对于内核来说,完整的C库太大了,影响速度和大小。
大部分常用的C库函数在内核中都已经得到了实现。比如说操作字符串的函数组就位与lib/string.c文件中。只要包含<linux/string.h>头文件就可以使用。

头文件

内核源代码文件不能包含外部头文件,所说的头文件是指组成内核源代码树的内核头文件。
在没有实现的函数中,最著名的就数printf()函数了。内核代码虽然无法调用printf(),但它可以调用printk()函数。printk()函数负责把格式化好的字符串拷贝到内核日志缓存区上,这样,syslog程序就可以通过读取缓冲区来获取内核信息。

没有内存保护机制

如果一个用户程序试图进行一次非法的内存访问,内核会出现这个错误,发送SIGSEGV,并结束整个进程。然而,如果是内核自己非法访问了内存,那后果就很难控制了。内核中发生的内存错误会导致oops,这是内核中常见的一类错误。
此外,内核中的内存都不分页,也就是说,每用掉一个字节,物理内存就减少一个字节。所以,在你想往内核加入什么新功能的时候,要记住这一点。

容积小而固定的栈

内核栈的准确大小随体系结构而变,但都是两页。每个处理器都有自己的栈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/379684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL在DOS下的基本命令操作

启动net start mysql 重置root密码 方法一:在my.ini的[mysqld]字段加入&#xff1a; skip-grant-tables 重启mysql服务&#xff0c;这时的mysql不需要密码即可登录数据库然后进入mysql mysql>use mysql;mysql>更新 user set passwordpassword(新密码) WHERE Userroot; …

strlen的神奇实现

https://blog.delphij.net/2012/04/freebsd-strlen3.html 与 Pascal 等语言不同&#xff0c;C 的字符串并不保存串的长度&#xff0c;而是在字符串末尾以 nul 字符&#xff08;\0&#xff09;来表示字符串结束。这个设计决策是上世纪 60 年代作出的&#xff0c;有都市传说是为了…

python求和_Python程序查找特殊求和系列的解决方案

python求和We are going to design a special sum series function which has following characteristics: 我们将设计一个特殊的求和系列函数&#xff0c;该函数具有以下特征&#xff1a; f(0) 0f(1) 1f(2) 1f(3) 0f(x) f(x-1) f(x-3)Python solution of the above sum…

linux内核设计与实现---进程管理

进程管理1 进程描述符及任务结构分配进程描述符进程描述符的存放进程状态设置当前进程状态进程上下文进程家族树2 进程创建写时拷贝fork()vfork()3 线程在Linux中的实现内核线程4 进程终结删除进程描述符孤儿进程造成的进退微谷5 小结进程的另一个名字叫做任务&#xff08;task…

JS错误代码解释大全+VBS错误代码解释大全

JScript 运行时错误 JScript 运行时错误是指当 JScript 脚本试图执行一个系统不能运行的动作时导致的错误。当正在运行脚本、计算变量表达式、或者正在动态分配内存时出现 JScript 运行时错误时。 错误号 描述 5029 数组长度必须为一有限正整数 5030 必须赋给数组长度一个有…

生日蜡烛(蓝桥杯)

某君从某年开始每年都举办一次生日party&#xff0c;并且每次都要吹熄与年龄相同根数的蜡烛。 现在算起来&#xff0c;他一共吹熄了236根蜡烛。 请问&#xff0c;他从多少岁开始过生日party的&#xff1f; 请填写他开始过生日party的年龄数。 注意&#xff1a;你提交的应该是…

python日历模块_Python日历模块| firstweekday()方法与示例

python日历模块Python calendar.firstweekday()方法 (Python calendar.firstweekday() Method) firstweekday() method is an inbuilt method of the calendar module in Python. It works on simple text calendars and returns the current setting for the weekday to start…

php 处理 mysql to json, 前台js处理

public function GetJson(){$query"select * from table";$result mysql_query($query);$rows array();while($row mysql_fetch_array($result)){$rows [] $row;}echo json_encode($rows); } js处理 $.get( "./bll.php", option,function(data ) {var j…

Linux内核设计与实现---进程调度

进程调度1 策略I/O消耗型和处理器消耗型的进程进程优先级时间片进程抢占2 Linux调度算法可执行队列优先级数组重新计算时间片schedule()计算优先级和时间片睡眠和唤醒负载平衡程序3 抢占和上下文切换用户抢占内核抢占4 实时5 与调度相关的系统调用与调度策略和优先级相关的系统…

ServletContext(核心内容)

什么是ServletContext对象 ServletContext代表是一个web应用的环境&#xff08;上下文&#xff09;对象&#xff0c;ServletContext对象 内部封装是该web应用的信息&#xff0c;ServletContext对象一个web应用只有一个 一个web应用有多个servlet对象 ServletContext对象的生…

【转载】[TC]飞船动画例子--《C高级实用程序设计》

【声明和备注】本例子属于转载来源于《C高级实用程序设计》&#xff08;王士元&#xff0c;清华大学出版社&#xff09;第11章&#xff0c;菜单设计与动画技术&#xff0c;第11.5节&#xff0c;一个动画例子。 本例讲解的是在一个繁星背景下&#xff0c;一个由经纬线组成的蓝色…

math.sqrt 有问题_JavaScript中带有示例的Math.SQRT2属性

math.sqrt 有问题JavaScript | Math.SQRT2属性 (JavaScript | Math.SQRT2 Property) Math.SQRT2 is a property in math library of JavaScript that is used to find the value of square root of 2. It is generally used to solve problems related to circular figures. Ma…

Linux内核设计与实现---系统调用

系统调用1 API、POSIX和C库2 系统调用系统调用号3 系统调用处理程序指定恰当的系统调用参数传递4 系统调用的实现参数验证5 系统调用上下文绑定一个系统调用的最后步骤从用户空间访问系统调用为什么不通过系统调用的方式实现1 API、POSIX和C库 API&#xff1a;应用编程接口。一…

内核编译配置选项含义

Linux 2.6.19.x 内核编译配置选项简介 作者&#xff1a;金步国 版权声明 本文作者是一位自由软件爱好者&#xff0c;所以本文虽然不是软件&#xff0c;但是本着 GPL 的精神发布。任何人都可以自由使用、转载、复制和再分发&#xff0c;但必须保留作者署名&#xff0c;亦不得对声…

js编码处理(转)

js编码处理(转) 1. 使用 JS 中的 encodeURIComponent 或 encodeURI 方法。 说明&#xff1a; encodeURIComponent(String) 对传递参数进行设置。不编码字符有 71 个&#xff1a; ! &#xff0c; &#xff0c; ( &#xff0c; ) &#xff0c; * &#xff0c; - &#…

手动去设置HTTP响应行、响应头、响应体

①手动去设置HTTP响应行中的状态码&#xff0c;这里用到了response的setStatus(int sc);这个方法 package com.itheima.line;import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpSer…

Java SecurityManager checkListen()方法与示例

SecurityManager类的checkListen()方法 (SecurityManager Class checkListen() method) checkListen() method is available in java.lang package. checkListen()方法在java.lang包中可用。 checkListen() method invokes checkPermission with the given SocketPermission(&q…

基本的二分查找、寻找第一个和最后一个数的二分查找

二分查找1 二分查找的框架2 寻找一个数&#xff08;基本的二分搜索&#xff09;3 寻找左侧边界的二分搜索4 寻找右侧边界的二分查找5 合并二分查找场景&#xff1a;有序数组寻找一个数、寻找左侧边界&#xff08;有序数组第一个等目标数的下标&#xff09;、寻找右侧边界&#…

PostgreSQL 中的递归查询 与oracle 的比较

PostgreSQL 中的递归查询&#xff0c;2种方法&#xff1a; 1、用with decursive WITH RECURSIVE d AS (SELECT d1.id,d1.parent_id,d1.caption FROM course_types d1 where d1.dr 0 and d1.idtypeId union ALL SELECT d2.id,d2.parent_id,d2.caption FROM course_types d2, d …

教你如何玩转GitHub

使用GitHub ①目的&#xff1a;借助GitHub托管项目代码 基本概念&#xff1a; ①仓库(Repository)&#xff1a; 用来存放项目代码&#xff0c;每个项目对应一个仓库&#xff0c;多个开源项目对应多个仓库 ②收藏(Star)&#xff1a; 收藏项目&#xff0c;方便下次查看 ③…