#include <linux/init.h> #include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/uaccess.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/miscdevice.h> #include <linux/signal.h> #include <linux/timer.h> #include <linux/slab.h> #define printw(fmt, ...) ({printk( KERN_ERR "[ksync] " fmt, ##__VA_ARGS__); 0; }) int major = 123; struct cdev testcdev; struct class *myclass; static struct fasync_struct *async; static unsigned char fsync_buffer[2][2048] = {0}; int hexdump(unsigned char *name, unsigned char *data, unsigned short len) { unsigned char *buf; int i, p, ret; unsigned char tmp[128] = {0}; unsigned int tmp_len = 0; tmp_len = sprintf(tmp, "%s hex(len=%d): ", name, len); if (len > 1024) len = 1024; buf = kmalloc( (len + 1) * 3 + tmp_len, GFP_KERNEL); memset(buf, 0x00, (len + 1) * 3 + tmp_len); memcpy(buf, tmp, tmp_len); if ((NULL == data) || (0 == len)) { printw("%s\n", buf); kfree(buf); return 0; } for (i = 0, p = tmp_len; i < len; i++) { ret = sprintf((buf + p), "%02x ", *(data + i)); p = p + ret; } printw("%s\n", buf); kfree(buf); return 0; } void ksync_send(unsigned short cmd, unsigned char *buffer, short len) { unsigned char string[64] = {0}; sprintf(string, "%s(0x%x, %d)", __func__, cmd, len); memcpy(fsync_buffer[1] + 0, (char *)&cmd, 2); memcpy(fsync_buffer[1] + 2, (char *)&len, 2); memcpy(fsync_buffer[1] + 4, buffer, len); hexdump(string, fsync_buffer[1], len+4); kill_fasync(&async, SIGIO, POLL_IN); } void ksync_recv(unsigned short cmd, unsigned char *buffer, short len) { unsigned char string[64] = {0}; sprintf(string, "%s(0x%x, %d)", __func__, cmd, len); hexdump(string, buffer, len); ksync_send(0x57, buffer, len); } int char_open(struct inode *inode, struct file *filp) { printw("char_open ok...\n"); return 0; } static int char_fasync(int fd, struct file *filp, int mode) { return fasync_helper(fd, filp, mode, &async); } int char_release(struct inode *inode,struct file *filp) { printw("char close\n"); return char_fasync(-1, filp, 0);; } int char_ioctl (struct inode *inode, struct file *filelp, unsigned int cmd, unsigned long args) { return 0; } ssize_t char_write(struct file *filp, const char __user *buffer, size_t count, loff_t *offset) { unsigned short info[2]; printw("%s\n", __func__); if (copy_from_user(fsync_buffer[0], buffer, count)) { return -EFAULT; } hexdump("char_write", buffer, count); memcpy((char *)&info, fsync_buffer[0], 4); ksync_recv( info[0], fsync_buffer[0] + 4, info[1] ); printw("char_write ok...\n"); return count; } ssize_t char_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset) { int ret; ret = copy_to_user( (unsigned char *)buffer, fsync_buffer[1], count); if (0 != ret) { printw("[%s][%d][err]\n", __func__, __LINE__); return -EFAULT; } filp->f_pos += count; hexdump("char_read", fsync_buffer[1], count); printw("char_read ok...\n"); return 0; } struct file_operations fop = { .open = char_open, .release = char_release, .compat_ioctl = char_ioctl, .write = char_write, .read = char_read, .fasync = char_fasync, }; int __init a_init(void) { dev_t dev; int ret; dev = MKDEV(major,0); ret = register_chrdev_region(dev,1,"char"); if(ret) { alloc_chrdev_region(&dev,0,1,"char"); major = MAJOR(dev); } testcdev.owner = THIS_MODULE; cdev_init(&testcdev, &fop); cdev_add(&testcdev, dev, 1); myclass = class_create(THIS_MODULE, "char_class"); device_create(myclass,NULL,dev,NULL, "ksync"); printw("module init ok ...\n"); return 0; } void __exit a_exit(void) { dev_t dev; dev = MKDEV(major ,0); device_destroy(myclass, dev); class_destroy(myclass); cdev_del(&testcdev); unregister_chrdev_region(dev,1); printw("module exit ok....\n"); } module_init(a_init); module_exit(a_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("..."); MODULE_DESCRIPTION("ksync"); MODULE_VERSION("V1.0");
#include <stdio.h> #include <unistd.h> #include <signal.h> #include <fcntl.h> int g_fd; unsigned char fsync_buffer[2][2048] = {0}; int hexdump(unsigned char *name, unsigned char *data, unsigned short len) { unsigned char *buf; int i, p, ret; unsigned char tmp[128] = {0}; unsigned int tmp_len = 0; tmp_len = sprintf(tmp, "%s hex(len=%d): ", name, len); if (len > 1024) len = 1024; buf = malloc( (len + 1) * 3 + tmp_len); memset(buf, 0x00, (len + 1) * 3 + tmp_len); memcpy(buf, tmp, tmp_len); if ((NULL == data) || (0 == len)) { printf("%s\n", buf); free(buf); return 0; } for (i = 0, p = tmp_len; i < len; i++) { ret = sprintf((buf + p), "%02x ", *(data + i)); p = p + ret; } printf("%s\n", buf); free(buf); return 0; } void ksync_recv(unsigned short cmd, unsigned char *buffer, short len) { } void ksync_send(unsigned short cmd, unsigned char *buffer, short len) { unsigned char *s_buf = fsync_buffer[0]; int ret; memcpy(s_buf + 0, (char *)&cmd, 2); memcpy(s_buf + 2, (char *)&len, 2); memcpy(s_buf + 4, buffer, len); hexdump("send kernel", s_buf, len + 4); ret = write(g_fd, s_buf, len + 4); printf("write ret %d\n", ret); } void sig_handler(int sig) { int ret; unsigned short info[2]; unsigned char *r_buf = fsync_buffer[1]; if(sig == SIGIO) { ret = read(g_fd, r_buf, 2048); memcpy((char *)&info[0], r_buf + 0, 2); memcpy((char *)&info[1], r_buf + 2, 2); hexdump("recv kernel", r_buf, info[1]+4); ksync_recv(info[0], r_buf + 4, info[1]); } return; } int main(void) { unsigned char input[1024]; signal(SIGIO, sig_handler); g_fd = open("/dev/ksync", O_RDWR); if(0 == g_fd) { printf("open err\n"); return -1; } printf("open %d\n", g_fd); fcntl(g_fd, F_SETOWN, getpid()); fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL) | FASYNC); while(1) { memset(input, 0x00, 1024); gets(input); fflush(stdin); if(strlen(input) <= 0) continue; ksync_send(0x56, input, strlen(input) ); } return 0; }
# Makefile for PEDD EXTRA_CFLAGS += -Wframe-larger-than=4096 ifneq ($(CROSS_COMPILE),) EXTRA_CFLAGS += -DARC_SDP endif ifeq ($(KERNELRELEASE),) ifeq ($(CROSS_COMPILE),) KERNELDIR ?= /lib/modules/$(shell uname -r)/build else KERNELDIR ?= /workspace/bpcie/output/build/linux-arc-axs101-20141021-3.13 endif PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers *.order *.out .PHONY: modules modules_install clean else obj-m := ksync_drv.o endif