diff --git a/study/driver/00-code/android/Makefile b/study/driver/00-code/android/Makefile new file mode 100644 index 0000000..5f9bbbc --- /dev/null +++ b/study/driver/00-code/android/Makefile @@ -0,0 +1,31 @@ +#direntorys +HELLO_DIR=hello +CPLD_DIR=cpld +FPGA_DIR=fpga +TEST_MODULE_DIR=test_module +DIRS=$(HELLO_DIR) $(CPLD_DIR) $(FPGA_DIR) $(TEST_MODULE_DIR) + +SUBDIRS=$(DIRS) + +.PHONY:all $(SUBDIRS) + +all: $(SUBDIRS) + +$(SUBDIRS): + $(MAKE) -C $@ + @echo "=======BUILD $@ SUCCESS=======" + +#all : +# for i in $(DIRS); do \ +# (cd $$i && echo "making $$i" && $(MAKE) ) || exit 1; \ +# done + +clean: + for i in $(DIRS); do \ + (cd $$i && echo "cleaning $$i" && $(MAKE) clean) || exit 1; \ + done + +install : + for i in $(DIRS); do \ + (cd $$i && echo "install $$i" && $(MAKE) install) || exit 1; \ + done diff --git a/study/driver/00-code/android/cpld/Makefile b/study/driver/00-code/android/cpld/Makefile new file mode 100644 index 0000000..12e727d --- /dev/null +++ b/study/driver/00-code/android/cpld/Makefile @@ -0,0 +1,85 @@ +# ------------------------------------------------------------------------------ +# +# Makefile for the LDD-LinuxDeviceDrivers. +# +# Author: gatieme +# Create: 2016-07-29 15:50:46 +# Last modified: 2016-07-29 16:10:29 +# Description: +# This program is loaded as a kernel(v2.6.18 or later) module. +# Use "make install" to load it into kernel. +# Use "make remove" to remove the module out of kernel. +# +# ------------------------------------------------------------------------------ + + + +# my driver description +DRIVER_VERSION := "1.0.0" +DRIVER_AUTHOR := "Gatieme @ AderStep Inc..." +DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices" +DRIVER_LICENSE := "Dual BSD/GPL" + + + +MODULE_NAME := ccpld + +ifneq ($(KERNELRELEASE),) + +#CFG_FLAGS += -O2 -I./ +#EXTRA_CFLAGS += $(C_FLAGS) $(CFG_INC) $(CFG_INC) + + + +RESMAIN_CORE_OBJS := cpld.o +RESMAIN_GLUE_OBJS := slaveSerial.o + + +ccpld-objs := $(RESMAIN_GLUE_OBJS) $(RESMAIN_CORE_OBJS) +obj-m := $(MODULE_NAME).o + +else + +CURRENT_PATH ?= $(shell pwd) +ifeq ($(ARCH),arm64) +LINUX_KERNEL_PATH ?= /home/rockchip/rk3399/Android/7.1/android/kernel +else +LINUX_KERNEL ?= $(shell uname -r) +LINUX_KERNEL_PATH ?= /lib/modules/$(LINUX_KERNEL)/build +endif + +modules: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules + +modules_install: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules_install + + + +insmod: + sudo insmod $(MODULE_NAME).ko + +reinsmod: + sudo rmmod $(MODULE_NAME) + sudo insmod $(MODULE_NAME).ko + +github: + cd $(ROOT) && make github + +rmmod: + sudo rmmod $(MODULE_NAME) + +test : + sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1 + +clean: + make -C $(LINUX_KERNEL_PATH) M=$(PWD) clean + rm -f modules.order Module.symvers Module.markers + +.PHNOY: + modules modules_install clean + + + +endif + diff --git a/study/driver/00-code/android/cpld/cpld.c b/study/driver/00-code/android/cpld/cpld.c new file mode 100644 index 0000000..17be27f --- /dev/null +++ b/study/driver/00-code/android/cpld/cpld.c @@ -0,0 +1,209 @@ +/* +CPLD test +byTX +2013.1.31:add cpld_ioctl +*/ +#include +#include +#include +#include +//#include +//for file opration +#include +//for cdev create +#include +//#include + +//#include +//#include +//#include +//#include +//#include +//#include +//copy_to_user +#include +//class_create +#include +//#include +//#include +//#include +//#include +//ioremap defined here +#include +#include "slaveSerial.h" +//#include + +#include +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Gatieme"); +MODULE_DESCRIPTION("hello world"); + + +static void __iomem *io_base; +struct cdev *cpld_cdev; +struct class *cpld_class; +dev_t devid; + +static int cpld_open(struct inode *inode, struct file *file) +{ + //可配置eint18,并复位cpld + printk("cpld open\n"); + return 0; +} +//read ,do not change f_pos +ssize_t cpld_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + unsigned short int tmp; +#if DEBUG_PRINT + printk("f_pos=0x%x\n",*(unsigned int*)f_pos); +#endif + tmp=ioread16(io_base+(*f_pos)); +#if DEBUG_PRINT + printk("cpld read =0x%x\n",tmp); +#endif + //return copy_to_user(buf,(char *)&tmp,sizeof(unsigned short int)); + *(unsigned short int*)buf=tmp; + return 2;//always read 2bytes +} +//write ,do not change f_pos +ssize_t cpld_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ +#if DEBUG_PRINT + printk("f_pos=0x%x count=%d\n",*(unsigned int*)f_pos,count); +#endif + if(count==2) + { + iowrite16(*(unsigned short int*)buf,io_base+(*f_pos)); +#if DEBUG_PRINT + printk("write data=0x%x\n",*(unsigned short int*)buf); +#endif + return count; + } +/* + else if(count==FPGA_BURST_SIZE)//多字节连续写入 + { + for(i=0;i=0 && offsetf_pos = new_pos; + return new_pos; +} + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) +static int cpld_ioctl(struct inode *indoe, struct file *file, + unsigned int cmd, unsigned long arg) +{ +#else +//long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); +//long (*compat_ioctl) (struct file *file, unsigned int cmd, unsigned long arg) +static long cpld_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + //struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = inode = file_inode(file); +#endif + switch(cmd) + { + case CMD_START_SHIFT: + shiftWordOut((unsigned short int)arg,io_base); + break; + case CMD_START_PROG: + set_prog_b(io_base,0); //?????? 这函数功能-设置boot值,io_base+REG_PROG_B_OFFSET + set_prog_b(io_base,0); + set_prog_b(io_base,1); + break; + case CMD_CHECK_DONE: + return check_done(io_base); //这check_done在slaveSerial.c中,检查是否下载完成 + case CMD_SET_LED: + iowrite16((arg>0)?SET_LED_ON:SET_LED_OFF, io_base+REG_LED_OFFSET); + break; + case CMD_SEND_LOW_BYTE: + shiftByteOut((char)arg,io_base); + break; + case CMD_SEND_HIGH_BYTE: + shiftByteOut((char)(arg>>8),io_base); + break; + case CMD_CHECK_INIT: + return get_init_bit(io_base); + break; + case CMD_SET_CONTROL: + iowrite16((unsigned short int)arg,io_base+REG_CONTROL_OFFSET); ///?????REG_CONTROL_OFFSET在哪里定义的?arg是要设置的值,第二个参数是地址 + break; + case CMD_SET_DATA: + iowrite16((unsigned short int)arg,io_base+REG_DATA_OFFSET); + break; + default: + break; + } + return 0; +} + + +static struct file_operations cpld_fops = { + .owner = THIS_MODULE, + .open = cpld_open, + .read = cpld_read, + .write = cpld_write, + .llseek = cpld_llseek, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) + .ioctl = cpld_ioctl, +#else + .compat_ioctl = cpld_compat_ioctl, +#endif +}; +static int __init cpld_init(void) +{ + + //创建字符设备 + cpld_cdev=cdev_alloc(); + cdev_init(cpld_cdev, &cpld_fops); + cpld_cdev->owner = THIS_MODULE; + + alloc_chrdev_region(&devid, 0, 1, "cpld"); + cdev_add(cpld_cdev,devid,1); + + cpld_class = class_create(THIS_MODULE,"cpld_class"); + device_create(cpld_class, NULL, devid, NULL,"cpld"); + //申请内存 + io_base=ioremap(CPLD_BASE,CPLD_SIZE); + if(io_base==0) + printk("failed to ioremap cpld\n"); + else + printk("cpld test reg.=0x%x\n",ioread16(io_base+REG_TEST_OFFSET)); + printk("CPLD initialized.\n"); + return 0; +} +static void __exit cpld_exit(void) +{ + unregister_chrdev_region(devid,1); + device_destroy(cpld_class , devid); + class_destroy(cpld_class); + cdev_del(cpld_cdev); + iounmap(io_base); + printk("cpld exit\n"); +} + +module_init(cpld_init); +module_exit(cpld_exit); + diff --git a/study/driver/00-code/android/cpld/slaveSerial.c b/study/driver/00-code/android/cpld/slaveSerial.c new file mode 100644 index 0000000..60f7861 --- /dev/null +++ b/study/driver/00-code/android/cpld/slaveSerial.c @@ -0,0 +1,110 @@ +/* + 2013.1.31byTX +*/ +#include #include +#include "slaveSerial.h" + + +/* +assert cclk when value>1 +*/ +void set_cclk(void *io_base,int value) +{ + iowrite16((value>0)?1:0,io_base+REG_CCLK_OFFSET); +} +/* +assert din when value>0 +*/ +void set_din(void *io_base,int value) +{ + iowrite16((value>0)?1:0,io_base+REG_DIN_OFFSET); +} +/* +assert prog_b when value>0 +*/ +void set_prog_b(void *io_base,int value) +{ + iowrite16((value>0)?1:0,io_base+REG_PROG_B_OFFSET); +} +/* + +*/ +unsigned short int get_stat(void *io_base) +{ + return ioread16(io_base+REG_STAT_OFFSET); +} +//返回pin状态 +int get_done_bit(void *io_base) +{ + return ((get_stat(io_base)& STAT_DONE_BIT)>0)?1:0; +} +//返回pin状态 +int get_init_bit(void *io_base) +{ + return ((get_stat(io_base)& STAT_INIT_BIT)>0)?1:0; +} +int check_done(void *io_base) +{ + int i; + int done=0; + int init=1; + //check init first!! + if(0==get_init_bit(io_base)) + { + printk("init=0,so failed\n"); + return INFOR_DONE_FAILED; + } + while((done==0) && (init==1)) + { + //Apply additional CCLK pulse until DONE=1 + set_cclk(io_base,0); + set_cclk(io_base,1); + done=get_done_bit(io_base); + printk("done == 0x%x\n",(unsigned int)done); + init=get_init_bit(io_base); + } + if(done>0) + { + //printk("done=1, succeed!\n"); + for(i=0;i<8;i++) + { + set_cclk(io_base,0); + set_cclk(io_base,1); + } + return INFOR_DONE_SUCCEED; + } + else + { + printk("failed!done=%d,init=%d\n",done, init); + return INFOR_DONE_FAILED; + } +} +void shiftWordOut(unsigned short int data, void *io_base) +{ + int i; + //low byte + for(i=0;i<8;i=i+1) { + set_cclk(io_base,0);//set cclk low + set_din(io_base,(data&(0x0080>>i))?1:0); + set_cclk(io_base,1);//set cclk high + } + //high byte + for(i=0;i<8;i=i+1) + { + set_cclk(io_base,0);//set cclk low + set_din(io_base,(data&(0x8000>>i))?1:0); + set_cclk(io_base,1);//set cclk high + } +} +void shiftByteOut(char data, void *io_base) +{ + int i; + for(i=0;i<8;i=i+1) { + set_cclk(io_base,0);//set cclk low + set_din(io_base,(data&(0x80>>i))?1:0); + set_cclk(io_base,1);//set cclk high + } +} + + + diff --git a/study/driver/00-code/android/cpld/slaveSerial.c.bak b/study/driver/00-code/android/cpld/slaveSerial.c.bak new file mode 100644 index 0000000..6e59290 --- /dev/null +++ b/study/driver/00-code/android/cpld/slaveSerial.c.bak @@ -0,0 +1,109 @@ +/* + 2013.1.31byTX +*/ +#include #include +#include "slaveSerial.h" + + +/* +assert cclk when value>1 +*/ +void set_cclk(void *io_base,int value) +{ + iowrite16((value>0)?1:0,io_base+REG_CCLK_OFFSET); +} +/* +assert din when value>0 +*/ +void set_din(void *io_base,int value) +{ + iowrite16((value>0)?1:0,io_base+REG_DIN_OFFSET); +} +/* +assert prog_b when value>0 +*/ +void set_prog_b(void *io_base,int value) +{ + iowrite16((value>0)?1:0,io_base+REG_PROG_B_OFFSET); +} +/* + +*/ +unsigned short int get_stat(void *io_base) +{ + return ioread16(io_base+REG_STAT_OFFSET); +} +//返回pin状态 +int get_done_bit(void *io_base) +{ + return ((get_stat(io_base)& STAT_DONE_BIT)>0)?1:0; +} +//返回pin状态 +int get_init_bit(void *io_base) +{ + return ((get_stat(io_base)& STAT_INIT_BIT)>0)?1:0; +} +int check_done(void *io_base) +{ + int i; + int done=0; + int init=1; + //check init first!! + if(0==get_init_bit(io_base)) + { + printk("init=0,so failed\n"); + return INFOR_DONE_FAILED; + } + while((done==0) && (init==1)) + { + //Apply additional CCLK pulse until DONE=1 + set_cclk(io_base,0); + set_cclk(io_base,1); + done=get_done_bit(io_base); + init=get_init_bit(io_base); + } + if(done>0) + { + //printk("done=1, succeed!\n"); + for(i=0;i<8;i++) + { + set_cclk(io_base,0); + set_cclk(io_base,1); + } + return INFOR_DONE_SUCCEED; + } + else + { + printk("failed!done=%d,init=%d\n",done, init); + return INFOR_DONE_FAILED; + } +} +void shiftWordOut(unsigned short int data, void *io_base) +{ + int i; + //low byte + for(i=0;i<8;i=i+1) { + set_cclk(io_base,0);//set cclk low + set_din(io_base,(data&(0x0080>>i))?1:0); + set_cclk(io_base,1);//set cclk high + } + //high byte + for(i=0;i<8;i=i+1) + { + set_cclk(io_base,0);//set cclk low + set_din(io_base,(data&(0x8000>>i))?1:0); + set_cclk(io_base,1);//set cclk high + } +} +void shiftByteOut(char data, void *io_base) +{ + int i; + for(i=0;i<8;i=i+1) { + set_cclk(io_base,0);//set cclk low + set_din(io_base,(data&(0x80>>i))?1:0); + set_cclk(io_base,1);//set cclk high + } +} + + + diff --git a/study/driver/00-code/android/cpld/slaveSerial.h b/study/driver/00-code/android/cpld/slaveSerial.h new file mode 100644 index 0000000..3645174 --- /dev/null +++ b/study/driver/00-code/android/cpld/slaveSerial.h @@ -0,0 +1,50 @@ +/* +create 2013.1.31byTX + +*/ +#define CPLD_SIZE 256 +#define CPLD_BASE 0x80000000 + +#define REG_TEST_OFFSET 0 + +#define REG_CCLK_OFFSET 0x2 +#define REG_PROG_B_OFFSET 0x4 +#define REG_DIN_OFFSET 0x6 +#define REG_STAT_OFFSET 0x8 +#define STAT_DONE_BIT 0x2 +#define STAT_INIT_BIT 0x1 +#define REG_LED_OFFSET 0xa +#define REG_CONTROL_OFFSET 0xc +#define REG_DATA_OFFSET 0x20 + +#define REG_FPGA_BURST_OFFSET 0x20 +#define FPGA_BURST_SIZE 0x10 //words + +#define INFOR_DONE_SUCCEED 0 +#define INFOR_DONE_FAILED 1 +#define INFOR_INIT_SUCCEED 1 //new,diff as done +#define INFOR_INIT_FAILED 0 //new + +#define DEBUG_PRINT 0 + +#define CMD_START_PROG 0x10 +#define CMD_START_SHIFT 0x11 +#define CMD_CHECK_DONE 0x12 +#define CMD_SET_LED 0x13 +#define CMD_SEND_HIGH_BYTE 0x14 //new +#define CMD_SEND_LOW_BYTE 0x15 //new +#define CMD_CHECK_INIT 0x16 +#define CMD_SET_CONTROL 0x17 +#define CMD_SET_DATA 0x18 +#define SET_LED_ON 0 +#define SET_LED_OFF 1 +void set_cclk(void *io_base,int value); +void set_din(void *io_base,int value); +void set_prog_b(void *io_base,int value); +unsigned short int get_stat(void *io_base); +int get_done_bit(void *io_base); +int get_init_bit(void *io_base); +int check_done(void *io_base); +void shiftWordOut(unsigned short int data, void *io_base); +void shiftByteOut(char data, void *io_base); + diff --git a/study/driver/00-code/android/fpga/Makefile b/study/driver/00-code/android/fpga/Makefile new file mode 100644 index 0000000..2eae2a2 --- /dev/null +++ b/study/driver/00-code/android/fpga/Makefile @@ -0,0 +1,79 @@ +# ------------------------------------------------------------------------------ +# +# Makefile for the LDD-LinuxDeviceDrivers. +# +# Author: gatieme +# Create: 2016-07-29 15:50:46 +# Last modified: 2016-07-29 16:10:29 +# Description: +# This program is loaded as a kernel(v2.6.18 or later) module. +# Use "make install" to load it into kernel. +# Use "make remove" to remove the module out of kernel. +# +# ------------------------------------------------------------------------------ + + +# my driver description +DRIVER_VERSION := "1.0.0" +DRIVER_AUTHOR := "Gatieme @ AderStep Inc..." +DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices" +DRIVER_LICENSE := "Dual BSD/GPL" + + +MODULE_NAME := fpga + +EXTRA_CFLAGS += -g + + +ifneq ($(KERNELRELEASE),) # kernelspace + +obj-m += $(MODULE_NAME).o + +else # userspace + + +CURRENT_PATH ?= $(shell pwd) +ifeq ($(ARCH),arm64) +LINUX_KERNEL_PATH ?= /home/rockchip/rk3399/Android/7.1/android/kernel +else +LINUX_KERNEL ?= $(shell uname -r) +LINUX_KERNEL_PATH ?= /lib/modules/$(LINUX_KERNEL)/build +endif + +CURRENT_PATH := $(shell pwd) + +modules: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules + +modules_install: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules_install + + + +insmod: + sudo insmod $(MODULE_NAME).ko + +reinsmod: + sudo rmmod $(MODULE_NAME) + sudo insmod $(MODULE_NAME).ko + +github: + cd $(ROOT) && make github + +rmmod: + sudo rmmod $(MODULE_NAME) + +test : + sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1 + +clean: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean + rm -f modules.order Module.symvers Module.markers + +.PHNOY: + modules modules_install clean + + + +endif + diff --git a/study/driver/00-code/android/fpga/fpga.c b/study/driver/00-code/android/fpga/fpga.c new file mode 100644 index 0000000..ba1d238 --- /dev/null +++ b/study/driver/00-code/android/fpga/fpga.c @@ -0,0 +1,137 @@ +/* +FPGA test +byTX +2013.1.31:create +*/ +#include +#include +#include +#include +//for file opration +#include +//for cdev create +#include +//copy_to_user +#include +//class_create +#include +//ioremap defined here +#include + + +#include + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Gatieme"); +MODULE_DESCRIPTION("hello world"); + +#define FPGA_SIZE 1024 +#define FPGA_BASE 0x80010000 + +#define CMD_FPGA_MODULE_RST 0x20 +#define REG_RST_OFFSET 0x0006 +static void __iomem *io_base; +struct cdev *fpga_cdev; +struct class *fpga_class; +dev_t fpga_devid; + +static int fpga_open(struct inode *inode, struct file *file) +{ + printk("fpga open\n"); + return 0; +} +ssize_t fpga_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + *(unsigned short int*)buf=ioread16(io_base+(*f_pos)); + return 2; +} +/*fpga write*/ +ssize_t fpga_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + if(count==2) + { + iowrite16(*(unsigned short int*)buf,io_base+(*f_pos)); + return 2; + } + else + return 0; +} + +loff_t fpga_llseek (struct file *filp, loff_t offset, int whence) +{ + loff_t new_pos; + if(offset>=0 && offsetf_pos = new_pos; + return new_pos; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) +static int fpga_ioctl(struct inode *indoe, struct file *file, + unsigned int cmd, unsigned long arg) +{ +#else +//long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); +//long (*compat_ioctl) (struct file *file, unsigned int cmd, unsigned long arg) +static long fpga_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + //struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = inode = file_inode(file); +#endif + switch(cmd) + { + case CMD_FPGA_MODULE_RST: + iowrite16(0, io_base+REG_RST_OFFSET); + iowrite16(1, io_base+REG_RST_OFFSET); + break; + } + return 0; +} + +static struct file_operations fpga_fops = { + .owner = THIS_MODULE, + .open = fpga_open, + .read = fpga_read, + .write = fpga_write, + .llseek = fpga_llseek, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) + .ioctl = fpga_ioctl, +#else + .compat_ioctl = fpga_compat_ioctl, +#endif +}; +static int __init fpga_init(void) +{ + + //创建字符设备 + fpga_cdev=cdev_alloc(); + cdev_init(fpga_cdev, &fpga_fops); + fpga_cdev->owner = THIS_MODULE; + + alloc_chrdev_region(&fpga_devid, 0, 1, "fpga"); + cdev_add(fpga_cdev,fpga_devid,1); + + fpga_class = class_create(THIS_MODULE,"fpga_class"); + device_create(fpga_class, NULL, fpga_devid, NULL,"fpga"); + //申请内存 + io_base=ioremap(FPGA_BASE,FPGA_SIZE); + if(io_base==0) + printk("failed to ioremap fpga\n"); + printk("fpga initialized.\n"); + return 0; +} +static void __exit fpga_exit(void) +{ + unregister_chrdev_region(fpga_devid,1); + device_destroy(fpga_class , fpga_devid); + class_destroy(fpga_class); + cdev_del(fpga_cdev); + iounmap(io_base); + printk("fpga exit\n"); +} + +module_init(fpga_init); +module_exit(fpga_exit); + diff --git a/study/driver/00-code/android/hello/Makefile b/study/driver/00-code/android/hello/Makefile new file mode 100644 index 0000000..084b41a --- /dev/null +++ b/study/driver/00-code/android/hello/Makefile @@ -0,0 +1,82 @@ +# ------------------------------------------------------------------------------ +# +# Makefile for the LDD-LinuxDeviceDrivers. +# +# Author: gatieme +# Create: 2016-07-29 15:50:46 +# Last modified: 2016-07-29 16:10:29 +# Description: +# This program is loaded as a kernel(v2.6.18 or later) module. +# Use "make install" to load it into kernel. +# Use "make remove" to remove the module out of kernel. +# +# ------------------------------------------------------------------------------ + + +ROOT=.. +#PLATFORM=$(shell $(ROOT)/systype.sh) +#include $(ROOT)/Make.defines.$(PLATFORM) + +# my driver description +DRIVER_VERSION := "1.0.0" +DRIVER_AUTHOR := "Gatieme @ AderStep Inc..." +DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices" +DRIVER_LICENSE := "Dual BSD/GPL" + + +MODULE_NAME := hello +#MODCFLAGS:=-O2 -Wall -DMODULE -D__KERNEL__ -DLINUX -std=c99 +#EXTRA_CFLAGS += $(MODULE_FLAGS) $(CFG_INC) $(CFG_INC) +EXTRA_CFLAGS += -g -std=gnu99 + + +ifneq ($(KERNELRELEASE),) # kernelspace + +obj-m := $(MODULE_NAME).o + +else # userspace + +CURRENT_PATH ?= $(shell pwd) +ifeq ($(ARCH),arm64) +LINUX_KERNEL_PATH ?= /home/rockchip/rk3399/Android/7.1/android/kernel +else +LINUX_KERNEL ?= $(shell uname -r) +LINUX_KERNEL_PATH ?= /lib/modules/$(LINUX_KERNEL)/build +endif + + +modules: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules + +modules_install: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules_install + + + +insmod: + sudo insmod $(MODULE_NAME).ko + +reinsmod: + sudo rmmod $(MODULE_NAME) + sudo insmod $(MODULE_NAME).ko + +github: + cd $(ROOT) && make github + +rmmod: + sudo rmmod $(MODULE_NAME) + +test : + sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1 + +clean: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean + rm -f modules.order Module.symvers Module.markers + +.PHNOY: + modules modules_install clean + + + +endif + diff --git a/study/driver/00-code/android/hello/Makefile.m b/study/driver/00-code/android/hello/Makefile.m new file mode 100644 index 0000000..f409b48 --- /dev/null +++ b/study/driver/00-code/android/hello/Makefile.m @@ -0,0 +1,84 @@ +# ------------------------------------------------------------------------------ +# +# Makefile for the LDD-LinuxDeviceDrivers. +# +# Author: gatieme +# Create: 2016-07-29 15:50:46 +# Last modified: 2016-07-29 16:10:29 +# Description: +# This program is loaded as a kernel(v2.6.18 or later) module. +# Use "make install" to load it into kernel. +# Use "make remove" to remove the module out of kernel. +# +# ------------------------------------------------------------------------------ + + +ROOT=.. +#PLATFORM=$(shell $(ROOT)/systype.sh) +#include $(ROOT)/Make.defines.$(PLATFORM) + +# my driver description +DRIVER_VERSION := "1.0.0" +DRIVER_AUTHOR := "Gatieme @ AderStep Inc..." +DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices" +DRIVER_LICENSE := "Dual BSD/GPL" + + + +MODULE_NAME := hello + +ifneq ($(KERNELRELEASE),) + +#CFG_FLAGS += -O2 -I./ +#EXTRA_CFLAGS += $(C_FLAGS) $(CFG_INC) $(CFG_INC) + + + +RESMAIN_CORE_OBJS := hello_dev.o +RESMAIN_GLUE_OBJS := hello_proc.o hello_devfs.o + +hello-objs := $(RESMAIN_GLUE_OBJS) $(RESMAIN_CORE_OBJS) +obj-m := $(MODULE_NAME).o + +else + +#MODULE_NAME := memory-engine +KERNELDIR ?= /lib/modules/$(shell uname -r)/build +#KERNELDIR ?= /home/gatieme/Work/Kernel/ +PWD := $(shell pwd) + +modules: + make -C $(KERNELDIR) M=$(PWD) modules + +modules_install: + make -C $(KERNELDIR) M=$(PWD) modules_install + + + +insmod: + sudo insmod $(MODULE_NAME).ko + +reinsmod: + sudo rmmod $(MODULE_NAME) + sudo insmod $(MODULE_NAME).ko + +github: + cd $(ROOT) && make github + +rmmod: + sudo rmmod $(MODULE_NAME) + +test : + sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1 + +clean: + make -C $(KERNELDIR) M=$(PWD) clean + rm -f modules.order Module.symvers Module.markers + +.PHNOY: + modules modules_install clean + + + +endif + diff --git a/study/driver/00-code/android/hello/hello.c b/study/driver/00-code/android/hello/hello.c new file mode 100644 index 0000000..2d22a1a --- /dev/null +++ b/study/driver/00-code/android/hello/hello.c @@ -0,0 +1,500 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hello.h" + +/*主设备和从设备号变量*/ +static int hello_major = 0; +static int hello_minor = 0; + +/*设备类别和设备变量*/ +static struct class* hello_class = NULL; +static struct hello_android_dev* hello_dev = NULL; + +/*传统的设备文件操作方法*/ +static int hello_open(struct inode* inode, struct file* filp); +static int hello_release(struct inode* inode, struct file* filp); +static ssize_t hello_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos); +static ssize_t hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos); + +/*设备文件操作方法表*/ +static struct file_operations hello_fops = { + .owner = THIS_MODULE, + .open = hello_open, + .release = hello_release, + .read = hello_read, + .write = hello_write +}; + +#ifdef HELLO_DEVFS_BUILD +/*访问设置属性方法*/ +static ssize_t hello_val_show(struct device* dev, struct device_attribute* attr, char* buf); +static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count); + +/*定义设备属性*/ +static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, hello_val_show, hello_val_store); +#endif + + + +/* + 定义传统的设备文件访问方法, + 主要是定义hello_open、hello_release、hello_read和hello_write + 这四个打开、释放、读和写设备文件的方法: +*/ + +/*打开设备方法*/ +static int hello_open(struct inode* inode, struct file* filp) { + struct hello_android_dev* dev; + + /*将自定义设备结构体保存在文件指针的私有数据域中,以便访问设备时拿来用*/ + dev = container_of(inode->i_cdev, struct hello_android_dev, dev); + filp->private_data = dev; + + return 0; +} + +/*设备文件释放时调用,空实现*/ +static int hello_release(struct inode* inode, struct file* filp) { + return 0; +} + +/*读取设备的寄存器val的值*/ +static ssize_t hello_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) { + //ssize_t err = 0; + struct hello_android_dev* dev = filp->private_data; + char temp[81]; + + /*同步访问*/ + if(down_interruptible(&(dev->sem))) { + printk("down_interruptible\n"); + return -ERESTARTSYS; + } + if (*f_pos >= sizeof(dev->val)) + { + printk("f_pos = %lld, count = %ld error\n", *f_pos, count); + up(&(dev->sem)); + return count ? 0 : -ENXIO; + } + + if(count < sizeof(dev->val)) { + printk("count = %ld error\n", count); + up(&(dev->sem)); + return count; + } + + memset(temp, '\0', sizeof(temp)); + sprintf(temp, "%d\n", dev->val); + printk("value = %d, temp = %s\n", dev->val, temp); + + /*将寄存器val的值拷贝到用户提供的缓冲区*/ + if(copy_to_user(buf, temp, sizeof(temp))) { + + up(&(dev->sem)); + printk("copy_to_user error\n"); + return -EFAULT; + + } + count = sizeof(dev->val); + *f_pos += sizeof(dev->val); + + printk("%lld\n", *f_pos); + + up(&(dev->sem)); + return count; +} + +/*写设备的寄存器值val*/ +static ssize_t hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) { + struct hello_android_dev* dev = filp->private_data; + //ssize_t err = 0; + char temp[81]; + + /*同步访问*/ + if(down_interruptible(&(dev->sem))) { + printk("down_interruptible\n"); + return -ERESTARTSYS; + } + + if(*f_pos >= sizeof(dev->val)) + { + printk("twice read\n"); + up(&(dev->sem)); + return count ? -ENXIO : 0; + } + + if(count <= 0) + { + printk("count = %ld\n", count); + up(&(dev->sem)); + return -ERESTARTSYS; + } + + memset(temp, '\0', sizeof(temp)); + if(copy_from_user(temp, buf, count) != 0) + { + up(&(dev->sem)); + return -ERESTARTSYS; + } + + if(sscanf(temp, "%d", &(dev->val)) != 1) + { + up(&(dev->sem)); + return -ERESTARTSYS; + } + + *f_pos += sizeof(dev->val); + printk(KERN_INFO "Rcv value : %d\n", dev->val); + + up(&(dev->sem)); + return count; +} + + +#ifdef HELLO_DEVFS_BUILD +/* + 定义通过devfs文件系统访问方法, + 这里把设备的寄存器val看成是设备的一个属性, + 通过读写这个属性来对设备进行访问, + 主要是实现hello_val_show和hello_val_store两个方法, + 同时定义了两个内部使用的访问val值的方法__hello_get_val和__hello_set_val: +*/ +/*读取寄存器val的值到缓冲区buf中,内部使用*/ +static ssize_t __hello_get_val(struct hello_android_dev* dev, char* buf) { + int val = 0; + + /*同步访问*/ + if(down_interruptible(&(dev->sem))) { + return -ERESTARTSYS; + } + + val = dev->val; + up(&(dev->sem)); + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +/*把缓冲区buf的值写到设备寄存器val中去,内部使用*/ +static ssize_t __hello_set_val(struct hello_android_dev* dev, const char* buf, size_t count) { + int val = 0; + + /*将字符串转换成数字*/ + val = simple_strtol(buf, NULL, 10); + + /*同步访问*/ + if(down_interruptible(&(dev->sem))) { + return -ERESTARTSYS; + } + + dev->val = val; + up(&(dev->sem)); + + return count; +} + +/*读取设备属性val*/ +static ssize_t hello_val_show(struct device* dev, struct device_attribute* attr, char* buf) { + struct hello_android_dev* hdev = (struct hello_android_dev*)dev_get_drvdata(dev); + + return __hello_get_val(hdev, buf); +} + +/*写设备属性val*/ +static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) { + struct hello_android_dev* hdev = (struct hello_android_dev*)dev_get_drvdata(dev); + + return __hello_set_val(hdev, buf, count); +} + +#endif /* #ifdef HELLO_DEVFS_BUILD */ + + + +#ifdef HELLO_PROC_BUILD +/* + 定义通过proc文件系统访问方法, + 主要实现了hello_proc_read和hello_proc_write两个方法, + 同时定义了在proc文件系统创建和删除文件的方法hello_create_proc和hello_remove_proc: +*/ + + +/*把缓冲区的值buff保存到设备寄存器val中去*/ +static ssize_t hello_proc_write(struct file* filp, const char __user *buff, unsigned long len, void* data) { + int err = 0; + char* page = NULL; + + if(len > PAGE_SIZE) { + printk(KERN_ALERT"The buff is too large: %lu.\n", len); + return -EFAULT; + } + + page = (char*)__get_free_page(GFP_KERNEL); + if(!page) { + printk(KERN_ALERT"Failed to alloc page.\n"); + return -ENOMEM; + } + + /*先把用户提供的缓冲区值拷贝到内核缓冲区中去*/ + if(copy_from_user(page, buff, len)) { + printk(KERN_ALERT"Failed to copy buff from user.\n"); + err = -EFAULT; + goto out; + } + + err = __hello_set_val(hello_dev, page, len); + +out: + free_page((unsigned long)page); + return err; +} + +#ifndef PROC_SEQ_FILE_OPERATIONS + +/* 读取设备寄存器val的值,保存在page缓冲区中 */ +static ssize_t hello_proc_read( + char* page, + char** start, + off_t off, + int count, + int* eof, + void* data) { + if(off > 0) { + *eof = 1; + return 0; + } + + return __hello_get_val(hello_dev, page); +} + + +/*创建/proc/hello文件*/ +static void hello_create_proc(void) { + struct proc_dir_entry* entry; + entry = create_proc_entry(HELLO_DEVICE_PROC_NAME, 0, NULL); + if(entry) { + entry->owner = THIS_MODULE; + entry->read_proc = hello_proc_read; + entry->write_proc = hello_proc_write; + } + + entry = proc_create(HELLO_DEVICE_PROC_NAME, 0666, NULL, &proc_hello_fops); + + if(entry == NULL) + { + printk("Can't create " HELLO_DEVICE_PROC_NAME "\n"); + } + + printk("PROC_CREATE "); +} + +#else + +// seq_operations -> show +static int hello_seq_show(struct seq_file *m, void *v) +{ + struct hello_android_dev* dev = hello_dev; + + printk("%d\n", dev->val); + seq_printf(m, "%d\n", dev->val); + + return 0; //!! must be 0, or will show nothing T.T +} + + +// seq_operations -> open +static int hello_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, hello_seq_show, NULL); +} + +const struct file_operations hello_proc_fops = +{ + .owner = THIS_MODULE, + .open = hello_proc_open, + .read = seq_read, + .write = hello_proc_write, + .llseek = seq_lseek, + .release = single_release, +}; + +/*创建/proc/hello文件*/ +static void hello_create_proc(void) { + struct proc_dir_entry* entry; + + entry = proc_create(HELLO_DEVICE_PROC_NAME, 0666, NULL, &hello_proc_fops); + + if(entry == NULL) + { + printk("Can't create " HELLO_DEVICE_PROC_NAME "\n"); + } + + printk("PROC_CREATE "); +} + + +#endif + +/*删除/proc/hello文件*/ +static void hello_remove_proc(void) { + remove_proc_entry(HELLO_DEVICE_PROC_NAME, NULL); +} + + +#endif /* #ifdef HELLO_PROC_BUILD */ + + +/* + 最后,定义模块加载和卸载方法,这里只要是执行设备注册和初始化操作: +*/ + +/*初始化设备*/ +static int __hello_setup_dev(struct hello_android_dev* dev) { + int err; + dev_t devno = MKDEV(hello_major, hello_minor); + + memset(dev, 0, sizeof(struct hello_android_dev)); + + cdev_init(&(dev->dev), &hello_fops); + dev->dev.owner = THIS_MODULE; + dev->dev.ops = &hello_fops; + + /*注册字符设备*/ + err = cdev_add(&(dev->dev),devno, 1); + if(err) { + return err; + } + + /*初始化信号量和寄存器val的值*/ + //init_MUTEX(&(dev->sem)); + sema_init(&(dev->sem), 1); + dev->val = 0; + + return 0; +} + +/*模块加载方法*/ +static int __init hello_init(void){ + int err = -1; + dev_t dev = 0; + struct device* temp = NULL; + + printk(KERN_ALERT"Initializing hello device.\n"); + + /*动态分配主设备和从设备号*/ + err = alloc_chrdev_region(&dev, 0, 1, HELLO_DEVICE_NODE_NAME); + if(err < 0) { + printk(KERN_ALERT"Failed to alloc char dev region.\n"); + goto fail; + } + + hello_major = MAJOR(dev); + hello_minor = MINOR(dev); + + /* 分配hello设备结构体变量 */ + hello_dev = kmalloc(sizeof(struct hello_android_dev), GFP_KERNEL); + if(!hello_dev) { + err = -ENOMEM; + printk(KERN_ALERT"Failed to alloc hello_dev.\n"); + goto unregister; + } + + /*初始化设备*/ + err = __hello_setup_dev(hello_dev); + if(err) { + printk(KERN_ALERT"Failed to setup dev: %d.\n", err); + goto cleanup; + } + +#ifdef HELLO_DEVFS_BUILD + /*在/sys/class/目录下创建设备类别目录hello*/ + hello_class = class_create(THIS_MODULE, HELLO_DEVICE_CLASS_NAME); + if(IS_ERR(hello_class)) { + err = PTR_ERR(hello_class); + printk(KERN_ALERT"Failed to create hello class.\n"); + goto destroy_cdev; + } + + /*在/dev/目录和/sys/class/hello目录下分别创建设备文件hello*/ + temp = device_create(hello_class, NULL, dev, "%s", HELLO_DEVICE_FILE_NAME); + if(IS_ERR(temp)) { + err = PTR_ERR(temp); + printk(KERN_ALERT"Failed to create hello device."); + goto destroy_class; + } + + /*在/sys/class/hello/hello目录下创建属性文件val*/ + err = device_create_file(temp, &dev_attr_val); + if(err < 0) { + printk(KERN_ALERT"Failed to create attribute val."); + goto destroy_device; + } + + dev_set_drvdata(temp, hello_dev); +#endif /* #ifdef HELLO_DEVFS_BUILD */ + +#ifdef HELLO_PROC_BUILD + /*创建/proc/hello文件*/ + hello_create_proc(); +#endif + + printk(KERN_ALERT"Succedded to initialize hello device.\n"); + return 0; + +destroy_device: + device_destroy(hello_class, dev); + +destroy_class: + class_destroy(hello_class); + +destroy_cdev: + cdev_del(&(hello_dev->dev)); + +cleanup: + kfree(hello_dev); + +unregister: + unregister_chrdev_region(MKDEV(hello_major, hello_minor), 1); + +fail: + return err; +} + +/*模块卸载方法*/ +static void __exit hello_exit(void) { + dev_t devno = MKDEV(hello_major, hello_minor); + + printk(KERN_ALERT"Destroy hello device.\n"); +#ifdef HELLO_PROC_BUILD + /*删除/proc/hello文件*/ + hello_remove_proc(); +#endif + +#ifdef HELLO_DEVFS_BUILD + /*销毁设备类别和设备*/ + if(hello_class) { + device_destroy(hello_class, MKDEV(hello_major, hello_minor)); + class_destroy(hello_class); + } +#endif + + /*删除字符设备和释放设备内存*/ + if(hello_dev) { + cdev_del(&(hello_dev->dev)); + kfree(hello_dev); + } + + /*释放设备号*/ + unregister_chrdev_region(devno, 1); +} + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("First Android Driver"); + +module_init(hello_init); +module_exit(hello_exit); diff --git a/study/driver/00-code/android/hello/hello.h b/study/driver/00-code/android/hello/hello.h new file mode 100644 index 0000000..ab53c88 --- /dev/null +++ b/study/driver/00-code/android/hello/hello.h @@ -0,0 +1,33 @@ +#ifndef _HELLO_ANDROID_H_ +#define _HELLO_ANDROID_H_ + +#include +#include + +/* config */ +#define HELLO_DEVFS_BUILD + + +#define HELLO_PROC_BUILD +#define PROC_SEQ_FILE_OPERATIONS + + +#define HELLO_DEVICE_NODE_NAME "hello" +#define HELLO_DEVICE_FILE_NAME "hello" + +#ifdef HELLO_PROC_BUILD + #define HELLO_DEVICE_PROC_NAME "hello" +#endif + +#ifdef HELLO_DEVFS_BUILD + #define HELLO_DEVICE_CLASS_NAME "hello" +#endif + +struct hello_android_dev +{ + int val; + struct semaphore sem; + struct cdev dev; +}; + +#endif diff --git a/study/driver/00-code/android/hello/test b/study/driver/00-code/android/hello/test new file mode 100755 index 0000000..8ee71b6 Binary files /dev/null and b/study/driver/00-code/android/hello/test differ diff --git a/study/driver/00-code/android/hello/test.c b/study/driver/00-code/android/hello/test.c new file mode 100644 index 0000000..bef61fa --- /dev/null +++ b/study/driver/00-code/android/hello/test.c @@ -0,0 +1,27 @@ +#include +#include +#include +#define DEVICE_NAME "/dev/hello" +int main(int argc, char** argv) +{ + int fd = -1; + int val = 0; + fd = open(DEVICE_NAME, O_RDWR); + if(fd == -1) { + printf("Failed to open device %s.\n", DEVICE_NAME); + return -1; + } + + printf("Read original value:\n"); + read(fd, &val, sizeof(val)); + printf("%d.\n\n", val); + val = 5; + printf("Write value %d to %s.\n\n", val, DEVICE_NAME); + write(fd, &val, sizeof(val)); + + printf("Read the value again:\n"); + read(fd, &val, sizeof(val)); + printf("%d.\n\n", val); + close(fd); + return 0; +} \ No newline at end of file diff --git a/study/driver/00-code/android/test/Makefile b/study/driver/00-code/android/test/Makefile new file mode 100644 index 0000000..e4594a2 --- /dev/null +++ b/study/driver/00-code/android/test/Makefile @@ -0,0 +1,82 @@ +# ------------------------------------------------------------------------------ +# +# Makefile for the LDD-LinuxDeviceDrivers. +# +# Author: gatieme +# Create: 2016-07-29 15:50:46 +# Last modified: 2016-07-29 16:10:29 +# Description: +# This program is loaded as a kernel(v2.6.18 or later) module. +# Use "make install" to load it into kernel. +# Use "make remove" to remove the module out of kernel. +# +# ------------------------------------------------------------------------------ + + +ROOT=.. +#PLATFORM=$(shell $(ROOT)/systype.sh) +#include $(ROOT)/Make.defines.$(PLATFORM) + +# my driver description +DRIVER_VERSION := "1.0.0" +DRIVER_AUTHOR := "Gatieme @ AderStep Inc..." +DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices" +DRIVER_LICENSE := "Dual BSD/GPL" + + +MODULE_NAME := test +#MODCFLAGS:=-O2 -Wall -DMODULE -D__KERNEL__ -DLINUX -std=c99 +#EXTRA_CFLAGS += $(MODULE_FLAGS) $(CFG_INC) $(CFG_INC) + + + +ifneq ($(KERNELRELEASE),) # kernelspace + +obj-m := $(MODULE_NAME).o + +else # userspace + +CURRENT_PATH ?= $(shell pwd) +ifeq ($(ARCH),arm64) +LINUX_KERNEL_PATH ?= /home/rockchip/rk3399/Android/7.1/android/kernel +else +LINUX_KERNEL ?= $(shell uname -r) +LINUX_KERNEL_PATH ?= /lib/modules/$(LINUX_KERNEL)/build +endif + + +modules: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules + +modules_install: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules_install + + + +insmod: + sudo insmod $(MODULE_NAME).ko + +reinsmod: + sudo rmmod $(MODULE_NAME) + sudo insmod $(MODULE_NAME).ko + +github: + cd $(ROOT) && make github + +rmmod: + sudo rmmod $(MODULE_NAME) + +test : + sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1 + +clean: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean + rm -f modules.order Module.symvers Module.markers + +.PHNOY: + modules modules_install clean + + + +endif + diff --git a/study/driver/00-code/android/test/test.c b/study/driver/00-code/android/test/test.c new file mode 100644 index 0000000..23df420 --- /dev/null +++ b/study/driver/00-code/android/test/test.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +//#include +//#include +//#include + + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Gatieme"); +MODULE_DESCRIPTION("test world"); + +/* + * print the module information + */ +static void print_module(void) +{ + struct module *mod; + + printk(KERN_ALERT "this module: %p==%p\n", &__this_module, THIS_MODULE); + printk(KERN_ALERT "module state: %d\n", THIS_MODULE->state); + printk(KERN_ALERT "module name: %s\n", THIS_MODULE->name); + + list_for_each_entry(mod, *(&THIS_MODULE->list.prev), list); + printk(KERN_ALERT "module name: %s\n", mod->name); + printk(KERN_ALERT "module state: %d\n", THIS_MODULE->state); +} + + +static int test_init(void) +{ + print_module( ); + + printk(KERN_ALERT "run in cpu %d\n", get_cpu()); + + printk(KERN_ALERT "PAGE_OFFSET : 0x%lx, TASK_SIZE : 0x%lx", PAGE_OFFSET, TASK_SIZE); + + + return 0; +} + + + +static void test_exit(void) +{ + printk(KERN_ERR"exit"); +} + + +module_init(test_init); +module_exit(test_exit); diff --git a/study/driver/00-code/android/test_module/Makefile b/study/driver/00-code/android/test_module/Makefile new file mode 100644 index 0000000..54e49d4 --- /dev/null +++ b/study/driver/00-code/android/test_module/Makefile @@ -0,0 +1,77 @@ +# ------------------------------------------------------------------------------ +# +# Makefile for the LDD-LinuxDeviceDrivers. +# +# Author: gatieme +# Create: 2016-07-29 15:50:46 +# Last modified: 2016-07-29 16:10:29 +# Description: +# This program is loaded as a kernel(v2.6.18 or later) module. +# Use "make install" to load it into kernel. +# Use "make remove" to remove the module out of kernel. +# +# ------------------------------------------------------------------------------ + + +# my driver description +DRIVER_VERSION := "1.0.0" +DRIVER_AUTHOR := "Gatieme @ AderStep Inc..." +DRIVER_DESC := "Linux input module for Elo MultiTouch(MT) devices" +DRIVER_LICENSE := "Dual BSD/GPL" + + +MODULE_NAME := test_module + +EXTRA_CFLAGS += -g -std=gnu99 + + +ifneq ($(KERNELRELEASE),) # kernelspace + +obj-m += $(MODULE_NAME).o + +else # userspace + + +CURRENT_PATH ?= $(shell pwd) +ifeq ($(ARCH),arm64) +LINUX_KERNEL_PATH ?= /home/rockchip/rk3399/Android/7.1/android/kernel +else +LINUX_KERNEL ?= $(shell uname -r) +LINUX_KERNEL_PATH ?= /lib/modules/$(LINUX_KERNEL)/build +endif + +modules: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules + +modules_install: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules_install + + + +insmod: + sudo insmod $(MODULE_NAME).ko + +reinsmod: + sudo rmmod $(MODULE_NAME) + sudo insmod $(MODULE_NAME).ko + +github: + cd $(ROOT) && make github + +rmmod: + sudo rmmod $(MODULE_NAME) + +test : + sudo ../injector/memInjector -l stack -m random -t word_0 --time 1 --timeout 3 -p 1 + +clean: + make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean + rm -f modules.order Module.symvers Module.markers + +.PHNOY: + modules modules_install clean + + + +endif + diff --git a/study/driver/00-code/android/test_module/test_module.c b/study/driver/00-code/android/test_module/test_module.c new file mode 100644 index 0000000..c27b53b --- /dev/null +++ b/study/driver/00-code/android/test_module/test_module.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int g_testmodule_major = 0; + +struct testmodule_dev{ + struct cdev dev; + char buf[100]; +}; + +struct testmodule_dev* testmodule_devp; + +static ssize_t testmodule_read(struct file* filp, char __user* buf, size_t buf_size, loff_t* f_pos){ + struct testmodule_dev* dev = filp->private_data; + + if(copy_to_user(buf,dev->buf, 100)) + { + return -EFAULT; + } + + return 100; +} + +static ssize_t testmodule_write(struct file* filp, const char __user* buf, size_t buf_size, loff_t* f_pos){ + struct testmodule_dev* dev = filp->private_data; + + if(copy_from_user(dev->buf,buf,buf_size)) + { + return -EFAULT; + } + + return buf_size; +} + +static int testmodule_open(struct inode* node, struct file* filp){ + struct testmodule_dev* dev = container_of(node->i_cdev,struct testmodule_dev, dev); + filp->private_data = dev; + return 0; +} + +static long testmodule_ioctl(struct file* filp, unsigned int cmd, unsigned long arg){ + struct testmodule_dev* dev = filp->private_data; + switch(cmd){ + case 0: + memset(dev->buf,0,100); + printk(KERN_INFO "buf set to zero!"); + break; + case 1: + memset(dev->buf,1,100); + printk(KERN_INFO "buf set to 1!"); + break; + default: + break; + } + return 0; +} + +static const struct file_operations testmodule_fops = { + .owner = THIS_MODULE, + .read = testmodule_read, + .write = testmodule_write, + .unlocked_ioctl = testmodule_ioctl, + .open = testmodule_open +}; + +void updateDev(struct testmodule_dev* dev, int index){ + dev_t devno = MKDEV(g_testmodule_major, index); + int error; + cdev_init(&dev->dev, &testmodule_fops); + dev->dev.owner = THIS_MODULE; + error = cdev_add(&dev->dev, devno, 1); + if(error) + printk(KERN_NOTICE "Error %d adding testmodule %d", error, index); +} + +int __init testmodule_init(void){ + dev_t device_no; + /*Get Major Number*/ + alloc_chrdev_region(&device_no,0,1,"testmodule"); + g_testmodule_major = MAJOR(device_no); + + /*Generate device struct*/ + testmodule_devp = kmalloc(sizeof(struct testmodule_dev), GFP_KERNEL); + if(!testmodule_devp){ + /*Generate Failed*/ + int result; + result = -ENOMEM; + unregister_chrdev_region(device_no, 0); + return result; + } + memset(testmodule_devp,0,sizeof(struct testmodule_dev)); + + /*Update device struct*/ + updateDev(testmodule_devp,MINOR(device_no)); + return 0; +} + +void __exit testmodule_exit(void){ + cdev_del(&testmodule_devp->dev); + kfree(testmodule_devp); + unregister_chrdev_region(MKDEV(g_testmodule_major,0),1); +} + +module_init(testmodule_init); +module_exit(testmodule_exit); + +MODULE_LICENSE("Dual BSD/GPL");