* Device node - How does kernel know about it
@ 2007-12-27 1:31 Siva Prasad
2007-12-27 2:55 ` Jon Smirl
2007-12-28 8:39 ` Nicholas Mc Guire
0 siblings, 2 replies; 7+ messages in thread
From: Siva Prasad @ 2007-12-27 1:31 UTC (permalink / raw)
To: linuxppc-dev, linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1971 bytes --]
Hi,
I am really interested in finding out how kernel knows about device
nodes and how the whole thing work. This is as part of my debugging
effort on 8641D based PowerPC board.
* It all started with the problem of "not printing" any thing that comes
from ramdisk (echo and printf statements), while kernel printk's work
perfectly fine.
* Ramdisk is also executing fine, just that prints are not coming out of
serial. I can see the execution of various user programs with a printk
in sys_execve() routine. Ramdisk has all the required files like
/dev/console, /dev/ttyS0, etc.
* Looking further into tty driver, I noticed that call to tty_write() or
do_tty_write() is not happening at all. So, somewhere the interface
between kernel and user program is lost.
* Just to check it out, I tried to write a small kernel module and a
test program.
- Attached memtest.c module (not really testing memory there. :-))
- Attached testmemtest.c user program, that just open's it and reads
the information
- Created a device node using "mknod /dev/memtest c 168 0"
- When I do "insmod memtest.ko" inside the ramdisk bootup scripts, I
could see all the printk's on the console
- When I execute "testmemtest" next in the same script, it does not
display the printk inside of memtest.c module. This only indicates that
read call did not really go to the kernel side.
- Just to check my program's validity, I checked on a similar machine
and all the code works fine.
- "uname -r" also matches with what I built. So, chances of exiting
from open call because of mismatch is remote. Since userland cannot
print, I have no idea what exactly is happening there.
Now going back to the original question...
How does a kernel know about device nodes and how to link with it.
Basically I believe interface between user programs and kernel is lost
at device nodes.
Appreciate any help in continuing my debugging efforts.
Thanks
Siva
[-- Attachment #2: memtest.c --]
[-- Type: application/octet-stream, Size: 4715 bytes --]
/* Appropriate Kernel header files */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/random.h>
#include <asm/io.h>
/* Defaults */
#define DEFAULT_MAJOR 168
#define DEFAULT_NAME "memtest"
/* Parameters that can be set by insmod */
static int major = DEFAULT_MAJOR;
static char* name = DEFAULT_NAME;
#define uint unsigned int
/* Function Prototypes */
ssize_t memtest_read (struct file *, char *, size_t, loff_t *);
ssize_t memtest_write (struct file *, const char *, size_t, loff_t *);
int memtest_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
int memtest_open (struct inode *, struct file *);
int memtest_release (struct inode *, struct file *);
MODULE_AUTHOR("Siva Prasad.");
MODULE_DESCRIPTION("This a a very simple memory test module");
MODULE_LICENSE("GPL");
/*
* This must be made static since it is use after the current
* function returns. It holds the methods used by the driver.
*/
#define NUMMINORS 5
static struct file_operations memtest_fops = {
.read = memtest_read,
.write = memtest_write,
.ioctl = memtest_ioctl,
.open = memtest_open,
.release = memtest_release,
.owner = THIS_MODULE,
};
static dev_t memtestdev;
static struct cdev *memtest_cdev;
#define K(x) ((x) << (PAGE_SHIFT - 10))
#define PAGEFACTOR 32
/*
* my_init_module()
*
* First function called when loaded with insmod. This registers the
* char driver handler.
*
* Returns 0 if successfull, non-zero on failure
*/
int my_init_module(void)
{
unsigned long total_memory, free_memory, page_size;
unsigned long testable_memory, testable_pages;
struct sysinfo meminformation;
int retval;
/* Load character driver */
memtest_cdev = cdev_alloc();
memtestdev = MKDEV(major,0);
retval = register_chrdev_region(memtestdev,NUMMINORS,name);
/* Fail to load if register_chardriver fails */
if (retval < 0)
return retval;
/* If major = 0, it if auto-allocated */
if (!major)
major = retval;
printk(KERN_EMERG "Memtest module registered with major = %d\n",major);
memtest_cdev->ops = &memtest_fops;
memtest_cdev->owner = THIS_MODULE;
retval = cdev_add(memtest_cdev,memtestdev,NUMMINORS);
si_meminfo(&meminformation);
total_memory = K(meminformation.totalram); // in Kbytes
total_memory *= 1024; // Regular bytes
free_memory = K(meminformation.freeram);
free_memory *= 1024;
page_size = PAGE_SIZE * PAGEFACTOR;
printk(KERN_EMERG "System Information...\n");
printk(KERN_EMERG "Total Memory = %uK.\n", (uint)(total_memory/1024));
printk(KERN_EMERG "Free Memory = %uK.\n", (uint)(free_memory/1024));
printk(KERN_EMERG "Test Page Size = %08X.\n", (uint)page_size);
testable_memory = (free_memory/100)*50;
testable_pages = testable_memory / (page_size);
return retval;
}
/*
* my_cleanup_module()
*
* Called when module is removed by insmod.
*/
void my_cleanup_module(void)
{
printk(KERN_EMERG "memtest Cleaning up the module.\n");
cdev_del(memtest_cdev);
/* Unregister character driver. */
unregister_chrdev_region(memtestdev,NUMMINORS);
}
// * Returns number of bytes read
ssize_t memtest_read (struct file *filp, char *buf, size_t nbytes, loff_t* ppos)
{
int tr;
char stringpass[] = "Dude, here is the info from kernel to user";
printk(KERN_EMERG "memtest READ.\n");
tr = 80;
tr = tr - copy_to_user(buf, stringpass, tr);
return tr;
}
// * Returns the number of bytes written
ssize_t memtest_write (struct file *filp, const char *buf, size_t nbytes, loff_t* ppos)
{
printk(KERN_EMERG "memtest WRITE: %d bytes\n",(int)nbytes);
if (!nbytes)
return 0;
return nbytes;
}
// * Returns 0 for success
int memtest_ioctl(struct inode *inode , struct file * filp, unsigned int cmd, unsigned long arg)
{
printk(KERN_EMERG "memtest IOCTL: cmd = %d\n",cmd);
// Just return, as there is nothing to do in open.
return -ENOTTY;
}
// * Returns 0 on success, non-zero on error
int memtest_open (struct inode * inode, struct file * filp)
{
unsigned int minor = MINOR(inode->i_rdev);
printk(KERN_EMERG "memtest OPEN: Major=%d Minor=%d Mode=%08x\n",
MAJOR(inode->i_rdev), MINOR(inode->i_rdev),filp->f_mode);
if (minor >3 )
return -ENXIO;
// Just return, as there is nothing to do in open.
return 0;
}
// * Returns 0 on success, non-zero on error
int memtest_release (struct inode *inode, struct file * filp)
{
printk(KERN_EMERG "memtest RELEASED:\n");
// Just return, as there is nothing to do in release.
return 0;
}
module_init(my_init_module);
module_exit(my_cleanup_module);
[-- Attachment #3: testmemtest.c --]
[-- Type: application/octet-stream, Size: 574 bytes --]
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#define DEVICE "/dev/memtest"
#define BUFFER_SIZE 50
int main(void)
{
int fd, retval, i;
char buffer[BUFFER_SIZE*80];
unsigned long buflength = 0;
fd = open(DEVICE, O_RDONLY);
printf("testmemtest: open returned fd=%d.\n", fd);
if (fd < 0)
{
printf("Could not open the device `%s'.\n", DEVICE);
return -1;
}
retval = read(fd, buffer, BUFFER_SIZE*80);
if (retval < 1)
printf("Error reading information from %s.\n", DEVICE);
for (i=0; i<retval; i++) printf("%c", buffer[i]);
close(fd);
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Device node - How does kernel know about it
2007-12-27 1:31 Device node - How does kernel know about it Siva Prasad
@ 2007-12-27 2:55 ` Jon Smirl
2007-12-28 8:39 ` Nicholas Mc Guire
1 sibling, 0 replies; 7+ messages in thread
From: Jon Smirl @ 2007-12-27 2:55 UTC (permalink / raw)
To: Siva Prasad; +Cc: linuxppc-dev, linuxppc-embedded
On 12/26/07, Siva Prasad <sprasad@bivio.net> wrote:
> Hi,
>
> I am really interested in finding out how kernel knows about device
> nodes and how the whole thing work. This is as part of my debugging
> effort on 8641D based PowerPC board.
>
> * It all started with the problem of "not printing" any thing that comes
> from ramdisk (echo and printf statements), while kernel printk's work
> perfectly fine.
> * Ramdisk is also executing fine, just that prints are not coming out of
> serial. I can see the execution of various user programs with a printk
> in sys_execve() routine. Ramdisk has all the required files like
> /dev/console, /dev/ttyS0, etc.
Does adding console=ttyS0,baud to the kernel boot command line fix it?
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: Device node - How does kernel know about it
2007-12-28 8:39 ` Nicholas Mc Guire
@ 2007-12-28 3:27 ` Siva Prasad
2007-12-28 4:15 ` Jon Smirl
2007-12-30 23:43 ` Brad Boyer
0 siblings, 2 replies; 7+ messages in thread
From: Siva Prasad @ 2007-12-28 3:27 UTC (permalink / raw)
To: Nicholas Mc Guire, Jon Smirl; +Cc: linuxppc-dev, linuxppc-embedded
Thank you Jon and Nicholas.
I already have "console=3DttyS0" in the kernel command line. That is not
helping me.
I looked at the major/minor numbers with a good working system and it
looks correct for the nodes created in ramdisk.
What is the kernel routine that is first called when there is, for
example a read() function call from user program?=20
I would like to start debugging from there and see if any thing at all
happens when there is a call. Appreciate your help with this question.
Thanks
Siva
-----Original Message-----
From: Nicholas Mc Guire [mailto:der.herr@hofr.at]=20
Sent: Friday, December 28, 2007 12:39 AM
To: Siva Prasad
Cc: linuxppc-dev@ozlabs.org; linuxppc-embedded@ozlabs.org
Subject: Re: Device node - How does kernel know about it
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
> * Ramdisk is also executing fine, just that prints are not coming out
of
> serial. I can see the execution of various user programs with a printk
> in sys_execve() routine. Ramdisk has all the required files like
> /dev/console, /dev/ttyS0, etc.
> * Looking further into tty driver, I noticed that call to tty_write()
or
> do_tty_write() is not happening at all. So, somewhere the interface
> between kernel and user program is lost.
> * Just to check it out, I tried to write a small kernel module and a
> test program.
> - Attached memtest.c module (not really testing memory there. :-))
> - Attached testmemtest.c user program, that just open's it and reads
> the information
> - Created a device node using "mknod /dev/memtest c 168 0"
> - When I do "insmod memtest.ko" inside the ramdisk bootup scripts, I
> could see all the printk's on the console
> - When I execute "testmemtest" next in the same script, it does not
> display the printk inside of memtest.c module. This only indicates
that
> read call did not really go to the kernel side.
> - Just to check my program's validity, I checked on a similar machine
> and all the code works fine.
> - "uname -r" also matches with what I built. So, chances of exiting
> from open call because of mismatch is remote. Since userland cannot
> print, I have no idea what exactly is happening there.
>
The kernel will simply look at the major:minor numbers - so maybe you
simply have a wrong major/minor for /dev/ttyS0 ? in that case you will
see nothing but other than that most things will go on working.
hofrat
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFHdLY2nU7rXZKfY2oRApFpAKCKfGanKHGuFFJmUFy3aQtjmWNjEACfU7uK
hrfpn2RMn5l23ZqCOXV5rd8=3D
=3DGfsF
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Device node - How does kernel know about it
2007-12-28 3:27 ` Siva Prasad
@ 2007-12-28 4:15 ` Jon Smirl
2007-12-28 4:55 ` Siva Prasad
2007-12-30 23:43 ` Brad Boyer
1 sibling, 1 reply; 7+ messages in thread
From: Jon Smirl @ 2007-12-28 4:15 UTC (permalink / raw)
To: Siva Prasad; +Cc: linuxppc-dev, Nicholas Mc Guire, linuxppc-embedded
On 12/27/07, Siva Prasad <sprasad@bivio.net> wrote:
> Thank you Jon and Nicholas.
>
> I already have "console=ttyS0" in the kernel command line. That is not
> helping me.
Do you have
CONFIG_EARLY_PRINTK=y
in .config?
>
> I looked at the major/minor numbers with a good working system and it
> looks correct for the nodes created in ramdisk.
>
> What is the kernel routine that is first called when there is, for
> example a read() function call from user program?
> I would like to start debugging from there and see if any thing at all
> happens when there is a call. Appreciate your help with this question.
>
> Thanks
> Siva
>
>
> -----Original Message-----
> From: Nicholas Mc Guire [mailto:der.herr@hofr.at]
> Sent: Friday, December 28, 2007 12:39 AM
> To: Siva Prasad
> Cc: linuxppc-dev@ozlabs.org; linuxppc-embedded@ozlabs.org
> Subject: Re: Device node - How does kernel know about it
>
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> > * Ramdisk is also executing fine, just that prints are not coming out
> of
> > serial. I can see the execution of various user programs with a printk
> > in sys_execve() routine. Ramdisk has all the required files like
> > /dev/console, /dev/ttyS0, etc.
> > * Looking further into tty driver, I noticed that call to tty_write()
> or
> > do_tty_write() is not happening at all. So, somewhere the interface
> > between kernel and user program is lost.
> > * Just to check it out, I tried to write a small kernel module and a
> > test program.
> > - Attached memtest.c module (not really testing memory there. :-))
> > - Attached testmemtest.c user program, that just open's it and reads
> > the information
> > - Created a device node using "mknod /dev/memtest c 168 0"
> > - When I do "insmod memtest.ko" inside the ramdisk bootup scripts, I
> > could see all the printk's on the console
> > - When I execute "testmemtest" next in the same script, it does not
> > display the printk inside of memtest.c module. This only indicates
> that
> > read call did not really go to the kernel side.
> > - Just to check my program's validity, I checked on a similar machine
> > and all the code works fine.
> > - "uname -r" also matches with what I built. So, chances of exiting
> > from open call because of mismatch is remote. Since userland cannot
> > print, I have no idea what exactly is happening there.
> >
> The kernel will simply look at the major:minor numbers - so maybe you
> simply have a wrong major/minor for /dev/ttyS0 ? in that case you will
> see nothing but other than that most things will go on working.
>
> hofrat
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.4 (GNU/Linux)
>
> iD8DBQFHdLY2nU7rXZKfY2oRApFpAKCKfGanKHGuFFJmUFy3aQtjmWNjEACfU7uK
> hrfpn2RMn5l23ZqCOXV5rd8=
> =GfsF
> -----END PGP SIGNATURE-----
>
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: Device node - How does kernel know about it
2007-12-28 4:15 ` Jon Smirl
@ 2007-12-28 4:55 ` Siva Prasad
0 siblings, 0 replies; 7+ messages in thread
From: Siva Prasad @ 2007-12-28 4:55 UTC (permalink / raw)
To: Jon Smirl; +Cc: linuxppc-dev, Nicholas Mc Guire, linuxppc-embedded
Jon,
Yes!... I have CONFIG_EARLY_PRINTK=3Dy, and I could see early prints
during booting the kernel. Afterwards, printk's also work as expected.
Only printf's from user space has problem.
- Siva
-----Original Message-----
From: Jon Smirl [mailto:jonsmirl@gmail.com]=20
Sent: Thursday, December 27, 2007 8:16 PM
To: Siva Prasad
Cc: Nicholas Mc Guire; linuxppc-dev@ozlabs.org;
linuxppc-embedded@ozlabs.org
Subject: Re: Device node - How does kernel know about it
On 12/27/07, Siva Prasad <sprasad@bivio.net> wrote:
> Thank you Jon and Nicholas.
>
> I already have "console=3DttyS0" in the kernel command line. That is =
not
> helping me.
Do you have
CONFIG_EARLY_PRINTK=3Dy
in .config?
>
> I looked at the major/minor numbers with a good working system and it
> looks correct for the nodes created in ramdisk.
>
> What is the kernel routine that is first called when there is, for
> example a read() function call from user program?
> I would like to start debugging from there and see if any thing at all
> happens when there is a call. Appreciate your help with this question.
>
> Thanks
> Siva
>
>
> -----Original Message-----
> From: Nicholas Mc Guire [mailto:der.herr@hofr.at]
> Sent: Friday, December 28, 2007 12:39 AM
> To: Siva Prasad
> Cc: linuxppc-dev@ozlabs.org; linuxppc-embedded@ozlabs.org
> Subject: Re: Device node - How does kernel know about it
>
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> > * Ramdisk is also executing fine, just that prints are not coming
out
> of
> > serial. I can see the execution of various user programs with a
printk
> > in sys_execve() routine. Ramdisk has all the required files like
> > /dev/console, /dev/ttyS0, etc.
> > * Looking further into tty driver, I noticed that call to
tty_write()
> or
> > do_tty_write() is not happening at all. So, somewhere the interface
> > between kernel and user program is lost.
> > * Just to check it out, I tried to write a small kernel module and a
> > test program.
> > - Attached memtest.c module (not really testing memory there. :-))
> > - Attached testmemtest.c user program, that just open's it and
reads
> > the information
> > - Created a device node using "mknod /dev/memtest c 168 0"
> > - When I do "insmod memtest.ko" inside the ramdisk bootup scripts,
I
> > could see all the printk's on the console
> > - When I execute "testmemtest" next in the same script, it does not
> > display the printk inside of memtest.c module. This only indicates
> that
> > read call did not really go to the kernel side.
> > - Just to check my program's validity, I checked on a similar
machine
> > and all the code works fine.
> > - "uname -r" also matches with what I built. So, chances of exiting
> > from open call because of mismatch is remote. Since userland cannot
> > print, I have no idea what exactly is happening there.
> >
> The kernel will simply look at the major:minor numbers - so maybe you
> simply have a wrong major/minor for /dev/ttyS0 ? in that case you will
> see nothing but other than that most things will go on working.
>
> hofrat
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.4 (GNU/Linux)
>
> iD8DBQFHdLY2nU7rXZKfY2oRApFpAKCKfGanKHGuFFJmUFy3aQtjmWNjEACfU7uK
> hrfpn2RMn5l23ZqCOXV5rd8=3D
> =3DGfsF
> -----END PGP SIGNATURE-----
>
--=20
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Device node - How does kernel know about it
2007-12-27 1:31 Device node - How does kernel know about it Siva Prasad
2007-12-27 2:55 ` Jon Smirl
@ 2007-12-28 8:39 ` Nicholas Mc Guire
2007-12-28 3:27 ` Siva Prasad
1 sibling, 1 reply; 7+ messages in thread
From: Nicholas Mc Guire @ 2007-12-28 8:39 UTC (permalink / raw)
To: Siva Prasad; +Cc: linuxppc-dev, linuxppc-embedded
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
> * Ramdisk is also executing fine, just that prints are not coming out of
> serial. I can see the execution of various user programs with a printk
> in sys_execve() routine. Ramdisk has all the required files like
> /dev/console, /dev/ttyS0, etc.
> * Looking further into tty driver, I noticed that call to tty_write() or
> do_tty_write() is not happening at all. So, somewhere the interface
> between kernel and user program is lost.
> * Just to check it out, I tried to write a small kernel module and a
> test program.
> - Attached memtest.c module (not really testing memory there. :-))
> - Attached testmemtest.c user program, that just open's it and reads
> the information
> - Created a device node using "mknod /dev/memtest c 168 0"
> - When I do "insmod memtest.ko" inside the ramdisk bootup scripts, I
> could see all the printk's on the console
> - When I execute "testmemtest" next in the same script, it does not
> display the printk inside of memtest.c module. This only indicates that
> read call did not really go to the kernel side.
> - Just to check my program's validity, I checked on a similar machine
> and all the code works fine.
> - "uname -r" also matches with what I built. So, chances of exiting
> from open call because of mismatch is remote. Since userland cannot
> print, I have no idea what exactly is happening there.
>
The kernel will simply look at the major:minor numbers - so maybe you
simply have a wrong major/minor for /dev/ttyS0 ? in that case you will
see nothing but other than that most things will go on working.
hofrat
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFHdLY2nU7rXZKfY2oRApFpAKCKfGanKHGuFFJmUFy3aQtjmWNjEACfU7uK
hrfpn2RMn5l23ZqCOXV5rd8=
=GfsF
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Device node - How does kernel know about it
2007-12-28 3:27 ` Siva Prasad
2007-12-28 4:15 ` Jon Smirl
@ 2007-12-30 23:43 ` Brad Boyer
1 sibling, 0 replies; 7+ messages in thread
From: Brad Boyer @ 2007-12-30 23:43 UTC (permalink / raw)
To: Siva Prasad; +Cc: linuxppc-dev, Nicholas Mc Guire, linuxppc-embedded
On Thu, Dec 27, 2007 at 07:27:17PM -0800, Siva Prasad wrote:
> What is the kernel routine that is first called when there is, for
> example a read() function call from user program?
> I would like to start debugging from there and see if any thing at all
> happens when there is a call. Appreciate your help with this question.
I don't generally recommend starting debugging at that level, but I'll
try to give you some pointers. Every system call coming into the kernel
from a user space program initially runs a little piece of assembly
language code that looks up a handler (by number) in the system call
table and sets up the proper environment to call the appropriate function
that implements that call (which is written in C). Normally, those
functions are named with a prefix of sys_ and the name of the system
call. For example, the implementation of read(2) is called sys_read. You
should be able to find it in fs/read_write.c. Other system call
implementations are scattered around to be with code related to that
call. Most of the file related ones can be found someplace under the
fs directory.
Brad Boyer
flar@allandria.com
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2007-12-30 23:43 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-27 1:31 Device node - How does kernel know about it Siva Prasad
2007-12-27 2:55 ` Jon Smirl
2007-12-28 8:39 ` Nicholas Mc Guire
2007-12-28 3:27 ` Siva Prasad
2007-12-28 4:15 ` Jon Smirl
2007-12-28 4:55 ` Siva Prasad
2007-12-30 23:43 ` Brad Boyer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).