mirror of
https://github.com/54shady/kernel_drivers_examples.git
synced 2026-01-13 16:02:37 +00:00
vfs read write example
This commit is contained in:
@ -7,7 +7,6 @@
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/device.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#define CHAR_SKELETON_COUNT 1
|
||||
|
||||
36
debug/misc/Makefile
Normal file
36
debug/misc/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
# Makefile
|
||||
# Comment/uncomment the following line to disable/enable debugging
|
||||
# DEBUG = y
|
||||
|
||||
# Usage
|
||||
# make CROSS_COMPILE=<cross_compiler_prefix> KERNEL_DIR=<your_kernel_dir> KERNEL_BUID_OUTPUT=<kernel_buid_output>
|
||||
#
|
||||
# make CROSS_COMPILE=/home/zeroway/rk3399/tool/gcc-linaro-4.9.4-2017.01-i686_aarch64-linux-gnu/bin/aarch64-linux-gnu- KERNEL_DIR=/home/zeroway/rk3399/src/firefly/kernel KERNEL_BUID_OUTPUT=/home/zeroway/rk3399/src/firefly/out/target/product/rk3399_firefly_box/obj/KERNEL
|
||||
|
||||
# Add your debugging flag (or not) to CFLAGS
|
||||
ifeq ($(DEBUG),y)
|
||||
DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
|
||||
else
|
||||
DEBFLAGS = -O2
|
||||
endif
|
||||
|
||||
obj-m := vfs_rw.o
|
||||
|
||||
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
|
||||
KERNEL_BUID_OUTPUT ?=$(KERNEL_DIR)
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
PWD := $(shell pwd)
|
||||
|
||||
modules:
|
||||
$(MAKE) -C $(KERNEL_DIR) ARCH=arm64 M=$(PWD) O=$(KERNEL_BUID_OUTPUT) modules
|
||||
|
||||
clean:
|
||||
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order Module.symvers
|
||||
|
||||
depend .depend dep:
|
||||
$(CC) $(CFLAGS) -M *.c > .depend
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
67
debug/misc/vfs_rw.c
Normal file
67
debug/misc/vfs_rw.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
/* read write buffer */
|
||||
static char wbuf[] = "this is a kernel read write test";
|
||||
static char rbuf[1024];
|
||||
|
||||
#define FILE_NAME "/tmp/vfs_rw_test"
|
||||
|
||||
/*
|
||||
* 在内核中一般不容易生成用户空间的指针
|
||||
* 或者不方便独立使用用户空间内存
|
||||
* 而vfs_read,vfs_write的参数buffer都是用户空间指针
|
||||
* 所以需要调用set_fs目的是为了让内核改变对内存地址检查的处理方式
|
||||
* set_fs参数只有两个USER_DS和KERNEL_DS
|
||||
* USER_DS代表用户空间,set_fs
|
||||
* KERNEL_DS代表内核空间
|
||||
*/
|
||||
static int vfs_rw_init(void)
|
||||
{
|
||||
struct file *fp;
|
||||
mm_segment_t fs;
|
||||
loff_t pos;
|
||||
|
||||
printk("%s, %d\n", __FUNCTION__, __LINE__);
|
||||
|
||||
/* open file */
|
||||
fp = filp_open(FILE_NAME, O_RDWR | O_CREAT, 0644);
|
||||
if (IS_ERR(fp))
|
||||
{
|
||||
printk("create file error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* write file */
|
||||
|
||||
/* get current fs*/
|
||||
fs = get_fs();
|
||||
|
||||
/* 即对内核空间地址检查并做变换 */
|
||||
set_fs(KERNEL_DS);
|
||||
pos = 0;
|
||||
printk("=> %s\n", wbuf);
|
||||
vfs_write(fp, wbuf, sizeof(wbuf), &pos);
|
||||
|
||||
/* read file */
|
||||
pos = 0;
|
||||
vfs_read(fp, rbuf, sizeof(wbuf), &pos);
|
||||
printk("<= %s\n", rbuf);
|
||||
|
||||
/* close file */
|
||||
filp_close(fp, NULL);
|
||||
set_fs(fs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vfs_rw_exit(void)
|
||||
{
|
||||
printk("%s, %d\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
module_init(vfs_rw_init);
|
||||
module_exit(vfs_rw_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
Reference in New Issue
Block a user