首页 欧冠联赛正文

优德88 ios_优德88手机投注_优德88官方网站下载

admin 欧冠联赛 2019-07-15 301 0


宏内核和微内核


持续前面榜首章的常识,尽管有点烦琐,已然烦琐了就持续烦琐下去吧,也是给榜首章的内容添加解说。


咱们知道内核假如按品种来差异的话,能够分为宏内核微内核,微内核是一个比较先进的内核,我不知道是不是真的先进,可是 BSD 体系的规划便是想用微内核的思维来完结的,成果导致体系稳定性很差,不能抵达正常运用的程度。


什么是微内核呢? 

假如把CPU当成是皇帝的话,皇帝身边的大臣们就能够差异为各种进程和线程了,比方打印机是一个进程,微内核的思维便是其他进程之间不能直接通讯,他们只能跟CPU中心处理器进程通讯,然后中心进程再做调度处理,这样看起来十分完美,也避免了内核许多高耦合的代码。


什么是宏内核呢?

宏内核的规划就跟微内核有点相反,宏内核的子进程之间是能够相互通讯的,各个模块之间是能够进行函数调用的,你能够调查下 Linux 内核模块,导出内核符号表后,能够在其他模块调用。


这样规划从理论视点来看,代码耦合度比较高,出问题的概率会增大,然后实力打脸的是,Linux 十分成功,耦合度高有坏处也有长处,其间长处得到了充沛的诠释,再加上内核模块能够动态的加载和卸载,这简直不要太完美哦。



(能够点击扩大)

这个图,假如你这样看,或许看不是很清楚,由于图片比较大,你需求点击扩大了来看,就能够看到里边的端倪和不同了。


Monolithic kernel 

是咱们所说的宏内核了,里边的设备文件,驱动,进程间通讯,进程间通讯也能够叫做IPC,这些都是柔和在一个一个形式里边,这个形式叫做内核态,宏内核能够动态加载内核模块,当然了,也能够动态卸载内核模块,你看上面图片那个深红色的当地便是内核态。


Micro kernel 

是咱们说的微内核了,微内核便是中心集权操控的了,已然是中心集权操控,就应该精简,究竟贵族的话,都想自己身份特别点,所以里边便是黄色的往下了许多。


Hybrid kernel

是混合式内核,又是微内核,又是宏内核,windows的规划者便是这么凶猛,你们俩都说自己最凶猛,又都不退一步,或许你们没有发现,或许我才是最凶猛的,所以有人说,Windows 是宏内核,嗯,这样说没什么问题,看看目录[c:\windows\system32\drivers]下面有许多驱动相关的,然后又有人跑出来说,Windows是微内核,嗯,这样说也没有什么不对。

Linux 环境装置


先说下我在榜首章节说的,会在这儿给咱们一个资源链接,我其间包含ubuntu的下载链接,ubuntu假如运转不了的话,需求进入bios翻开虚拟机选项,这个是比较洁净的版别,里边的vim ,git什么的都还没有装置,咱们翻开后需求自己装置,我觉得假如是初学者的话,这样也是要阅历的,了解体系的一个进程。


https://github.com/weiqifa0/linuxBook


作为一个Linux的疯狂分子,我设置的Linux账号暗码便是[ Linux ],咱们可要记住啊。


Linux 内核,能够运转在 x86 体系结构上,也能够运转在 ARM 体系结构上。我刚开端学习 Linux 的时分,十分火急的想要在 ARM 上运转代码,经过这么多年的摸爬滚打,我总算发现那是一个十分打趣的主意,Linux 内核博学多才,你学的是内核,是思维,咱们后边会从是嵌入式Linux开发,安卓开发,openwrt开发,MIFI开发等等,用到的都是Linux内核,会有不同,可是原理性的东西不会不同太大。


所以我想自己给咱们写书的时分,仍是用 ubuntu 来介绍 Linux 内核。至于在在ARM开发板上运转,给咱们说一个东西,叫做穿插编译链,什么是穿插编译链,原本windows是X86体系结构的,正常编译出来的文件,应该只能在X86体系结构上履行,可是有了穿插编译器之后呢,我能够在windows上编译ARM体系结构的固件。


反过来说,你学好了Linux内核,理清了其间的头绪结构,不论你是做安卓开发,仍是嵌入式开发,以及其他衍生的Linux运用或许驱动开发,都会称心如意。


我装置好的 ubuntu 开发环境,有需求的能够下载,下载链接检查前面部分提到的 github 链接,本书的一切例程都上传到 github 上做备份,到前面链接上下载 ubuntu 虚拟机紧缩包,下载后用 VMware 翻开,或许会翻开会有提示犯错,重启电脑,进入 Bios 把虚拟机功用选项设置为 Enable,再从头进入体系就能够看到一个能够让你学习的 ubuntu 体系了。

Linux 内核模块能够做什么?


Linux 内核下面的代码简直都是用内核模块完结开发的,咱们换一个视点来看,内核模块看起来就像是一个运用程序的一段代码,这个点我觉得应该很简略了解,可是它有跟运用程序又不相同,咱们知道内核空间和用户空间地址段是不相同的,内核模块编写需求十分慎重,由于略微不留意就会或许引起体系的溃散,我这样说咱们应该能了解吧,运用空间运转的运用程序有问题,溃散了不要紧,那仅仅它自己挂掉了,可是内核模块不相同,假如内核模块有调用它的当地,比方音频的 ALSA 驱动,假如溃散了,那么整个体系看语音部分就不能作业了。


设备驱动运用内核模块编程,就比方一个触摸屏驱动,在设备模型章节咱们好好聊下这个作业,可是咱们这儿就提一下,一个设备需求依靠一个驱动,没有驱动设备是不或许正常作业了,所以内核模块在体系下的驱动都是用内核模块编写的,Linux 内核下面有十分多的设备,当然就需求十分多的驱动。


文件体系驱动,提到设备文件不得不提一句,Linux 下的一切都能够看做是文件,不同的文件体系还有有一个一致的虚拟文件体系来办理,这些都是需求内核模块来完结的。


体系调用,用户空间的程序需求调用内核服务,就有必要要运用体系调用,正常的体系调用比方关机,读写文件,假如你需求新建一个体系调用也是能够的,那就需求你这个大神自己写个内核模块。


我大约就知道这么多,或许还有些没写出来的,也是内核模块编程规模的,比方网络编程等。

Hello World 内核模块

学习 C 言语的时分,咱们会写一个 Hello World 来证明一下自己,然后咱们学习 C++ 的时分,咱们也会写一个 Hello World 来证明一下自己,再然后咱们会学习 java、python、还有其他许多许多的编程言语,可是最开端,你总是想写一个 Hello World 来证明一下自己。


我也很想知道为什么咱们跟 Hello World 那么过不去,来个比方,这就像咱们习气了喝热水相同,假如细心去追查,如同喝热水并不能怎样怎样,为什么咱们习气喝热水,很大的原因是由于咱们的妈妈想让咱们喝热水,由于咱们的妈妈觉得喝热水是一个好习气,喝热水是能够强身健体的,喝热水包治百病。


再反回来看咱们为什么会在刚开端学习一个东西的时分喜爱去写 Hello World ,由于你触摸的许多人告知你这样做,假如能够,你分明是不需求些 Hello World 的,而是写 Hello You 或许 Hello 等其他什么东西的。


提到这儿,我仍是要写一个 Hello World 来让自己入个门,进入那个莫测高深的国际,倾听 Linux 教导、领会Linux带给咱们的快感。


Hello World 内核模块代码

#include <linux/init.h>

#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)

{

   printk(KERN_ALERT "Hello, world\n");

   return 0;

}

static void hello_exit(void)

{

   printk(KERN_ALERT "Goodbye, cruel world\n");

}

module_init(hello_init);

module_exit(hello_exit);


便是这简略的几行代码,咱们来简略的剖析一下,前面两行是包含头文件,这个跟咱们学习 C 言语没有什么差异,有了头文件才干调用函数,便是这么简略。


第三行,MODULE_LICENSE 这个是声明模块的许可证阐明的,比方一下,咱们开车,就有必要有一个驾驶证,假如咱们没有驾驶证,就会被交警叔叔给捉住,模块代码也相同,假如没有许可证声明,就会被内核给捉住


模块的许可证声明 从 2.4.10 内核版别开端,模块有必要经过 MODULE_LICENSE 宏声明此模块的许可证,否则在加载此模块时,会收到内核被污染 “kernel tainted” 的正告。从 linux/module.h 文件中能够看到,被内核承受的有意义的许可证有 


"GPL",

"GPL v2",

"GPL and additional rights",

"Dual BSD/GPL",

"Dual MPL/GPL",

"Proprietary"


在一同支撑2.4与2.6内核的设备驱动中,模块可按如下办法声明自己的许可证。

MODULE_LICENSE(“GPL”);

然后下面便是声明的两个函数,函数里边调用了 printk 来打印内容,后边再有一个 module_init 和 module_exit ,断章取义,咱们能够知道这两行代码是用来阐明模块初始化和模块退出时调用的函数。


printk 内核打印和调试东西


内核里边是没有 C 库(C库是咱们写C言语的那个库函数)的,咱们刚开端学习 C 言语的时分,知道一个函数叫做 printf ,这个也是一个打印函数,可是这个打印函数需求 C 库的协助,内核里边需求没有C库可是需求自己的打印函数,这个函数就叫做 printk。


不知道咱们想过没有,为什么内核模块里边能够直接调用printk函数,内核模块是归于内核的,printk也是归于内核的,假如内核函数在内核导出了内核符号表,那么这个函数能够被内核里边的其他当地运用,我又要惊叹一下这样的规划了。


KERN_ALERT 这个是一个宏界说,用来操控内核打印的等级,等级很重要,经过操控等级能够动态的操控日志的输出,Linux 经久不衰的原因也是由于有这么多优秀的基因,而其间的这个基因必定是包含 printk


关于内核的打印部分,我觉得后边能够起一个章节独自阐明,调试打印仍是十分有必要的。


编写Makefile编译HelloWorld模块

有源码仍是不行的,就如同咱们烧饭,预备了许多食材,咱们还需求一个锅来照料这些食材,源代码也是相同,它们也是码农的食材,可是也是需求照料的,所以就呈现了许多烹饪办法,咱们码农也触摸到了许多编译器,而在 Linux 下最常用的 便是 GCC 编译器,运用GCC 就离不开 makefile。

咱们给上面的 Hello World 模块编写一个 makefile 吧

ifneq ($(KERNELRELEASE),)

obj-m := hello.o

else

PWD  := $(shell pwd)

KVER := $(shell uname -r)

KDIR := /lib/modules/$(KVER)/build

all:

$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:

rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

endif


许多人写好了Makefile 可是编译却不成功,由于里边还有一些需求留意的当地,特别是初学者,或许要被这几行代码调戏很长时刻,其间需求留意的是要用4空格的Tab键,要不然很大约率会呈现编译犯错。


咱们编译内核需求编译东西Makefile,还需求一个很重要的东西,便是内核库文件,我现在是自己装置了一个ubuntu体系,这个体系在装置的时分现已有了一个内核编译好的库文件,方位便是 KDIR 指定的方位,里边的东西大约如下。


HelloWorld 模块编译的时分,需求从这个库文件里边去找到它需求依靠的函数,头文件等等。

linux@ubuntu:/lib/modules/3.13.0-32-generic/build$ ls

arch    Documentation  fs       ipc      kernel    mm              samples   sound   usr

block   drivers        include  Kbuild   lib       Module.symvers  scripts   tools   virt

crypto  firmware       init     Kconfig  Makefile  net             security  ubuntu

linux@ubuntu:/lib/modules/3.13.0-32-generic/build$


假定像这样的过错

linux@ubuntu:~/linux$ make

Makefile:11: *** missing separator.  Stop.


咱们编译出来的内核模块,是包含必定的信息的,咱们能够运用指令来检查这些信息,当然了,你也能够用这个办法去检查他人编写的内核模块的信息,许多初学者写代码都是哐哐哐,编译经过,高兴一下,运转成功了,高兴一下,彻底不去考虑其间的细节,检查内核模块信息便是其间的一个细节,运用指令和运转成果如下。


linux@ubuntu:~/linuxBook/HelloWorld$ modinfo hello.ko

filename:       hello.ko

license:        Dual BSD/GPL

srcversion:     31FE72DA6A560C890FF9B3F

depends:        

vermagic:       3.13.0-117-generic SMP mod_unload modversions

linux@ubuntu:~/linuxBook/HelloWorld$


内核模块的加载和卸载


内核模块编译好了之后,在当时的途径下会生成一些产品,如下图

linux@ubuntu:~/linux$ ls

hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o  Makefile  modules.order  Module.symvers

linux@ubuntu:~/linux$


这时分,咱们就需求装载这个内核模块到内核里,Linux 内核里边有一个链表来保护在运转中的内核模块,咱们装载内核模块,便是往这个链表刺进咱们的内核模块,像下面的图片相同,假如你想得极点一点,就有点像插队。

装载 HelloWorld 内核模块

linux@ubuntu:~/linux$ sudo insmod hello.ko

[sudo] password for linux:

linux@ubuntu:~/linux$

输入 sudo insmod hello.ko 后,需求输入 su 超级用户的暗码,这个时分,咱们理论上就会履行module_init ,会有一个打印出来,咱们去哪里看这个打印了这样输入指令 dmesg |tail -5 检查后边 5 行日志。

linux@ubuntu:~/linux$ dmesg |tail -5

[ 1154.971812] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

[41991.859527] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None

[41991.869932] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready

[41991.870367] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

[42035.102864] Hello, world

linux@ubuntu:~/linux$

相同咱们去卸载内核模块的时分,履行指令sudo rmmod hello.ko

linux@ubuntu:~/linux$ dmesg |tail -5

[41991.859527] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None

[41991.869932] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready

[41991.870367] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

[42035.102864] Hello, world

[42284.945557] Goodbye, cruel world

linux@ubuntu:~/linux$

insmod 和rmmod 的流程图如下面的图片,我这个图片引证的是其他书本里边的,有或许跟最新的内核有收支,可是大致不会相差太多,能够作为参阅。

(内核模块加载的流程图)


Module_init


Linux 内核里边十分多的代码都是经过模块的办法加载的,可是每个模块的加载次序都是不相同的,比方设备驱动,由于设备驱动是在体系启动完结后再进行加载的,归于偏后边一些,可是必定有一些中心组件需求提早加载的(比方时钟,I2C core等),由于需求不同的加载次序,就有了不同等级的xx_init等级。


\include\linux\init.h里边界说了不同的等级函数,数字越低,代表的等级越高,越早加载。


/*

* A "pure" initcall has no dependencies on anything else, and purely

* initializes variables that couldn't be statically initialized.

*

* This only exists for built-in code, not for modules.

* Keep main.c:initcall_level_names[] in sync.

*/

#define pure_initcall(fn) __define_initcall(fn, 0)

#define core_initcall(fn) __define_initcall(fn, 1)

#define core_initcall_sync(fn) __define_initcall(fn, 1s)

#define postcore_initcall(fn) __define_initcall(fn, 2)

#define postcore_initcall_sync(fn) __define_initcall(fn, 2s)

#define arch_initcall(fn) __define_initcall(fn, 3)

#define arch_initcall_sync(fn) __define_initcall(fn, 3s)

#define subsys_initcall(fn) __define_initcall(fn, 4)

#define subsys_initcall_sync(fn) __define_initcall(fn, 4s)

#define fs_initcall(fn) __define_initcall(fn, 5)

#define fs_initcall_sync(fn) __define_initcall(fn, 5s)

#define rootfs_initcall(fn) __define_initcall(fn, rootfs)

#define device_initcall(fn) __define_initcall(fn, 6)

#define device_initcall_sync(fn) __define_initcall(fn, 6s)

#define late_initcall(fn) __define_initcall(fn, 7)

#define late_initcall_sync(fn) __define_initcall(fn, 7s)

#define __initcall(fn) device_initcall(fn)

#define __exitcall(fn) \

static exitcall_t __exitcall_##fn __exit_call = fn

#define console_initcall(fn) \

static initcall_t __initcall_##fn \

__used __section(.con_initcall.init) = fn

......

/**

* module_init() - driver initialization entry point

* @x: function to be run at kernel boot time or module insertion

*

* module_init() will either be called during do_initcalls() (if

* builtin) or at module insertion time (if a module).  There can only

* be one per module.

*/

#define module_init(x) __initcall(x);

/**

* module_exit() - driver exit entry point

* @x: function to be run when driver is removed

*

* module_exit() will wrap the driver clean-up code

* with cleanup_module() when used with rmmod when

* the driver is a module.  If the driver is statically

* compiled into the kernel, module_exit() has no effect.

* There can only be one per module.

*/

#define module_exit(x) __exitcall(x);


能够看到 module_init 实际上是__define_initcall(fn, 6) 归于设备等级的初始化,咱们之前一向在说Linux 内核支撑动态模块加载,Linux内核的许多子体系都是经过模块化来规划的,已然有动态加载,那就有必要有静态加载,假如需求内核静态加载的话,就有必要把这些内核模块编译进内核里边,咱们学习内核编译的时分,必定还记住一个 [*]和[M],只需简略的装备一下,就决议了你这个模块是作为一个独自的模块仍是作为内核的一个部分。


这个加载次序我认为是十分有用的,我之前做项目的时分,咱们搭档有个需求,需求A驱动有必要要在B驱动之前加载,并且尽或许早的加载,这时分,就用到了不同的优先等级的xx_init了。



Linux 内核模块的依靠装置(动态加载模块)


我如同在之前说过,Linux 内核是宏内核,内核模块之间是能够相互进行函数调用的,这样的耦合性是比较高的,所以呢,Linux 内核必定是存在依靠联系的,就如同,我像喝水,然后我首要要找到一个杯子,然后还要找到饮水机,等等等等。


依照上面的指令,咱们装置一个内核模块运用 insmod 指令,假如这个模块依靠另一个模块呢?

那就再需求用 insmod 装置另一个模块,这样看起来比较费事,所以就有了这个指令 modprobe,modprobe能够动态的装置内核模块,假如发现有依靠联系,就把需求依靠的内核模块也装置了。


提示一下,初学者做这个的时分,必定会遇到一些意想不到的问题,所以我也针对这些问题做了些总结,期望看完文章的同学不会踩坑。


Makefile 文件

$(info $(PWD))

$(info $(VER))

ifneq ($(KERNELRELEASE),)

obj-m := hello.o

else

PWD  := $(shell pwd)

KVER := $(shell uname -r)

KDIR := /lib/modules/$(KVER)/build

all:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

install:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install

clean:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

endif

源文件跟之前的HelloWorld相同,就不贴出来了,这儿主要是多了一个 make install 编译,用来装置内核模块。


运转modprobe 之前,要先运转depmod -a来更新依靠文件

linux@ubuntu:/lib/modules$ uname -r

3.13.0-117-generic

linux@ubuntu:/lib/modules$ cd /lib/modules/3.13.0-117-generic/


linux@ubuntu:/lib/modules/3.13.0-117-generic$ sudo depmod -a


linux@ubuntu:/lib/modules/3.13.0-117-generic$ cat modules.dep |tail -2

kernel/lib/percpu_test.ko:

extra/hello.ko:

linux@ubuntu:/lib/modules/3.13.0-117-generic$


然后再履行 modprobe -v hello ,后边跟的是 hello 而不是 hello.ko ,假如你输入 hello.ko 的话,会一向提示找不到该模块。

linux@ubuntu:/lib/modules/3.13.0-117-generic$ modprobe -v hello

linux@ubuntu:/lib/modules/3.13.0-117-generic$ dmesg|tail -2

[244664.594921] Goodbye, cruel world

[245400.931435] Hello, world

linux@ubuntu:/lib/modules/3.13.0-117-generic$ sudo modprobe -r hello

linux@ubuntu:/lib/modules/3.13.0-117-generic$ dmesg|tail -2

[245400.931435] Hello, world

[246484.772567] Goodbye, cruel world

linux@ubuntu:/lib/modules/3.13.0-117-generic$


内核空间和用户空间


上面这两个姓名有点拗口,或许能够这样说,内核地址和用户地址,内核态和用户态实际上便是经过地址来差异的。


我觉得作为初学者,把这个图片看了解,然后再把周围的英文自己看了解,然后把他们吃透,多看几回,多了解几回,多问几回,这样之后再去看其他的内容。


假如把Linux 看作是一个一个家庭,一个家庭首要就需求有一个房子,这便是硬件设备,然后呢爸爸妈妈便是这个家庭的内核,孩子们便是这个家庭用户空间进程,爸爸妈妈需求为这个家庭付出房租,水电,买吃的,喝的,还有给孩子们烧饭,洗衣服等等。那孩子们做什么作业呢?孩子们就担任上学,担任玩,他们要吃了,就找爸爸妈妈去拿,想睡觉了,就去睡觉,总归,他们不是这个家庭的根底,假如内核空间没有了,这个家庭必定就瓦解了,可是用户没有了,内核仍是会存在,这便是咱们所说的丁克家庭。


我举个比方,家庭里的小孩有一天想吃饭,好了,他把碗拿到桌子边上,敲着碗说,爸爸妈妈,爸爸妈妈,快给我吃饭,然后呢,CPU就需求跳转到内核态,让爸爸妈妈去给小孩预备食物,预备好了,小孩就能够吃饭了,这时分CPU又回到了用户态履行。


有一天,我很高兴的在上网,然后又一张图片印入了我的眼皮,你应该猜到了,便是下面这张图片,这张图片十分完美的解说了用户空间和内核空间,作者给咱们举得比方便是体系调用,体系调用了write的函数办法,在调用的进程中,CPU跳转到内核空间履行,函数履行完毕后,又会跳转到用户空间履行。


构建自己的 Linux 内核


咱们想学习 Linux 内核,一个最重要的条件是会构建自己的 Linux 内核,要不然便是仅仅一个空谈家,我的书本也是期望给咱们一个这样着手的条件,理论加实践相结合来浸透进入 Linux 内核,我在前面现已给咱们供给了一个装置好的 ubuntu 体系,咱们就用这个 ubuntu 开刀,扒出咱们自己的 Linux 内核。


获取内核源码

sudo apt-cache search linux-source

sudo apt-get install linux-source-3.2.0

榜首句是查询 Linux 内核源码,便是说咱们现在运转的这个 ubuntu的体系内核源码是哪个版其他,咱们假如要开发自己的内核,有必要要有完好的内核源码,我说的 ubuntu 指的是我上面给出链接的那个。

第二句是装置 Linux 内核源码,装置完后在 /usr/src 下面有有源码紧缩包。

ubuntu 下的 Linux 内核源码方位

/usr/src

咱们装置了 ubuntu 下面就有了 linux 内核源码,可是这个源码需求咱们自己解压出来,对应的应该是

linux@ubuntu:/usr/src$ ls

linux-headers-3.13.0-117          linux-headers-3.13.0-32-generic

linux-headers-3.13.0-117-generic  linux-source-3.2.0

linux-headers-3.13.0-32           linux-source-3.2.0.tar.bz2

linux@ubuntu:/usr/src$


所以便是这个紧缩包了

linux-source-3.2.0.tar.bz2


运用 make menuconfig 装备自己的内核

咱们有了自己的源码,还需求一个 .config 来装备内核,国际上的硬件设备千千万万,咱们就只有一个内核源码,他们最大的差异便是装备文件了,所以咱们就需求一个装备文件,这一步也很简略。

运用 uname -a 检查内核版别号

root@ubuntu:/usr/src# uname -a

Linux ubuntu 3.13.0-117-generic #164~precise1-Ubuntu SMP Mon Apr 10 16:16:25 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

root@ubuntu:/usr/src#


把内核版别号下面的 .config 复制到内核源码下面

root@ubuntu:/usr/src# cp linux-headers-3.13.0-117-generic/.config linux-source-3.2.0/linux-source-3.2.0/


运用 make menuconfig 装备内核

这一步不要做任何修正,直接 exit 就能够了,能够履行看看装备的界面爽一把是能够的。


编译内核

履行 make bzImage -jN 编译内核,我截取了编译进程中的一些输出日志,这儿的 N 能够指定并行编译的线程,但不限定是core的个数。

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$sudo make bzImage -j6

[sudo] password for linux:

 CHK     include/linux/version.h

make[1]: Nothing to be done for `relocs'.

 CHK     include/generated/utsrelease.h

 CALL    scripts/checksyscalls.sh

 CHK     include/generated/compile.h

 VDSOSYM arch/x86/vdso/vdso-syms.lds

 VDSOSYM arch/x86/vdso/vdso32-int80-syms.lds

 VDSOSYM arch/x86/vdso/vdso32-syscall-syms.lds

 VDSOSYM arch/x86/vdso/vdso32-sysenter-syms.lds

 VDSOSYM arch/x86/vdso/vdso32-syms.lds

 LD      arch/x86/vdso/built-in.o

 LD      arch/x86/built-in.o

 LD      vmlinux.o

 MODPOST vmlinux.o

 GEN     .version

 CHK     include/generated/compile.h

 UPD     include/generated/compile.h

 CC      init/version.o

 LD      init/built-in.o

 LD      .tmp_vmlinux1

 KSYM    .tmp_kallsyms1.S

 AS      .tmp_kallsyms1.o

 LD      .tmp_vmlinux2

 KSYM    .tmp_kallsyms2.S

 AS      .tmp_kallsyms2.o

 LD      vmlinux

 SYSMAP  System.map

 SYSMAP  .tmp_System.map

 VOFFSET arch/x86/boot/voffset.h

 CC      arch/x86/boot/version.o

 OBJCOPY arch/x86/boot/compressed/vmlinux.bin

 GZIP    arch/x86/boot/compressed/vmlinux.bin.gz

 MKPIGGY arch/x86/boot/compressed/piggy.S

 AS      arch/x86/boot/compressed/piggy.o

 LD      arch/x86/boot/compressed/vmlinux

 ZOFFSET arch/x86/boot/zoffset.h

 OBJCOPY arch/x86/boot/vmlinux.bin

 AS      arch/x86/boot/header.o

 LD      arch/x86/boot/setup.elf

 OBJCOPY arch/x86/boot/setup.bin

 BUILD   arch/x86/boot/bzImage

Setup is 17052 bytes (padded to 17408 bytes).

System is 4422 kB

CRC e36fccb0

Kernel: arch/x86/boot/bzImage is ready  (#2)

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$


编译 Linux 内核模块

咱们履行 make modules - j4 编译内核模块,咱们前面说了,Linux 内核下面都是依照模块化来编程的,咱们需求把这些模块编译出来,然后再装置到现在运转的 ubuntu 体系上,就完结了Linux 内核的装置。


履行的时分有或许呈现一些什么问题,找到 error 相关的 Log ,百度找一下答案就能够了,如下是我履行的成果

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$ sudo make modules -j6

[sudo] password for linux:

 CHK     include/linux/version.h

make[1]: Nothing to be done for `relocs'.

 CHK     include/generated/utsrelease.h

 CALL    scripts/checksyscalls.sh

 Building modules, stage 2.

 MODPOST 2801 modules

WARNING: modpost: Found 4 section mismatch(es).

To see full details build your kernel with:

'make CONFIG_DEBUG_SECTION_MISMATCH=y'

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$


装置内核

先装置内核模块,运用这个骚指令make modules_install

$sudo make modules_install

INSTALL /lib/firmware/keyspan_pda/keyspan_pda.fw

 INSTALL /lib/firmware/keyspan_pda/xircom_pgs.fw

 INSTALL /lib/firmware/cpia2/stv0672_vp4.bin

 INSTALL /lib/firmware/yam/1200.bin

 INSTALL /lib/firmware/yam/9600.bin

 DEPMOD  3.2.79

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$


然后装置内核,运用这个指令make install

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$ sudo make install

sh /usr/src/linux-source-3.2.0/linux-source-3.2.0/arch/x86/boot/install.sh 3.2.79 arch/x86/boot/bzImage \

System.map "/boot"

run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 3.2.79 /boot/vmlinuz-3.2.79

run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.2.79 /boot/vmlinuz-3.2.79

update-initramfs: Generating /boot/initrd.img-3.2.79

run-parts: executing /etc/kernel/postinst.d/pm-utils 3.2.79 /boot/vmlinuz-3.2.79

run-parts: executing /etc/kernel/postinst.d/update-notifier 3.2.79 /boot/vmlinuz-3.2.79

run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.2.79 /boot/vmlinuz-3.2.79

Generating grub.cfg ...

Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.

Found linux image: /boot/vmlinuz-3.13.0-117-generic

Found initrd image: /boot/initrd.img-3.13.0-117-generic

Found linux image: /boot/vmlinuz-3.13.0-32-generic

Found initrd image: /boot/initrd.img-3.13.0-32-generic

Found linux image: /boot/vmlinuz-3.2.79

Found initrd image: /boot/initrd.img-3.2.79

Found memtest86+ image: /boot/memtest86+.bin

done

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$

检查新装置的内核

内核装置完结之后,咱们怎样判别新装置的内核是自己编译出来的呢?这个操作十分要害,许多码农写了代码烧录后,发现履行的状况不如自己的预期,也没有去检查有没有烧录成功,就不断的修正代码排查,这个是十分初级的过错。

生成initrd.img文件,运用指令update-initramfs。

#cd /lib/modules/3.2.79

root@ubuntu:/lib/modules# update-initramfs -c -k 3.2.79

update-initramfs: Generating /boot/initrd.img-3.2.79

root@ubuntu:/lib/modules#


运用 update-grub2 更新新的内核,这个指令会去查找当时存在的新内核,然后用新的内核去装置引导。

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$ sudo update-grub2

Generating grub.cfg ...

Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.

Found linux image: /boot/vmlinuz-3.13.0-117-generic

Found initrd image: /boot/initrd.img-3.13.0-117-generic

Found linux image: /boot/vmlinuz-3.13.0-32-generic

Found initrd image: /boot/initrd.img-3.13.0-32-generic

Found linux image: /boot/vmlinuz-3.2.79

Found initrd image: /boot/initrd.img-3.2.79

Found memtest86+ image: /boot/memtest86+.bin

done

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$


检查重启前运转的内核版别

linux@ubuntu:/usr/src/linux-source-3.2.0/linux-source-3.2.0$ uname -a

Linux ubuntu 3.13.0-117-generic #164~precise1-Ubuntu SMP Mon Apr 10 16:16:25 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

重启体系 shutdown -r now

这时分重启,你应该是看不到咱们的内核版其他,由于咱们用的是 ubuntu ,还有一些怪异的当地需求设置,其间就需求设置的是 /etc/grub.d/00_header

vim /etc/grub.d/00_header 修正style="countdown"为style="menu",这样咱们在开机的时分就能够挑选咱们体系里边的内核了,要不然就一向是一个默许的内核。


经过上面的骚操作之后,咱们再重启,重启的进程中会提示咱们挑选内核版别,咱们记住别选本来的内核版别了,选一个咱们本来不知道的内核版别,然后自傲的按下回车键,等候一下。


这时分,咱们再来检查一下内核版别

root@ubuntu:~# uname -a

Linux ubuntu 3.2.79 #4 SMP Wed Jun 12 19:33:11 PDT 2019 x86_64 x86_64 x86_64 GNU/Linux

root@ubuntu:~#


总结


内核模块是根底,是咱们开发内核的根底,可是又由于根底的东西难度不是十分大,所以写的也比较轻松,不过学习的时分,不应该慢待,该敲代码的时分,就敲代码,该看书的时分,就看看书,有了解不了的,就提下问题。厚实的根底就应该在学习的时分边着手边考虑,加深自己的形象。


原创文章写起来十分不简略,辛苦是在所难免的,由于从后边开端,没一个章节的篇幅就添加许多,所以我会拆开来写,比方一个章节我发几回。


我的文章后边默许翻开欣赏,原因是我的原创姓名和欣赏账号相同,也是由于懒的原因,这样我只需求点击一下就能够填好原创的作者,翻开欣赏不是想咱们给我多少钱,也是想得到读者们的必定,假如是学生还不如藏着钱去追下妹子,大学美好时光来之不易,该浪荡的时分就不要浪费了,可是觉得不错,有协助的,能够给个转发支撑一下,感激不尽。


下一章节会讲内核调试的一些办法,包含GDB,/proc文件体系调试,还有加dump_stack等手法来调试等等



引荐阅览

第1章  Linux内核概述

============================


引荐一下我自己的常识星球


1、首要十分感谢咱们付费进入我的常识星球,这是对我的必定,我也将尽心竭力协助咱们一同生长,假如有任何问题,请点击[发问]咨询我。假如有问题我答复不了的,请定心,我也会竭尽所能协助你,周建功是我的微信老友,我也有知道一些天使投资人,创业者,在各大企业从事作业的许多专业性的朋友。 


2、其次,我想说,人在生长进程中,必定是需求一个指引者的,需求一个让你信任他的人,许多时分,咱们也不知道前方对错,咱们很想得到一个背面的力气,我觉得这个十分重要,相互鼓舞,一起生长。 


3、再次,我觉得为了鼓舞咱们沟通,假如自动答复问题,被采用的话,我会给予 5 元欣赏奖赏,欣赏的钱会抵达你的常识星球钱包里边。约请朋友进来的,我会给予 20 元奖赏,鼓舞构成一个合作的社群。



版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

最近发表

    优德88手机客户端_w88优德_w88

    http://www.hongshengqp.com/

    |

    Powered By

    使用手机软件扫描微信二维码

    关注我们可获取更多热点资讯

    w88出品