Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

uClinux in Nios II with MMU - Device Driver Kernel Panic

Hi,

I'm developing a uClinux MMU kernel over a Nios II FPGA system and I'm having a lot of problemes when trying to run a custom device driver.

I've managed to run a "Hello world" driver, but now I'm trying to run a "PIO port" driver with an Init function like:

static int __init Init_LEDS(void){
	if (!(request_mem_region((unsigned long)PIO_0_BASE, PIO_0_SPAN, "Leds")))
		return -1;
	if(register_chrdev( MAJOR_LED, MODULE_NAME, &Fops_Leds )){
		printk("Error!!!!");	
		return -EIO;	
	}
	printk("%s OK\n",MODULE_NAME);	
	
	Data = 1;
	outb(Data,Pos_Leds_Mem);
			
	return 0;
}

This code prints the "printk" message but then it returns the following error in "outb":

CPU 0 Unable to handle kernel paging request at virtual address 08001000, epc == c22210e0, ra == c22210d4
Kernel panic - not syncing: Oops

I think it is probably due to the fact that I'm using a MMU system instead of a MMU-less one, but I've read other device drivers included in the uClinux MMU package and they also use the "outb" or "outl" function.

Does anybody know how could I fix this problem, please? Or has anybody managed to create a character device driver for the MMU uClinux kernel?

Thank you very much in advance.

See you!

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    Maybe Pos_Leds_Mem = 0x08001000. If this is the address of your LEDs, next code may help you, but I will not guarantee it.

    
        outb(Data, ((unsigned long)Pos_Leds_Mem) | 0xe0000000);
    
    If you want to make some driver for genuine Linux, I strongly recommend you to study the functionality of MMU and the meaning of virtual addresses.

    Kazu
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    Thank you very much for your reply! Yesterday I managed to fix the problem and, as you say, it was due to the virtual addresses mapping. The "outb" function is correct, but before this it is compulsory to make a "ioremap" call to remap the real address into virtual one (I found the "hrtimer.c" example in the Nios Wiki where something similar was used). Then, as any other device driver, "copy_to_user()" and "copy_from_user()" are needed to pass information between kernel and user space.

    Now, I am trying to make the device driver to read and write words instead of bytes and to use interrupts, because of my hardware requirements. I hope this to be easier hehehe

    By the way, I am having problems when trying to load the module with "modprobe"/"insmod". It works fine if I add it to the kernel, but when I make a "modprobe" the CPU stops running. I checked the apps config and everything is fine. I will keep on working on that!!

    See you!