PDA

View Full Version : Loadable Kernel Module (linux)


felix
07-28-2004, 03:38 PM
Hi,

I'm reading a article to basic write of LKM, but i have some doubts, and i tryed help in kernel-newbies but i doesn't have sucess. :(

If someone could help me.. ;)

I'm using kernel 2.4 series.

1 - This code was showed to call syscalls in LKM:

>int uid;mm_segment_t old_fs;
>old_fs = get_fs();
>set_fs(get_ds());
>uid = sys_getuid;
>printk("\nUID %d",uid);
>set_fs(old_fs);

I received this message:
libc-set_fs.o: unresolved symbol sys_getuid

>yes, u would get that error because, you should be
using sys_getuid()
>rather than getuid() , since the kernel doesnt know
>what getuid() is since, it is a userspace function,

So, if i change the sys_getuid() by _NR__getuid is
compile and load but the
output at printk() is completily wrong! Why ? :(


>and after insmod or rather during
>insmod your module is being linked with the kernel
>,libc would internally call sys_getuid() which is transparent to
>the user.

Ok, but in this case (if worked) i will be callin the
getuid. If i will call a syscall
(sys_*) i need use get_fs() and set_fs() ? Why if i'm
already in kernel-space ?

Anyway, doesn't exist a way to access libc functions ?
For example feof(), etc ?

2 - I want to get the name (and path) of program that
is running so i done like that:

printk("PID %d PROG %s",current->pid, current->comm);

The PID is showed correctily, but the PROG is always
empity! :( Why ?

3 - In the article we created a basic device driver
like that:

/*just a dummy for demonstration*/
static int driver_open(struct inode *i, struct file
*f){
printk("<1>Open Function\n");
return 0;
}

/*register every function which will be provided by
our driver*/
static struct file_operations fops = {
NULL, /*lseek*/
NULL, /*read*/
NULL, /*write*/
NULL, /*readdir*/
NULL, /*select*/
NULL, /*ioctl*/
NULL, /*mmap*/
driver_open, /*open, take a look at my dummy
open function*/
NULL, /*release*/
NULL /*fsync...*/
};

int init_module(void){
/*register driver with major 40 and the name driver*/
if(register_chrdev(40, "driver", &fops)) return -EIO;
return 0;
}

void cleanup_module(void){
/*unregister our driver*/
unregister_chrdev(40, "driver");
}

So i created the device with mknod and tryed "open"
with cat, echo, etc, but it never print the "Open
Function" from printk(), why ?

4 - Other intersting thing is that we can re-use
exported symbols, so i tryed to test and import the
vfat_rmdir and do it return 0 to doesn't remove my dir
over fat (only to test, to learn how to work import a
exported symbol), i done like that:

/* Get vfat_rmdir exported function */
extern int *vfat_rmdir_Rc0ad670e;

/* Our faked vfat_mkdir */
int *new_vfat_rmdir(struct inode *dir, struct dentry
*dentry){

return 0;

}

int init_module(void) {

vfat_rmdir_Rc0ad670e=new_vfat_rmdir;
return 0;

}

void cleanup_module(void){

}

And it really can't remove dir under fat with "rm",
but when i type "rm" i receive a dump from kernel, and
i can't access more fat fs! :(

Why ? What i done wrong ?

Thkz a lot and sorry for basic questions.

Regards

i3839
07-28-2004, 04:29 PM
You can't use libc with kernel modules, you should use only kernel functions. sys_* are systemcalls, but you are already in kernel space, so you shouldn't use those, use the internal versions instead. Did you read http://www.xml.com/ldd/chapter/book/index.html?

felix
07-28-2004, 04:46 PM
Hi i3839,

I didn't read yet Linux Device Drivers, i'm reading other tutorial first, and in examples i'm with the doubts above.

ps: I intend to read ldd when i finished it (the i imagine that i will be a better base). :)

Regards.

felix
07-28-2004, 07:51 PM
Hi,

I downloaded ldd book and i couldn't find solution for problems 2 and 4 below! :(

Anyway, i'm downloading LKM Guide Reference to see if it help me...

Regards.

felix
07-30-2004, 01:26 PM
Hi,

I don't know if it's intersting for someone more, but i found a way to solve the problem 2. ;)

The solution is:

1 - Get the PID
2 - Make a juntion of /proc/PID/exe and save in a string
3 - Call readlink and point to this string

So the full-path will be saved into the second argument of readlink. :)

Regards.