前言:进程间通信有:
socket , 共享内存, 消息队列,信号量,信号,环境变量等
一、字符设备驱动框架流程:

二、实列代码跑的效果:






poll的实现主要是使用的内核,驱动程序常用的等待队列
关于系统调用:(以调用open函数)
系统调用触发中断,中断会去找系统调用表通过基地址寻址调用内核sys_open, 然后调用file_operations里的函数。
open与channel_open有什么联系??
1. 调用open
2.触发int ox80的中断,中断的入口函数system_call
3.在system_call里面,调用sys_call_table,系统调用表
4.在unistd.h里,设置系统调用ID, (fork id 2 , read id is 3)
5. sys_call_table通过基地址寻址,sys_call_table+%eax*4-->
6. 调用内核函数sys_open
7. sys_调用file_operations对应的接口
fd位于应用层,而file位于内核层,他们都同属进程相关的概念。在linux中,同一个文件(对应于唯一的inode)可以被不同的进程打开多次,而每次打开都会获得file数据结构。而每个进程都会维护一个已经打开的file数组,fd就是对应file结构的数组下标。因此,file和fd在进程范围内是一一对应的关系。
inode ------- file_ops
fd ------file数组对应,根据fd找到file->file_ops
struct file {
const struct file_operations *f_op;
unsigned int f_flags;// 可读,可写
}
系统调用open,能找到channel_open().流程是这样:open("/dev/ntychannel",) --->每个进程都会被分配个file结构体,---》file结构体里又有个inode, 但是每个文件都有一个inode,inode里有设备号,根据96和0,找到是哪个设备,---》然后通过cdev_init & cdev_add, 把设备cdev和file_operations联系起来。
下面这幅图比较形象:
mknod /dev/ntychennel c 96 0
c:字符设备 96:主设备号 0:次设备号
cat /proc/devices: 查看设备号
mknod 用指定名称产生一个FIFO(命名管道),字符专用或块专用文件




也可以跟下内核的代码:



编译生成的ko文件,sudo insmod ntychannel.ko 报错如下:

获取公钥私钥:https://wiki.gentoo.org/wiki/Signed_kernel_module_support#Enabling_module_signature_verification

sudo su
openssl req -new -nodes -utf8 -sha512 -days 36500 -batch -x509 -config x509.genkey -outform DER -out signing_key.x509 -keyout signing_key.pem

可以思考下:虚拟文件系统(VFS)对mmap前期做了哪些操作?
1 https://www.leviathan.vip/2019/01/13/mmap%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/ 讲解很细,还是需要自己去看下内核源码,然后与该文档进行对照
Linux内核提供了remap_pfn_range函数: 来实现将内核空间的内存映射到用户空间
还有就是内核和驱动常用的等待队列的函数的说明(有点像条件等待)。
几个API是POLL实现的调用的几个内核函数:
wait_event_interruptible(channel->inq, have_data);
在进程执行过程中,有时候需要等待某个条件满足而进行进程阻塞。
常用的一种方法就是让调用者进程暂时挂起,直到目标进程返回结果后,再唤醒等待的进程。
wake_up(&channel->inq); 唤醒等待队列中进程
poll_wait(): 把本进程挂入某个队列
mknod: mknod 函数用于创建各种类型的文件,包括普通文件、特殊文件以及设备文件
设备文件是文件系统中代表设备的特殊文件。与普通的文件相比,设备文件在磁盘(或宿主文件系统所的在其它设备)上只占用一个索引节点,而没有任何用于存放数据的记录块与之相联系。当然,这是因为设备文件的目的并不在于存储和读取数据,而只在于为应用程序提供一条通向具体设备的途径,使应用程序可以跟具体设备建立起连接。
普通文件(以及某些特殊文件)可以通过系统调用 open 来创建,只要在调用参数中或上 O_CREAT 标志,就可以让open函数在目标文件不存在时先创建这个文件。当然也可通过调用 creat() 来直接创建文件,事实上 sys_creat() 就是通过 sys_open() 实现的。可是这两个系统调用都不能用来创建设备文件,因为设备文件的创建需要有一个参数来传递设备号,而 open 和 creat 函数都不包括这个参数。此时就是 mknod 函数存在的意义了。
二、自己实现一个文件系统,无存储文件系统
proc:虚拟文件系统,在linux系统中被挂载与/proc目录下。里面的文件包含了很多系统信息,比如cpu负载、 内存、网络配置和文件系统等等。我们可以通过内部文本流来查看进程信息(正在运行的各个进程的PID号也以目录名形式存在/proc目录下)和机器的状态.
tmpfs:虚拟内存文件系统,使用内存作为临时存储分区,掉电之后会丢失数据,创建时不需要使用mkfs等格式化 。
1.tmpfs挂载:
mount -t tmpfs -o size=20M tmpfs /tmp
df -h
使用/etc/fstab条目:tmpfs /tmp tmpfs default 0 0
2.tmpfs使用:
用来存储临时生成信息
正常使用挂载目录:创建文件,存储信息,删除文件等
3.tmpfs作用
因为内存的访问速度高于flash,所以可以提高存储效率,避免对flash频繁读写(flash寿命有限)
devfs:设备文件,提供类似于文件的方法来管理位于/dev目录下的设备
sysfs:虚拟内存文件系统,2.6内核之前没有规定sysfs的标准挂载目录,但是在2.6之后就规定了要挂载到/sys目录下(针对以前的 sysfs 挂载位置不固定或没有标准被挂载,有些程序从 /proc/mounts 中解析出 sysfs 是否被挂载以及具体的挂载点,这个步骤现在已经不需要了)。它的作用类似于proc,但除了与 proc 相同的具有查看和设定内核参数功能之外,还有为 Linux 统一设备模型作为管理之用。相比于 proc 文件系统,使用 sysfs 导出内核数据的方式更为统一,并且组织的方式更好。
与proc的比较:
sysfs 与 proc 相比有很多优点,最重要的莫过于设计上的清晰。一个 proc 虚拟文件可能有内部格式,如 /proc/scsi/scsi ,它是可读可写的,(其文件权限被错误地标记为了 0444 !,这是内核的一个BUG),并且读写格式不一样,代表不同的操作,应用程序中读到了这个文件的内容一般还需要进行字符串解析,而在写入时需要先用字符串格式化按指定的格式写入字符串进行操作;相比而言, sysfs 的设计原则是一个属性文件只做一件事情, sysfs 属性文件一般只有一个值,直接读取或写入。整个 /proc/scsi 目录在2.6内核中已被标记为过时(LEGACY),它的功能已经被相应的 /sys 属性文件所完全取代。新设计的内核机制应该尽量使用 sysfs 机制,而将 proc 保留给纯净的“进程文件系统”。
文件系统常用的数据结构
struct file_system_type 文件系统类型

struct super_block 超级块 文件系统的根

struct inode、struct inode_operations 索引节点

struct file 、struct file_operations 文件信息

struct dentry 目录项

register_filesystem(&tinyfs_fs_type) -------> tinyfs_mount(mount) ----> mount_nodev(fs_type, flags, data, tinyfs_fill_super)-------->tinyfs_fill_super------->inode_operations/file_operations ----->
inode_operations: create lookup mkdir rmdir unlink 具体实现
file_operations : read write readdir(ls) 具体实现
mount -t proc proc /mnt mount的流程
file inode
file: 存贮的文件的内容
inode: 强调的是磁盘当中存贮的元数据
一个文件系统怎么样才能工作,有以下3个部分
1. insmod kingfs.ko fingfs的文件系统加入全局的链表中
2. mount -t kingfs none /mnt
3. echo "111" > /mnt/a.txt
mount_nodev(fs_type, flags, data, tinyfs_fill_super); //mount -t kingfs none /mnt

为什么在mount的就有?为何不是insmod ko的时候生成?
多个设备使用同一个文件系统,并且mount可以挂载多次。每次实列化的时候,都生成一个,就是类的成员变量。不是静态变量。mount的时候生成super_block.
sb(超级块)管理多个inode, 必须要有inode,才可以存贮数据,具体存贮数据的地方,数据的组织。


linux 0.1.1 __syscall0 跑在用户空间的 unistd.h
open -->sys_open 如何做的?
fn_ptr sys_call_table[]

sys_call_table +NR_fork *4(指针4个字节) :找到系统调用。。 系统调用都是0x80的软中断



https://www.1024sou.com/article/363306.html netlink 协议栈实战
一、libnet库下载:
官网下载地址:
https://github.com/sam-github/libnet
http://sourceforge.net/projects/libnet-dev/
http://packetfactory.openwall.net/projects/libnet/index.html
二、libnet库编译:
CSDN博客上的编译:
http://blog.csdn.net/kanguolaikanguolaik/article/details/9358665
三、libnet库简单示例:
官网示例代码:
http://packetfactory.openwall.net/projects/libnet/dist/deprecated/manual/index.html
四、libnet文档:
官网文档:
http://packetfactory.openwall.net/projects/libnet/dist/deprecated/manual/index.html
三、虚拟文件系统VFS的实现原理
proc: 内核进程信息导入到用户空间,后来是内核信息导入到用户空间
sockfs proc sysfs cgroup 伪文件系统(假的文件系统)
四、用户态文件系统fuse 、/dev/fuse
操作系统的文件系统与分布式文件系统的区别
1. 操作系统的文件系统是根据磁盘做索引的,一块一块的存储,分布式文件系统是基于操作系统的文件系统做的,并且是基于文件本身做索引的
libfuse, 是对/dev/fuse,open read write的一系列的操作的封装 等待更新。。。。
五、虚拟网络适配器的实现
什么是服务器?
(1) 服务器物理硬件laaS (2) 操作系统 服务器版本PaaS 3应用程序 SaaS
服务器为什么能响应网络,网卡
网卡的作用:AD/DA转换
eth0/eth1/eth2: 网络适配器,适配现有绝大多数网卡 ,软件代码适配
网络适配器如何去适配所有的网卡?
1.属性 2.方法 面向对象
net_device实列化一次,就会有一个网络适配器
ifconfig 显示的内容都会存储再struct net_device的对象里
net_device_ops
网友评论