Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,4 @@ obj-$(CONFIG_UNISYS_VISORBUS) += visorbus/
obj-$(CONFIG_SIOX) += siox/
obj-$(CONFIG_GNSS) += gnss/
obj-$(CONFIG_SDW) += sdw/
obj-y += test_driver/
19 changes: 19 additions & 0 deletions drivers/test_driver/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
obj-y += test_driver.o

#KERNELDIR ?=/lib/modules/$(shell uname -r)/build
##KERNELDIR ?=$(HOME)/disk2/cht_r2/out/target/product/r2_cht_mrd/obj/kernel/lib/modules/3.14.79-x86_64-gb1e6894/build/
##Documentation/kbuild/kbuild.txt

#module:
#$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules
#rm -rf *.c~
#rm -rf *.mod*
#rm -rf *.o
#rm -rf modules.order
#rm -rf Module.symvers

#clean:
#rm -rf *.ko *.o *.mod* modules* Mo* .*.cmd .tmp_versions
#make -C $(KERNELDIR) M=`pwd` clean

#obj-m=test_driver.o
2 changes: 2 additions & 0 deletions drivers/test_driver/test_app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
test
a.out
11 changes: 11 additions & 0 deletions drivers/test_driver/test_app/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

#CFLAGS += -O2 -msse2
LDFLAGS += -static

all: test
rm test.o

test: test.o

clean:
rm -f test.o test
15 changes: 15 additions & 0 deletions drivers/test_driver/test_app/auto_create_device_file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
在加载驱动程序时自动创建:
Linux内核提供了一组函数,可以在模块加载时自动在/dev目录下创建相对应的设备节点,
并在卸载模块时删除该节点,能实现这样操作的前提是用户空间已经移植了udev(简化版本的mdev)。

相关的函数和结构:
(1)struct class,是一个设备结构体,
注册一个类结构,会在/sys/class目录下创建对应的文件夹,
/dev目录下有自动生成设备节点的信息。

(2)struct class_device结构体。
class_create()
class_device_create()

在成功挂载驱动程序之后,在/sys/class下就产生了一个led文件夹,里面有一个leds文件的包含信息;
并且已经自动在/dev目录下创建好了leds字符设备文件,不用手动创建。
169 changes: 169 additions & 0 deletions drivers/test_driver/test_app/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <string.h>
#include "../test_driver.h"

int read_cpuid(int fd, exx_reg_val_t *reg)
{
int ret = 0;

ioctl(fd, READ_CPUID, (unsigned int *)reg);
printf("%s: eax_ret_val=0x%x, ebx_ret_val=0x%x, ecx_ret_val=0x%x, edx_ret_val=0x%x\n",\
__func__, reg->eax_ret_val, reg->ebx_ret_val, reg->ecx_ret_val, reg->edx_ret_val);
return ret;
}

int read_msr(int fd, unsigned long msr_reg, unsigned long msr_val)
{
int ret = 0;
unsigned long msr_register = msr_reg;

ioctl(fd, GET_MSR_REG_VAL, (unsigned int *)&msr_reg);
if (msr_reg == ~0x0)
ret = -1;
msr_val = msr_reg;
printf("%s: msr_reg=0x%lx msr_val=0x%lx ret=%d\n",\
__func__, msr_register, (unsigned long)msr_reg, ret);
return ret;
}

int write_msr(int fd, unsigned long msr_reg, unsigned long msr_val)
{
int ret = 0;
msr_reg_val_t msr_para;
msr_para.reg = msr_reg;
msr_para.val = msr_val;
msr_para.ret = 0xff;
ioctl(fd, SET_MSR_REG_VAL, (unsigned int *)&msr_para);
printf("%s: msr_reg=0x%lx msr_val=0x%lx ret=%ld\n",\
__func__, msr_reg, msr_para.val, msr_para.ret);
return ret;
}

int main(int argc, const char *argv[])
{
int fd;
int ret;
unsigned long msr_reg = 0x17; //reg:0x17, display cpu model
unsigned long msr_val;
int val = 0;
unsigned long long addr;
unsigned int len;
mem_dump_t *mem_dump = NULL;
char wr_flag = 0;

if (argc < 3) {
fd = open("/dev/hello_class", O_RDWR, 0664);
if (0 > fd) {
printf("%s: test : open : error\n", __func__);
return -1;
}

//read cpuid
exx_reg_val_t reg = {0};
reg.eax_val = 0x7;
reg.ecx_val = 0;
read_cpuid(fd, &reg);

//read_msr
msr_reg = 0x17;
if (argc > 1)
msr_reg = (unsigned long)atoi(argv[1]);
printf("\n%s: msr_reg=0x%lx\n", __func__, msr_reg);
ret = read_msr(fd, msr_reg, msr_val);
if (ret < 0) {
printf("%s: read msr failed, ret=0x%x\n", __func__, ret);
close(fd);
return -1;
}

close(fd);
return 0;
}
else if (argc < 4)
{
sscanf(argv[1], "%llx", &addr);
sscanf(argv[2], "%x", &len);

mem_dump = malloc(sizeof(mem_dump_t) + len * sizeof(unsigned char));
if(!mem_dump) {
printf("mem alloc failed\n");
return 0;
}

memset(mem_dump, 0, sizeof(mem_dump_t) + len * sizeof(unsigned char));

mem_dump->addr = addr;
mem_dump->len = len;

printf("mem_base = 0x%llx\n", mem_dump->addr);
printf("mem_size = 0x%x\n", mem_dump->len);
printf("dump_addr = %p\n", mem_dump->buf);

fd = open("/dev/hello_class", O_RDWR);
if(fd == -1) {
printf("Failed to open device %s\n", "/dev/hello_class");
return -1;
}

ioctl(fd, DUMP_MEM, mem_dump);

for (int i = 0; i < mem_dump->len; i++) {
if((i != 0) && (i % 4 == 0))
printf(" ");
if((i != 0) && (i % 16 == 0))
printf("\n");
printf("%02x", mem_dump->buf[i]);
}

printf("\n");
ioctl(fd, CHECK_FEATURE, &val);
if (val)
printf("X86_FEATURE_RETPOLINE is set\n");
else
printf("X86_FEATURE_RETPOLINE is not set\n");

close(fd);

if(mem_dump)
free(mem_dump);

return 0;

}
else
{
wr_flag = *(char*)argv[2];
sscanf(argv[3], "%lx", &msr_reg);

fd = open("/dev/hello_class", O_RDWR, 0664);
if (0 > fd) {
printf("%s: test : open : error\n", __func__);
return -1;
}
//read_msr
if (wr_flag == 'r')
{
ret = read_msr(fd, msr_reg, msr_val);
if (ret < 0) {
printf("%s: read msr failed, ret=0x%x\n", __func__, ret);
close(fd);
return -1;
}
}
else if(wr_flag == 'w')
{
sscanf(argv[4], "%lx", &msr_val);
ret = write_msr(fd, msr_reg, msr_val);
}

close(fd);
return 0;
}

}
Loading