--- In [email protected], "Ernst Mayerhofer"
<[EMAIL PROTECTED]> wrote:
>
> hi,
>
> you can create the node in /etc, instead of /dev, dynamically.
>
>
Hi Ernest,
Your proposal is working perfect! Let me explain the steps I took to
get the device number dynamically allocated...
1. In the file
"devboard-R2_01/os/linux-2.6/arch/cris/arch-v10/drivers/i2c", I did
the following modifications to have the MAJOR number assigned dynamically:
* Added the following #includes:
#include <linux/types.h> /* for dev_t */
#include <linux/cdev.h> /* for struct cdev */
* In the function "static int __init i2c_register( void )":
- Added the following variables:
dev_t devt;
struct cdev *my_i2cdev = NULL;
- Replaced the code
res = register_chrdev( I2C_MAJOR, i2c_name, &i2c_fops );
if ( res < 0 )
{
printk( KERN_ERR "i2c: couldn't get a major number.\n" );
return res;
}
with the code
res = alloc_chrdev_region( &devt, 0, 1, i2c_name );
if ( res < 0 )
{
printk( KERN_INFO "i2cgvc: couldn't get a major number
dynamically allocated.\n" );
return ( res );
}
my_i2cdev = cdev_alloc();
my_i2cdev->ops = &i2c_fops;
my_i2cdev->owner = THIS_MODULE;
/* make device "alive" */
res = cdev_add( my_i2cdev, devt, 1 );
if ( res < 0 )
{
printk( KERN_INFO "i2cgvc: adding cdev failed.\n" );
return ( res );
}
Now, the moment the I2C driver gets initialised, it will obtain a free
MAJOR number from the kernel.
2. Creating the device node:
Since the MAJOR number is now dynamically defined, I can't create the
device node for the i2c driver (/dev/i2c) dynamically gain.
Your proposal made me think about a system to keep the "/dev/i2c" as
"user access point".
After all, opening a device using "open( "/dev/i2c", O_RDWR )" is
still far more better than using "open( "/etc/dev/i2c", O_RDWR )".
One expects devices in the "/dev" directory and not in the "/etc/dev"
directory. Sounds more "intuitive" isn't it?
So, I made the following decision:
- Create the i2c device in "/etc/dev" (so, "/etc/dev/i2c"). This can
be done dynamically, since it's not a read-only section (your input).
- Create a link "/dev/i2c" that points to "/etc/dev/i2c". This can be
done during the FB image build process, by doing the following changes
in "/devboard-R2_01/packages/devices/axis-2.4-R1_0_10/Makefile":
* Remove (or comment out) the following line:
$(MKNOD) -m 0644 $(DEV)/i2c c 123 0
* Add the following line:
$(LN) -sf ../etc/dev/i2c $(DEV)/i2c
This will statically create a link from "/dev/i2c" to the final
location of the real i2c device node "/etc/dev/i2c".
Because of that, we will be able to continue to use "/dev/i2c" in our
code to access the device => reached my goal!
But now, how to get those things working? See the next steps...
3. Creating the node "/etc/dev/i2c".
What I've done, is creating a new subdirectory called "i2cdev_R1" into
the directory "/devboard-R2_01/packages/initscripts". I also added a
link "i2cdev" that is pointing to "i2cdev_R1" (took the other files as
an example).
Into the directory "i2cdev-R1", I added a Makefile and an rc file,
with the following content:
- Makefile:
include $(AXIS_TOP_DIR)/tools/build/Rules.axis
OWN = -o root -g root
install:
$(INSTALL) $(OWN) -m 0755 rc $(prefix)/etc/init.d/i2cdev
$(LN) -sf ../init.d/i2cdev "$(prefix)"/etc/rcS.d/S30i2cdev
- rc file:
#! /bin/sh
. /etc/init.d/functions.sh
begin "Creating i2c dev node"
information "Create dev node for the I2C device, based upon the dyn.
allocated MAJOR number"
information "Make /etc/dev directory..."
mkdir /etc/dev
information "Create device node..."
mknod -m 0644 /etc/dev/i2c c $(awk '$2=="i2cgvc" {print $1}'
/proc/devices) 0
information "Done creating device node..."
end $?
5. Creation of the link "S30i2cdev".
Since I also wanted to have this script running automatically during
boot time, I added a link called "S30i2cdev" into the subdirectory
"/etc/init.d". In fact, this is already done by the Makefile
described in point 3. (see $(LN)....).
Like this, the "for" loop into "/etc/init.d/rc" is also taking the
link "S30i2cdev" into account while booting up.
This will result in running the script "i2cdev", located in
"/etc/init.d" on the RFS.
That's more or less how it works.
I'm still missing 1 link:
I had to manually add the line "packages/initscripts/i2cdev \" into
the main Makefile.
The problem is, when I rerun ./configure, this line will be kicked out
again and my script will not be taken into account any more...
Don't know how to solve this one yet, but I already submitted a
question on this newsgroup for assistance.
Once I have this last item tackled, the circle is round and I have my
new mechanism introduced.
If there are better approaches to do this, I'm certainly open for
suggestions.
But by doing this, I learned a lot about the whole set-up of the
complete system (although not everything is clear yet to me...).
Best rgds,
--Geert