2017-2018-1 20179205《Linux内核原理与设计》第十周作业
《Linux内核原理与设计》第十周作业
教材17、19、20章学习及收获
1、在Linux以及所有unix系统中,设备被分为以下三种:块设备(blkdev)以块为单位寻址,通过块设备节点来访问;字符设备(cdev),不可寻址,通过字符设备节点访问;网络设备:对网络的访问,通过物理适配器和协议进行访问。
2、可装载内核模块:单独的二进制镜像,允许内核在运行时动态插入或删除代码。如果编译到内核中,入口点init存放在内核映像中,并且退出函数不会被包含和调用。
3、导出符号表:只有被导出后的内核函数,才可以被模块调用,代码被配置为模块的时候必须确保接口全部被导出。导出的内核符号表被看做导出的内核接口,内核API。导出指令:EXPORT_SYMBOL()
内核模块相关操作:
make modules_install //把随内核编译出来的模块安装到合适的目录/lib/modules/version/kernel下
depmod //产生内核依赖关系信息
depmod -A // 只为新模块生成依赖信息(速度更快)
insmod module.ko //以root身份运行命令
modprobe module [module parameters] //modprobe提供了模块依赖性分析、错误智能检查、错误报告以及许多其他功能和选项,需以root身份运行,强烈建议使用
rmmod module.ko //以root身份运行命令
modprobe -r module // 同模块的加载类似,modprobe命令也会卸载给定模块所依赖的相关模块
EXPORT_SYMBOL(函数名) //接在要导出的函数后面即可
EXPORT_SYMBOL_GPL(函数名) //和EXPORT_SYMBOL一样,区别在于只对标记为GPL协议的模块可见
内核模块导出符号表 示例:
编写一个导出函数的模块 module_A: test_module_A.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
MODULE_LICENSE("Dual BSD/GPL");
static int test_export_A_init(void)
{
/* 进入内核模块 */
printk(KERN_ALERT "*************************\n");
printk(KERN_ALERT "ENTRY test_export_A!\n");
printk(KERN_ALERT "*************************\n");
printk(KERN_ALERT "\n\n\n\n\n");
return 0;
}
static void test_export_A_exit(void)
{
/* 退出内核模块 */
printk(KERN_ALERT "*************************\n");
printk(KERN_ALERT "EXIT test_export_A!\n");
printk(KERN_ALERT "*************************\n");
printk(KERN_ALERT "\n\n\n\n\n");
}
/* 要导出的函数 */
int export_add10(int param)
{
printk(KERN_ALERT "param from other module is : %d\n", param);
return param + 10;
}
EXPORT_SYMBOL(export_add10);
module_init(test_export_A_init);
module_exit(test_export_A_exit);
4、在安装和卸载多个模块时,要按照先安装模块A,再安装模块B;先卸载模块B,再卸载模块A的顺序进行。
5、统一设备模型的最初动机是为了实现智能的电源管理,linux 内核为了实现智能电源管理,需要建立表示系统中所有设备拓扑关系的树结构,这样在关闭电源时,可以从树的节点开始关闭。统一设备模型的核心部分就是 kobject,使得各个物理设备能够以树结构的形式组织起来。kset是kobject对象的集合体,可以所有相关的kobject置于一个kset之中,比如所有“块设备”可以放在一个表示块设备的kset中。

5、kset,ktype和sysfs都是和kobject息息相关的。
6、在编码可移植性代码时,使用不透明的数据结构不要假设该类型的长度,因为它们在不同的体系结构中可能会发生改变;长度确定的类型只能在内核空间使用, 用户空间无法使用. 用户空间有对应的变量类型, 名称前多了2个下划线。这个在敲代码时很容易出错,本周的linux实验在编译内核模块时我只敲了一个下划线,结果报错。
7、在协调数据对齐时,虽然调整结构体中元素的顺序可以减少填充的字节, 从而降低内存的消耗。但是对于内核中已有的那些结构, 千万不能随便调整其元素顺序, 因为内核中很多现存的方法都是通过元素在结构体中位置偏移来获取元素的。
8、使用 rmb() wmb() 等内存屏障来确保处理器的执行顺序。
9、起初编写的程序时常会有出现bug或者不完善的地方,这时可以通过提交补丁来改善。生成BUG或者改善代码的补丁有2种方法:
- 用diff命令创建补丁
生成patch
diff -urN linux-old/ linux-new/ > my-patch // 比对整个内核代码文件夹
OR
diff -u linux-old/some/file linux-new/some/file > my-patch // 比对某个文件
应用patch 应用了patch之后, linux-old 和 linux-new 中的代码就一样了
cd linux-old
patch -p1 < ../my-patch // 这个命令是进入linux内核代码根目录内执行的
diffstat -p1 my-patch //diffstat工具,列出补丁所引起的变更的统计(加入或移去的代码行)
- 用git命令创建补丁
提交修改的或新增的代码
git commit -a // 提交所有修改的代码
OR
git commit linux-src/some/file.c // 提交某个修改的代码
OR
git add linux-src/some/new-file.c // 把新增的文件加入版本库
git commit -a // 提交新增的文件
生成patch
git format-patch -N //N是正整数, 这条命令生成最后N次提交产生的补丁
OR
git format-patch -1 //最后1次提交产生的补丁
应用patch
和第一种方法一样
总结:
在学习了Linux内核设计与实现这本书后,想要利用Linux系统去做一些实践,比如敲些代码等,那么加入linux社区是很有必要的,因为可以在社区中获取内核最新的消息,而且可以及时和社区内有经验的内核开发者交流经验。同时也是提交代码和讨论代码的地方, 了解社区的规则, 融入社区环境之中, 才能更好的学习内核, 体会内核开发的乐趣和成就感。
问题:
数据对齐是增强可移植性的一个重要方面,意思是数据结构的内存地址可以被4整除。char 类型只占 1个字节, 它的地址不一定能被4整除, 那么转换为 4个字节或者8个字节的 usigned long之后,为什么会导致 unsigned long 出现数据不对齐的现象?
2017-2018-1 20179205《Linux内核原理与设计》第十周作业的更多相关文章
- 2017-2018-1 20179205《Linux内核原理与设计》第九周作业
<Linux内核原理与设计>第九周作业 视频学习及代码分析 一.进程调度时机与进程的切换 不同类型的进程有不同的调度需求,第一种分类:I/O-bound 会频繁的进程I/O,通常会花费很多 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第二周作业
<Linux内核原理与分析>第二周作业 本周视频学习情况: 通过孟老师的视频教程,大致对风诺依曼体系结构有了一个初步的认识,视频从硬件角度和程序员角度对CPU和Main Memory(内存 ...
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
- 20169210《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业
2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...
- 2017-2018-1 20179215《Linux内核原理与分析》第二周作业
20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...
- 2019-2020-1 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...
- 2019-2020-1 20209313《Linux内核原理与分析》第二周作业
2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第四周作业
<Linux内核原理与分析> 视频学习及实验操作 Linux内核源代码 视频中提到了三个我们要重点专注的目录下的代码,一个是arch目录下的x86,支持不同cpu体系架构的源代码:第二个是 ...
随机推荐
- Qt MetaObject System详解
网上的资源比较乱,该文章整理自地址:http://www.xuebuyuan.com/735789.html Qt meta-object系统基于三个方面: 1.QObject提供一个基类,方便派生类 ...
- Redis 学习之主从复制
该文使用centos6.5 64位 redis3.2.8 主从复制 Redis的复制功能是支持多个数据库之间的数据同步.一类是主数据库(master)一类是从数据库(slave),主数据库可以进 ...
- 【Python】安装python包时遇到"error: Microsoft Visual C++ 9.0 is required"的简答
简答 在Windows下用pip安装Scrapy报如下错误, error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall ...
- RESTful Webservice
1,REST和RESTFUL是什么? REST ( REpresentational State Transfer ),State Transfer 为 "状态传输" 或 &quo ...
- 【题解】51nod 1806 wangyurzee的树
看这道题目懵逼了好久, \(m <= 17\) 一眼容斥,然而并没有想到怎么求出生成树的个数.然后灵光一闪——我不是学过一个叫Prüfer编码的东西嘛?!那就完美解决啦~ Prüfer编码就是将 ...
- 容器化RDS|计算存储分离 or 本地存储?
随着交流机会的增多(集中在金融行业,规模都在各自领域数一数二),发现大家对 Docker + Kubernetes 的接受程度超乎想象, 并极有兴趣将这套架构应用到 RDS 领域.数据库服务的需求可以 ...
- getElementsByClassName的原生实现
DOM 提供了一个名为 getElementById() 的方法,这个方法将返回一个对象,这个对象就是参数 id 所对应的元素节点.另外,getElementByTagName() 方法会返回一个对象 ...
- C/C++中二维数组和指针关系分析
在C/c++中,数组和指针有着密切的关系,有很多地方说数组就是指针式错误的一种说法.这两者是不同的数据结构.其实,在C/c++中没有所谓的二维数组,书面表达就是数组的数组.我猜想是为了表述方便才叫它二 ...
- Magic FZU - 2280 无脑HASH暴力
Kim is a magician, he can use n kinds of magic, number from 1 to n. We use string Si to describe mag ...
- stout代码分析之五:UUID类
UUID全称通用唯一识别码,被广泛应用于分布式系统中,让所有的元素具有唯一的标识. stout中UUID类继承自boost::uuids::uuid.api如下: random, 产生一个UUID对象 ...