Linux

----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----

  文件管理:

  实现COW(copy_on_write:也就是windows下所谓的复制、粘贴):

  

 #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> int main(){
int file = open("test.txt", O_RDONLY); //打开文件
if(file == -){
perror("打开失败");
return ;
}
int new_file = open("love.txt", O_CREAT|O_WRONLY, );
if(new_file == -){
perror("打开失败");
return ;
}
int buff[] = {};
int count = ; count = read(file, buff, );
if(count == -){
perror("读取失败");
return ;
}
while(count){
write(new_file, buff, count);
count = read(file, buff, count);
}
//关闭文件
close(file);
close(new_file);
return ;
}

COW

  

----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----

  进程管理:

#include <linux/init.h>
#include <linux/module.h>
#include<linux/kernel.h>
extern int my_print(int n);
static int hello_init(void)
{
my_print(10);
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Hello World exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Song YanNa");
MODULE_LICENSE("GPL");

TARGET=m
KUER=$(shell uname -r)
KDIR=/lib/modules/$(KUER)/build
PWD=$(shell pwd)
obj-m +=$(TARGET).o
default:
make -C $(KDIR) M=$(PWD) modules

#include <linux/module.h>
#include <linux/blkdev.h>

#define SIMP_BLKDEV_DISKNAME "simp_blkdev" //块设备名
#define SIMP_BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR //主设备号
#define SIMP_BLKDEV_BYTES (50*1024*1024) // 块设备大小为50MB
#define SECTOR_SIZE_SHIFT 9

static struct gendisk *simp_blkdev_disk;// gendisk结构表示一个简单的磁盘设备
static struct block_device_operations simp_blkdev_fops = { //块设备操作,gendisk的一个属性
.owner = THIS_MODULE,
};
static struct request_queue *simp_blkdev_queue;//指向块设备请求队列的指针
unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];// 虚拟磁盘块设备的存储空间

//磁盘块设备数据请求的处理函数
static void simp_blkdev_do_request(struct request_queue *q){
struct request *req;// 正在处理的请求队列中的请求
struct bio *req_bio;// 当前请求的bio
struct bio_vec *bvec;// 当前请求的bio的段(segment)链表
char *disk_mem; // 需要读/写的磁盘区域
char *buffer; // 磁盘块设备的请求在内存中的缓冲区
int i = 0;

while((req = blk_fetch_request(q)) != NULL){
// 判断当前req是否合法
if((blk_rq_pos(req)<<SECTOR_SIZE_SHIFT) + blk_rq_bytes(req) > SIMP_BLKDEV_BYTES){
printk(KERN_ERR SIMP_BLKDEV_DISKNAME":bad request:block=%llu, count=%u\n",(unsigned long long)blk_rq_pos(req),blk_rq_sectors(req));
blk_end_request_all(req, -EIO);
continue;
}
//获取需要操作的内存位置
disk_mem = simp_blkdev_data + (blk_rq_pos(req) << SECTOR_SIZE_SHIFT);
req_bio = req->bio;// 获取当前请求的bio

switch (rq_data_dir(req)) { //判断请求的类型
case READ:
// 遍历req请求的bio链表
while(req_bio != NULL){
// for循环处理bio结构中的bio_vec结构体数组(bio_vec结构体数组代表一个完整的缓冲区)
for(i=0; i<req_bio->bi_vcnt; i++){
bvec = &(req_bio->bi_io_vec[i]);
buffer = kmap(bvec->bv_page) + bvec->bv_offset;
memcpy(buffer, disk_mem, bvec->bv_len);
kunmap(bvec->bv_page);
disk_mem += bvec->bv_len;
}
req_bio = req_bio->bi_next;
}
__blk_end_request_all(req, 0);
break;
case WRITE:
while(req_bio != NULL){
for(i=0; i<req_bio->bi_vcnt; i++){
bvec = &(req_bio->bi_io_vec[i]);
buffer = kmap(bvec->bv_page) + bvec->bv_offset;
memcpy(disk_mem, buffer, bvec->bv_len);
kunmap(bvec->bv_page);
disk_mem += bvec->bv_len;
}
req_bio = req_bio->bi_next;
}
__blk_end_request_all(req, 0);
break;
default:
/* No default because rq_data_dir(req) is 1 bit */
break;
}
}
}

/******************************************************
*
* 模块的入口函数
*
******************************************************/
static int __init simp_blkdev_init(void){
int ret;

//1.添加设备之前,先申请设备的资源
simp_blkdev_disk = alloc_disk(1);
if(!simp_blkdev_disk){
ret = -ENOMEM;
goto err_alloc_disk;
}

//2.设置设备的有关属性(设备名,设备号,fops指针,请求队列,512B的扇区数)
strcpy(simp_blkdev_disk->disk_name,SIMP_BLKDEV_DISKNAME);
simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;
simp_blkdev_disk->first_minor = 0;
simp_blkdev_disk->fops = &simp_blkdev_fops;
// 将块设备请求处理函数的地址传入blk_init_queue函数,初始化一个请求队列
simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request, NULL);
if(!simp_blkdev_queue){
ret = -ENOMEM;
goto err_init_queue;
}
simp_blkdev_disk->queue = simp_blkdev_queue;
set_capacity(simp_blkdev_disk, SIMP_BLKDEV_BYTES>>9);

//3.入口处添加磁盘块设备
add_disk(simp_blkdev_disk);
return 0;

err_alloc_disk:
return ret;
err_init_queue:
return ret;
}

/******************************************************
*
* 模块的出口函数
*
******************************************************/
static void __exit simp_blkdev_exit(void){
del_gendisk(simp_blkdev_disk);// 释放磁盘块设备
put_disk(simp_blkdev_disk); // 释放申请的设备资源
blk_cleanup_queue(simp_blkdev_queue);// 清除请求队列
}

module_init(simp_blkdev_init);// 声明模块的入口
module_exit(simp_blkdev_exit);// 声明模块的出口

ifeq ($(KERNELRELEASE),)
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *.ko .depend *.mod.o *.mod.c Module.* modules.*
.PHONY:modules modules_install clean
else
obj-m := block.o
endif

Linux相关代码的更多相关文章

  1. 手把手教你调试Linux C++ 代码(一步到位包含静态库和动态库调试)

    手把手教你调试Linux C++ 代码 软件调试本身就是一项相对复杂的活动,他不仅要求调试者有着清晰的思路,而且对调试者本身的技能也有很高的要求.Windows下Visual Studio为我们做了很 ...

  2. [转] Linux内核代码风格 CodingStyle [CH]

    from:http://blog.csdn.net/jiang_dlut/article/details/8163731 中文版维护者: 张乐 Zhang Le <r0bertz@gentoo. ...

  3. 临时2级页表的初始化过程 head_32.S 相关代码解释

    page_pde_offset = (__PAGE_OFFSET >> 20); /* __PAGE_OFFSET是0xc0000000,page_pde_offset = 3072 = ...

  4. [置顶] Linux协议栈代码阅读笔记(一)

    Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...

  5. Linux学习笔记:【004】Linux内核代码风格

    Chinese translated version of Documentation/CodingStyle   If you have any comment or update to the c ...

  6. Linux内核代码

    全局描述符表GDT(Global Descriptor Table): (1)在整个系统中,全局描述符表(注意这里是表,表只有一张)GDT只有一张(一个处理器对应一个GDT). (2)GDT可以被放在 ...

  7. [置顶] Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  8. Linux实战教学笔记19:Linux相关网络知识梳理

    第十九节 Linux相关网络知识梳理 标签(空格分隔): Linux实战教学笔记-陈思齐 一,前言 一个运维有时也要和网络打交道,所以具备最基本的网络知识,对一个运维人员来说是必要的.但,对于我们的工 ...

  9. Linux 内核代码风格

    文章目录 从编码风格错误开始 快速修改编码风格的工具 scripts/checkpatch.pl scripts/Lindent astyle Linux 内核代码风格 1) 缩进 2) 把长的行和字 ...

随机推荐

  1. Cookiecutter: 更好的项目模板工具:(1)简介及可用资源汇总

    原文档地址:https://cookiecutter.readthedocs.io/en/latest/ 本系列只介绍cookiecutter的基础使用,而且会删除与功能使用无关的部分.深度使用及了解 ...

  2. HTTP 错误 500.19 - Internal Server Error 无法读取配置节 system.serviceModel 因为它缺少节声明

    服务器环境:Windows Server2008 R2 Enterprise 配置 IIS 的时候报错. 错误信息: HTTP 错误 500.19 - Internal Server Error无法访 ...

  3. Vue.js中滚动条加载更多数据

    本文章参考:http://www.cnblogs.com/ssrsblogs/p/6108423.html 分析:1.需要判断滚动条是否到底部: 需要用到DOM的三个属性值,即scrollTop.cl ...

  4. 本地上传文件至服务器的技巧(linux文件压缩及解压文件)

    linux(ubuntu)文件解压及压缩文件 ubuntu支持文件的解压及压缩功能, 如果ubuntu上面没有安装过unzip工具的话,可以通过下面命令安装: sudo apt-get install ...

  5. 基于nmap扫描结果的端口爆破工具:BrutesPray

      大家搞内网或者C段渗透测试的时候可能遇到很多时候需要对大批的主机进行精确爆破,这时候BruteSpray就派上用场了. BruteSpray是一款基于nmap扫描输出的gnmap/XML文件.自动 ...

  6. python语法_使用占位符进行格式化输出

    “%s”   占位符 name = input("name:") age = input("age:") job = input("job:" ...

  7. ionic3 创建项目至apk打包全过程教程

    主要流程: 安装node.js  -->  安装jdk  -->  安装AndroidSDK  -->  安装cordova  -->  安装ionic -->  创建项 ...

  8. 项目实战03:Keepalived 实现高可用

    目录 实验一:实现keepalived主从方式高可用基于LVS-DR模式的应用实战: 1.环境准备: 2.在lvs-server-master 主上 3.在lvs-server-backup 从上 4 ...

  9. 图->有向无环图->拓扑排序

    文字描述 关于有向无环图的基础定义: 一个无环的有向图称为有向无环图,简称DAG图(directed acycline graph).DAG图是一类较有向树更一般的特殊有向图. 举个例子说明有向无环图 ...

  10. spring--给配置文件.properties加密

    11111111111编写类并继承PropertyPlaceholderConfigurer.java package com.xx.encryptDecrypt; import java.util. ...