最近我想在s3c2410的数据总线上放一个自己的设备,通过总线来给设备发送数据,我选用2410的nGCS4来用, 于是我看了cs8900a网卡的驱动程序,因为它在我的开发板上占用的是nGCS3的资源,想参考它来些我自己的驱动,然后我写了一个字符设备的驱动,写了一个应用程序,写这个字符设备,原以为能成功,但出现了错误,我的具体做法如下:
1:在smdk.h中定义好了物理地址和虚拟地址的映射
#define pLZJBUS_BASE 0x28000000
#define vLZJBUS_BASE 0xdf000000
2: 写了一个字符设备的驱动如下:
#include
#include
static int bus_value=0; static int io = 0xdf000000; static unsigned long start,len; static void lzjbusinit(void) {
// BWSCON 和 BWSCON4 的设置都是参考网卡设置的
BWSCON = (BWSCON & ~(BWSCON_ST4 | BWSCON_WS4 | BWSCON_DW4)) | (BWSCON_ST4 | BWSCON_WS4 | BWSCON_DW(4,BWSCON_DW_16)); BWSCON &= 0xFFFBFFFF; BANKCON4= BANKCON_Tacs0 | BANKCON_Tcos4 | BANKCON_Tacc14 | BANKCON_Toch1 | BANKCON_Tcah4 | BANKCON_Tacp6 | BANKCON_PMC16; }
static int lzjbus_write(struct file *file, char *buffer, size_t count, loff_t *ppos) { copy_from_user(&bus_value,buffer,sizeof buffer); outw(bus_value,io); } static struct file_operations lzjbus_ops = { owner: THIS_MODULE, write: lzjbus_write, }; static devfs_handle_t devfs_handle;
static int __init bus_init(void) { int ret,status; start = vLZJBUS_BASE; len = 0xf; ret = register_chrdev(BUS_MAJOR,DEVICE_NAME,&lzjbus_ops); if(ret < 0) { printk("device register fail !!\n"); return ret; } status=check_region(start,len); if(status == 0) { printk("succed for io map!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); request_region(start,len,DEVICE_NAME); } else { printk("failed io map !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); return(status); }
lzjbusinit(); devfs_handle = devfs_register(NULL,DEVICE_NAME,DEVFS_FL_DEFAULT,BUS_MAJOR,0,S_IFCHR | S_IRUSR | S_IWUSR,&lzjbus_ops,NULL); return 0; } static void __exit bus_exit(void) { devfs_unregister(devfs_handle); release_region(start,len); unregister_chrdev(BUS_MAJOR,DEVICE_NAME); } module_init(bus_init); module_exit(bus_exit);
3:写了一个应用程序如下:
#include
int main(void) { int buttons_fd; int key_value; key_value = 0xff; buttons_fd = open("/dev/lzjbus",O_WRONLY); if (buttons_fd < 0) { perror("open device buttons"); exit(1); } write(buttons_fd,&key_value,sizeof(key_value));
close(buttons_fd); return 0; }
此时我的设备并没有连在总线的数据线上,我只想看看我通过总线发送数据是否能成功。
驱动加到内核后在 /dev/lzjbus 设备 而且在/proc/ioports 有设备的地址范围
我以为一切都OK了呢,没想到一运行我的应用程序就报错了,我一查是 它 outw(bus_value,io); 这条语句出的错。
错误如下:
Unable to handle kernel paging request at virtual address df000000 pgd = c3cb4000 *pgd = 00000000, *pmd = 00000000 Internal error: Oops: ffffffff CPU: 0 pc : [
所以现在我就不知道该怎么做了,也不知道为什么会出现这个错误。
请大家帮忙看看。给些方法。谢谢!!!!