LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 06-05-2007, 09:26 PM   #1
godzilla
LQ Newbie
 
Registered: Jun 2007
Posts: 8

Rep: Reputation: 0
Question uclinux custom device driver not loading, possibly multiple problems


I am pretty new at this, and I have been reading all I can, but I can't seem to put all of the pieces together. Any help is greatly appreciated.

I am trying to write a simple driver called io1, for uClinux, targetting a Coldfire 5282LITE board, and I want it to load on boot. It never has to unload for this app.

The result so far (when loaded onto the board) is that io1 exists in /dev, but it does not exist in /proc/devices or /proc/modules. Also, the open("/dev/io1", O_RDWR) command in the c app that tries to use the driver fails.

This is what I have done:

1. place IO1 folder in linux-2.6.x/drivers/char
IO1 folder contains Makefile,io1.c (source of both shown below)

2. Add option for IO1 to menuconfig
edit linux-2.6.x/drivers/char/Kconfig, add the lines (before config VT):
----
config CONFIG_IO1
bool 'IO1 custom driver' if EMBEDDED
default y
----

3. edit linux-2.6.x/drivers/char/Makefile, add:
----
#ifdef CONFIG_IO1
obj-y += IO1/io1.o
#endif
----

4. tell linux to initialize the driver on boot
----
#ifdef CONFIG_IO1
extern void IO1_init(void);
#endif
----
#ifdef CONFIG_IO1
IO1_init();
#endif
----
at appropriate places
Add above text to drivers/char/mem.c, the init call should go in the chr_device_init() function, the extern at the top

5. edit vendors/Freescale/5282LITE/Makefile, add
----
io1,c,62,0 \
----
under ppp,c,108,0 (note beginning tab and ending slash), there IS one driver after this line (hence the \) note that linux-2.6.x/Documentation/devices.txt specifies major number 62 to be local/experimental use

6. make the image
sudo make menuconfig
verify device driver->char drivers->IO1 custom driver is checked also verify loadable module support:-> enable loadable module support is checked also verify loadable module support:-> enable module unloading is checked sudo make dep sudo make romfs sudo make clean sudo make
_________________

some command traces:

/proc> cat devices
Character devices:
1 mem
2 pty
3 ttyp
4 ttyS
5 /dev/tty
5 /dev/console
10 misc
13 input
90 mtd

Block devices:
1 ramdisk
31 mtdblock

/proc> cat modules

/proc> ls -C /dev
Can console cua0 cua1
io1 ipsec kmem mem
mtd0 mtd1 mtd2 mtdblock0
mtdblock1 mtdblock1 null ppp
ptyp0 ptyp1 ptyp2 ptyp3
ptyp4 ptyp5 ptyp6 ptyp7
ptyp8 ptyp9 ptypa ptypb
ptypc ptypd ptype ptypf
ram0 ram1 ram2 ram3
random rom0 rom1 rom2
rom3 rom4 rom5 rom6
rom7 rom8 rom9 tty
tty0 tty1 tty2 tty3
ttyS0 ttyS1 ttyp0 ttyp1
ttyp2 ttyp3 ttyp4 ttyp5
ttyp6 ttyp7 ttyp8 ttyp9
ttypa ttypb ttypc ttypd
ttype ttypf urandom zero


Notice io1 on the 2nd output line of ls -C /dev
_________________

If I remove the #ifdef and #endif lines from step 4, I get a compile error - reference to undefined function IO_init(). I have no idea why CONFIG_IO1 might not be set, and I have no idea why, even if it was, I would get the reference to undefined function error.
_________________
Makefile (yes, just one line)

obj-m := io1.o

_________________
io.c

#include <linux/slab.h>
#include <linux/module.h>
#include <asm/io.h>
#include <linux/poll.h>
#include <linux/init.h>


#define IO1_MAJOR 62

#define OUTPORT 0x40100010
#define OUTDIR 0x40100024
#define OUTMOD 0x4010005B
//#define OUTMEM *((const volatile unsigned byte *)(0x40020000))


static ssize_t IO1_write(struct file *file, const char *buf, size_t count, loff_t *ppos) {
u8 data;

if (copy_from_user(&data, (u8 *)buf, 1)) return -EFAULT; printk("WRITE Data from user %x hex\n", data); outb(data, OUTPORT); //OUTMEM = data; //writeb(data, OUTPORT); return 1; }

static ssize_t IO1_read(struct file *file, char *buffer, size_t count, loff_t *ppos) {
u8 data;

data = inb(OUTPORT);

printk("data = %x hex\n", data); // for debugging only

// transfer data from kernel address space to user address space

if(copy_to_user( buffer, &data, sizeof(u8))) return -EFAULT;

return 0;
}

static int IO1_open(struct inode * inode, struct file * file) {
printk("io1 Driver open: Usage = %d\n", MOD_IN_USE); MOD_INC_USE_COUNT; return 0; }

static int IO1_release(struct inode * inode, struct file * file) { MOD_DEC_USE_COUNT;
printk("io1 driver release: Usage = %d\n", MOD_IN_USE); return 0; }

struct file_operations IO1_fops = {
owner: THIS_MODULE,
open: IO1_open,
release: IO1_release,
write: IO1_write,
read: IO1_read
};



int __init IO1_init (void)
{
u8 data;
if (register_chrdev(IO1_MAJOR,"io1",&IO1_fops)) {
printk("io1 driver: Failed to get major %d\n", IO1_MAJOR); return -EIO; } printk("Registered device io1: major %d\n",IO1_MAJOR);

data=0x00;
printk("WRITE Port Mode: %x hex\n", data); outb(data, OUTMOD);

data=0x0F;
printk("WRITE Data Direction: %x hex\n", data); outb(data, OUTDIR);

return 0;
}

static void __exit IO1_cleanup (void)
{
printk("Freed resources: MOD_IN_USE = %d\n", MOD_IN_USE); unregister_chrdev(IO1_MAJOR,"My_Driver");
printk("Unregistered device io1: major %d\n",IO1_MAJOR); }


module_init(IO1_init);
module_exit(IO1_cleanup);

MODULE_LICENSE("GPL");

EXPORT_NO_SYMBOLS;

_________________
the code that uses the driver, toggle_pins.c

/*
* File: toggle_pins.c
* Purpose: Toggle some pins to test operation
*
* Notes:
*/

#include <stdio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "alwaysInclude/mcf5282.h"

int toggle_pins(int k)
{
unsigned char data;
int handle;

if (k<5)
data = 0xFF;
else
data = 0x00;

handle = open("/dev/io1", O_RDWR);
if(handle > 0)
printf("io1 opened %d\n", handle);

else
{
printf("Error opening io1\n");
return -1;
}

if(write(handle, &data, 1) < 0)
printf("Error writing io1\n");
else
printf("WRITE SUCCESSFUL\n");

printf("NOTHING HAPPENING\n");

return 1;
}
_________________

I know that's a lot, and I apologize. I am trying to give everything I can to help anyone help me.
Does ANYBODY have ANY thoughts on this? I have been spinning my wheels way too long. Thank you in advance!

Matt
 
Old 06-08-2007, 03:58 PM   #2
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
Are you writing a module or code linked with the kernel/any other module? It's not clear here. And that's the reason of your problems, I think.
 
Old 06-08-2007, 04:42 PM   #3
godzilla
LQ Newbie
 
Registered: Jun 2007
Posts: 8

Original Poster
Rep: Reputation: 0
Hmm... my novice sense tells me that I do not know how to answer this question. I will try to educate myself on this matter and respond when possible. Thank you so far!
 
Old 06-10-2007, 02:16 PM   #4
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
I'll explain it a bit, so it will be easier for you to search. If you add your code to the kernel, you can use all kernel structures and functions. The code exists even if it's not needed, takes RAM and so on.

Module can only use functions and structures that are exported from the kernel. It's more stand-alone and loaded only when needed.
 
Old 06-15-2007, 12:08 PM   #5
godzilla
LQ Newbie
 
Registered: Jun 2007
Posts: 8

Original Poster
Rep: Reputation: 0
kernel/module

I would say, then that for this application, it is best to compile this as part of the kernel. Resources are not an issue, and this driver should be as hidden as possible to any future user (loading/unloading is not desirable). AND that may make it easier to use the kernel functions, as you say.
 
Old 06-16-2007, 05:10 PM   #6
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
Then remove the module-related macros etc. You also need to find a good place to initialize it (the right moment...)
 
Old 07-15-2007, 11:33 AM   #7
godzilla
LQ Newbie
 
Registered: Jun 2007
Posts: 8

Original Poster
Rep: Reputation: 0
macros

I can't seem to find much info on drivers that AREN'T modules, and I can't seem to find what portions are module macros.

I assume these things:
#include <linux/module.h>

module_init(IO1_init);
module_exit(IO1_cleanup);

MODULE_LICENSE("GPL");

Do these things look OK for initializing the driver at the beginning of execution if I remove those macros? I am having trouble figuring out what deleting the above lines will actually do, so I think I am missing something.

----
#ifdef CONFIG_IO1
extern void IO1_init(void);
#endif
----
#ifdef CONFIG_IO1
IO1_init();
#endif
----
at appropriate places
Add above text to drivers/char/mem.c, the init call should go in the chr_device_init() function, the extern at the top
 
Old 07-15-2007, 12:41 PM   #8
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
The difference is mostly in the macros you show: module_init and module_exit. They're wrappers which run your functions and performs some module-related stuff (which you do not need). Remove the include file and the three following lines. Then you have to run IO1_init and IO1_cleanup at appropriate places. Your ifdefs look fine.
 
Old 07-15-2007, 12:54 PM   #9
godzilla
LQ Newbie
 
Registered: Jun 2007
Posts: 8

Original Poster
Rep: Reputation: 0
thank you

Thank you so much, Mara. Your help is greatly appreciated. I apologize for my noob-ness.

I will try what you said and see what I can do to work with it!
 
Old 07-17-2007, 12:07 PM   #10
godzilla
LQ Newbie
 
Registered: Jun 2007
Posts: 8

Original Poster
Rep: Reputation: 0
Still, when I comment out the #ifdefs but leave the functions:

----
//#ifdef CONFIG_IO1
extern int IO1_init(void);
//#endif
----
//#ifdef CONFIG_IO1
i=IO1_init();
//#endif
----

when I make, I get undefined reference to IO1_init. It is not the extern line, but the other one that is causing the error. Note that I did change the extern definition from void to init to match the IO1_init function in the driver, and I placed i= in the second fuctional reference. (i is an int) The error occurs with or without these int changes.
 
Old 07-17-2007, 12:46 PM   #11
godzilla
LQ Newbie
 
Registered: Jun 2007
Posts: 8

Original Poster
Rep: Reputation: 0
Of course, I had to comment out the ifdef lines in the char driver makefile also:

#ifdef CONFIG_IO1
obj-y += IO1/io1.o
#endif

Having done this, I get
"drivers/char/IO1/io1.o: No such file: No such file or directory"
on make.

In drivers/char, I have placed a directory called IO1. In this directory, I have the driver source, io1.c, and the Makefile, which is simply 1 line:

obj-m := io1.o

I must have gotten this from one of the tutorials I was trying to follow because I really don't know what it is doing. As such, I also do not know why io1.o does not exist on Make of the entire kernel/file system.

I will worry about why the ifdef's need commented later. If you could help on this, I would once again be very appreciative.
 
Old 07-19-2007, 03:37 PM   #12
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
You should add to the Makefile in char/ something like
obj-y := IO1/
Also, change that obj-m to obj-y (to make it always included, for the short time).
 
Old 09-10-2007, 06:39 PM   #13
godzilla
LQ Newbie
 
Registered: Jun 2007
Posts: 8

Original Poster
Rep: Reputation: 0
I did try what you said, and I never have gotten this to work. I am going to try a whole different route I think. I do appreciate all of your efforts, though, Mara. Thank you for being so helpful and tolerating a novice!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how to add a device driver into custom redhat 9 install cd zhchang Linux - Hardware 3 03-31-2010 02:57 AM
how to install dynamic device driver in uClinux chandansingh Programming 1 04-26-2005 03:02 PM
loading device driver during install from cd-rom ARCHIGAMER Fedora - Installation 1 04-07-2005 08:40 AM
Double Trouble: Music cd's not loading and video device problems. ObLiViOuS1886 Slackware - Installation 10 05-10-2004 09:51 PM
Problems trying to compile custom ATI binary driver guerilla fighta Linux - Software 0 02-13-2003 04:53 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 09:26 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration