linux字符驱动遇到问题

第一次写博客,不知道写什么,写我遇到的问题吧                                                      --程序员多年,还是那么水的我

背景:参考 https://www.cnblogs.com/acm-icpcer/p/8029656.html 编译内核安装OK后,(我安装的是https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.13.16.tar.gz,注意VMware安装的ubuntu 16.04开始时1G内存,安装新内核后,启动失败,需要将内存改为2G,why?)

然后从网上找了个globalmem的字符模块代码,以及makefile, 经过注释掉一些错误,后编译加载成功,但是printk内容无效,makefile增加 warning info error 都不打印内容,shell命令echo正常打印。


将代码贴在下面。有大神看到,请指教一二,遇到问题找不到路

Makefile

# Makefile

$(error, "here add the debug info")
ifneq ($(KERNELRELEASE),)
# kbuild syntax. dependency relationship of files and target modules are listed here.
    $(warning, $(KERNELRELEASE))
    $(warning, "here add the debug info")
    obj-m := globalmem.o
else
    PWD := $(shell pwd)
    KERNEL_VER ?= $(shell uname -r)
    KERNEL_DIR := /lib/modules/$(KERNEL_VER)/build
    $(error, "here add the debug info")
    $(info, $(PWD))
    $(info, $(KERNEL_VER))
    $(info,  $(KERNEL_DIR))
all:
	@echo "start the compilexxxxxxxxxxxxxxxxxxxxxxx"
	@echo $(KERNEL_DIR)	
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
endif

globalmem.c

/*********************************************************************************
*      Copyright:  (C) 2014 liuchengdeng <[email protected]>
*                  All rights reserved.
*
*       Filename:  globalmem.c
*    Description:  This file
*
*        Version:  0.0.0(08/28/2014~)
*         Author:  liuchengdeng <[email protected]>
*      ChangeLog:  1, Release initial version on "08/28/2014 09:42:22 AM"
*
********************************************************************************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

//#ifndef KERNEL_VERSION
//#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
//#endif

//#ifndef LINUX_VERSION_CODE
//#define LINUX_VERSION_CODE KERNEL_VERSION(4,13,16)
//#endif

#if LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0)
#include 
#else
#include 
#endif
#include 

#define  GLOBALMEM_SIZE 0x1000
#define  MEM_CLEAR         0x1   
#define  GLOBALMEM_MAJOR   150


static int globalmem_major = GLOBALMEM_MAJOR;


struct globalmem_dev {
	struct cdev cdev;
	unsigned char mem[GLOBALMEM_SIZE];
};


struct globalmem_dev *globalmem_devp;


int globalmem_open(struct inode *inode, struct file *filp)
{
	struct globalmem_dev *dev;

	dev = container_of(inode->i_cdev, struct globalmem_dev, cdev);
	filp->private_data = dev;


	return 0;
}


int globalmem_release(struct inode *inode, struct file *filp)
{
	return 0;
}


static long globalmem_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct globalmem_dev *dev = filp->private_data;


	switch (cmd) {
	case MEM_CLEAR:
		memset(dev->mem, 0, GLOBALMEM_SIZE);
		printk(KERN_INFO "globalmem is set to zero\n");
		break;
	default:
		return -EINVAL;
	}
	return 0;
}


static ssize_t globalmem_read(struct file *filp, char  __user *buf, size_t size, loff_t *ppos)
{
	unsigned long p = *ppos;
	unsigned int count = size;
	int ret = 0;
	printk(" globalmem_read\n ");
#if 1
	struct globalmem_dev *dev = filp->private_data;

	if (p >= GLOBALMEM_SIZE)
		return 0;
	if (count>GLOBALMEM_SIZE - p)
		count = GLOBALMEM_SIZE - p;
	

	if (copy_to_user(buf, (void *)(dev->mem + p), count)) {
		ret = -EFAULT;
	}
	else {
		*ppos += count;
		ret = count;
		printk(KERN_INFO "read %u bytes from %lu\n", count, p);
	}
#endif
	return ret;
}


static ssize_t globalmem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
	unsigned long p = *ppos;
	unsigned int count = size;
	int ret = 0;
	printk(" globalmem_write\n ");
#if 1
	struct globalmem_dev *dev = filp->private_data;


	if (p >= GLOBALMEM_SIZE)
		return 0;
	if (count>GLOBALMEM_SIZE - p)
		count = GLOBALMEM_SIZE - p;

	if (copy_from_user(dev->mem + p, buf, count))
		ret = -EFAULT;


	else {
		*ppos += count;
		ret = count;
		printk(KERN_INFO "written %u bytes from %lu\n", count, p);
	}
#endif
	return ret;
}


static loff_t globalmem_llseek(struct file *filp, loff_t offset, int orig)
{
	loff_t ret = 0;
	switch (orig)
	{
	case 0:
		if (offset<0)
		{
			ret = -EINVAL;
			break;
		}
		if ((unsigned int)offset > GLOBALMEM_SIZE)
		{
			ret = -EINVAL;
			break;
		}
		filp->f_pos = (unsigned int)offset;
		ret = filp->f_pos;
		break;
	case 1:
		if ((filp->f_pos + offset)>GLOBALMEM_SIZE)
		{
			ret = -EINVAL;
			break;
		}
		if ((filp->f_pos + offset)<0)
		{
			ret = -EINVAL;
			break;
		}
		filp->f_pos += offset;
		ret = filp->f_pos;
		break;
	default:
		ret = -EINVAL;
		break;
	}
	return ret;
}


static const struct file_operations globalmem_fops = {
	.owner = THIS_MODULE,
	.llseek = globalmem_llseek,
	.read = globalmem_read,
	.write = globalmem_write,
	.unlocked_ioctl=globalmem_ioctl,
	.open = globalmem_open,
	.release = globalmem_release,


};


static void globalmem_setup_cdev(struct globalmem_dev *dev, int index)
{
	int err, devno = MKDEV(globalmem_major, index);


	cdev_init(&dev->cdev, &globalmem_fops);
	dev->cdev.owner = THIS_MODULE;
	err = cdev_add(&dev->cdev, devno, 1);
	if (err)
		printk(KERN_NOTICE "error %d adding globalmem %d", err, index);
}


int globalmem_init(void)
{
	int result;
	dev_t devno = MKDEV(globalmem_major, 0);
	printk(" globalmem say hello !\n");

	if (globalmem_major)
		result = register_chrdev_region(devno, 2, "globalmem");
	else
	{
		result = alloc_chrdev_region(&devno, 0, 2, "globalmem");
		globalmem_major = MAJOR(devno);
	}


	if (result<0)
		return result;


	globalmem_devp = kmalloc(2 * sizeof(struct globalmem_dev), GFP_KERNEL);
	if (!globalmem_devp)
	{
		result = -ENOMEM;
		goto fail_malloc;
	}


	memset(globalmem_devp, 0, 2 * sizeof(struct globalmem_dev));

	globalmem_setup_cdev(&globalmem_devp[0], 0);
	globalmem_setup_cdev(&globalmem_devp[1], 1);


	return 0;


fail_malloc:
	unregister_chrdev_region(devno, 1);
	return result;
}


void globalmem_exit(void)
{
	printk(" globalmem say byebye !\n");
	cdev_del(&globalmem_devp[0].cdev);
	cdev_del(&globalmem_devp[1].cdev);
	kfree(globalmem_devp);
	unregister_chrdev_region(MKDEV(globalmem_major, 0), 2);
}

module_init(globalmem_init);
module_exit(globalmem_exit);
module_param(globalmem_major, int, S_IRUGO);

MODULE_AUTHOR("liu chengdeng <[email protected]>");
MODULE_LICENSE("Dual BSD/GPL");

你可能感兴趣的:(问题记录)