--- 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


Reply via email to