当前位置: 技术问答>linux和unix
请求支援:LINUX 2.6内核里添加新的LED模块失败
来源: 互联网 发布时间:2016-09-28
本文导语: 公司里有一个好的现成的项目。不过我想练兵。所以就在这个现成的LINUX 2.6内核上面添加一个LED模块。在MAKE MENUCONFIG里添加了LED模块后。LINUX内核就不能正常启动了。报错如下。如果把这个LED模块在MAKE MENUCONFIG里不...
公司里有一个好的现成的项目。不过我想练兵。所以就在这个现成的LINUX 2.6内核上面添加一个LED模块。在MAKE MENUCONFIG里添加了LED模块后。LINUX内核就不能正常启动了。报错如下。如果把这个LED模块在MAKE MENUCONFIG里不选择,启动就正常了。
我的LED代码
哪位兄弟帮我看一下。耽误很久了。万分感谢。
yaffs Sep 9 2010 11:17:10 Installing.
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
JZSOC: LCDC BTDEV Init mode.
BTDEV block: dev_id: 0x0, size: 0x340.
BTDEV FB: Phys: 0x3fbf000, Virt: 0xa3fbf000, Size: 0x41000.
fb0: jz-lcd frame buffer device, using 260K of video memory
+++ ipu request irq is ok +++
JzSOC onchip RTC installed !!!
JzSOC: char device family.
JZ4740 SAR-ADC driver registered
CPU 0 Unable to handle kernel paging request at virtual address 0000002c, epc == 800a775c, ra == 800a7750
Oops[#1]:
Cpu 0
$ 0 : 00000000 10000400 80300dd4 00000028
$ 4 : 00000038 00000000 8015fc18 0000001a
$ 8 : 00000000 8015fc18 00000ce8 80340000
$12 : 80340000 80340000 00000000 8033be20
$16 : 00000000 80306e14 80300000 80300000
$20 : fffffffe 00000000 00000000 00000000
$24 : 00000008 8033be40
$28 : 810a8000 810a9f08 802c0000 800a7750
Hi : ffffff8c
Lo : 747474e8
epc : 800a775c cdev_init+0x30/0x5c Not tainted
ra : 800a7750 cdev_init+0x24/0x5c
Status: 10000403 KERNEL EXL IE
Cause : 0080000c
BadVA : 0000002c
PrId : 2ed0024f (Ingenic JZRISC)
Modules linked in:
Process swapper (pid: 1, threadinfo=810a8000, task=810a7958)
Stack : 00000000 00000000 80340000 00000000 000000e8 83e04e00 8018c6c4 8018c674
810a9f3c 00000000 80329148 80329128 0e800000 00000002 00000000 00000000
80334080 00000000 8030f708 8030f708 00000000 8030f644 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
...
Call Trace:
[] cdev_init+0x30/0x5c
[] light_init+0xa0/0x148
[] kernel_init+0xc4/0x330
[] kernel_thread_helper+0x10/0x18
Code: 3c028030 26030028 24420dd4 ae030028 ae020018 0c0561cb 02002021 ae110024
Kernel panic - not syncing: Attempted to kill init!
我的LED代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#define LIGHT_ON 0
#define LIGHT_OFF 1
#define LIGHT_MAJOR 251
static int light_major = LIGHT_MAJOR;
/*设备结构体*/
struct light_dev
{
struct cdev *cdev; /*字符设备cdev结构体*/
unsigned char value; /*LED亮时为1,熄灭时为0,用户可读写此值*/
};
struct light_dev *light_devp;
MODULE_AUTHOR("Song Baohua");
MODULE_LICENSE("Dual BSD/GPL");
void light_on(void)
{
__gpio_set_pin(GPIO_LED_PIN);
}
void light_off(void)
{
__gpio_clear_pin(GPIO_LED_PIN);
}
#if 0
int light_init(void)
{
__gpio_as_output(GPIO_LED_PIN);
}
#endif
/*打开和关闭函数*/
int light_open(struct inode *inode, struct file *filp)
{
struct light_dev *dev;
/* 获得设备结构体指针 */
dev = container_of(inode->i_cdev, struct light_dev, cdev);
/* 让设备结构体作为设备的私有信息 */
filp->private_data = dev;
return 0;
}
int light_release(struct inode *inode, struct file *filp)
{
return 0;
}
/*写设备:可以不需要 */
ssize_t light_read(struct file *filp, char *buf, size_t count,loff_t*f_pos)
{
struct light_dev *dev = filp->private_data; /*获得设备结构体 */
if (copy_to_user(buf, &(dev->value), 1))
{
return - EFAULT;
}
return 1;
}
ssize_t light_write(struct file *filp, const char *buf, size_t count,
loff_t *f_pos)
{
struct light_dev *dev = filp->private_data;
if (copy_from_user(&(dev->value), buf, 1))
{
return - EFAULT;
}
/*根据写入的值点亮和熄灭LED*/
if (dev->value == 1)
light_on();
else
light_off();
return 1;
}
/* ioctl函数 */
int light_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct light_dev *dev = filp->private_data;
switch (cmd)
{
case LIGHT_ON:
dev->value = 1;
light_on();
break;
case LIGHT_OFF:
dev->value = 0;
light_off();
break;
default:
/* 不能支持的命令 */
return - ENOTTY;
}
return 0;
}
struct file_operations light_fops =
{
.owner = THIS_MODULE,
.read = light_read,
.write = light_write,
.ioctl = light_ioctl,
.open = light_open,
.release = light_release,
};
/*设置字符设备cdev结构体*/
static void light_setup_cdev(struct light_dev *dev, int index)
{
int err, devno = MKDEV(light_major, index);
cdev_init(dev->cdev, &light_fops);
dev->cdev->owner = THIS_MODULE;
dev->cdev->ops = &light_fops;
err = cdev_add(dev->cdev, devno, 1);
if (err)
printk(KERN_NOTICE "Error %d adding LED%d", err, index);
}
/*模块加载函数*/
int light_init(void)
{
int result;
dev_t dev = MKDEV(light_major, 0);
/* 申请字符设备号*/
if (light_major)
result = register_chrdev_region(dev, 1, "LED");
else
{
result = alloc_chrdev_region(&dev, 0, 1, "LED");
light_major = MAJOR(dev);
}
if (result cdev); /*删除字符设备结构体*/
kfree(light_devp); /*释放在light_init中分配的内存*/
unregister_chrdev_region(MKDEV(light_major, 0), 1); /*删除字符设备*/
}
module_init(light_init);
module_exit(light_cleanup);
哪位兄弟帮我看一下。耽误很久了。万分感谢。
|
我知道了
struct light_dev
{
struct cdev *cdev; /*字符设备cdev结构体*/
unsigned char value; /*LED亮时为1,熄灭时为0,用户可读写此值*/
};
你没给他空间啊
struct light_dev
{
struct cdev *cdev; /*字符设备cdev结构体*/
unsigned char value; /*LED亮时为1,熄灭时为0,用户可读写此值*/
};
你没给他空间啊
|
那么你可以在light_init中加入调试语句,跟踪一下,看哪里造成的崩溃。
|
这个刚好满足你的要求,不需要手动加载。
[code=C/C
#include
#include
#include
#include
#include
#include
#include
#include
#include
void *R_GPBCON;
void *R_GPBDAT;
static u32 resave_gpbcon;
static u32 resave_gpbdat;
static struct input_dev my_led_dev;
static void iomap_gpb(void)
{
R_GPBCON = ioremap(0x56000010,0x4);
R_GPBDAT = ioremap(0x56000014,0x4);
}
static void unmap_gpb(void)
{
iounmap(R_GPBCON);
iounmap(R_GPBDAT);
}
static void init_led_reg(void)
{
u32 temp;
resave_gpbcon = __raw_readl(R_GPBCON);
resave_gpbdat = __raw_readl(R_GPBDAT);
temp = resave_gpbcon & (~(0xff
[code=C/C
#include
#include
#include
#include
#include
#include
#include
#include
#include
void *R_GPBCON;
void *R_GPBDAT;
static u32 resave_gpbcon;
static u32 resave_gpbdat;
static struct input_dev my_led_dev;
static void iomap_gpb(void)
{
R_GPBCON = ioremap(0x56000010,0x4);
R_GPBDAT = ioremap(0x56000014,0x4);
}
static void unmap_gpb(void)
{
iounmap(R_GPBCON);
iounmap(R_GPBDAT);
}
static void init_led_reg(void)
{
u32 temp;
resave_gpbcon = __raw_readl(R_GPBCON);
resave_gpbdat = __raw_readl(R_GPBDAT);
temp = resave_gpbcon & (~(0xff