モジュールからファイル操作

Kenel2.4での話。
モジュールからファイルを正しく操作するには、手順がいる。


http://kerneltrap.org/node/3515
ここにかいてある。
いちおう引用しておく。

This can be fixed by one of two ways:

One, you find a way to allocate userspace memory, copy your string to that allocated userspace memory, and then pass acc_process() the pointer to that userspace memory. This is difficult since you can't readily allocate userspace memory from the kernel (at least it would be _very_ tricky).

The other option is to trick the kernel into thinking the pointer you're passing sys_creat is in fact in userspace and it's okay to operate on it. For this, I will explain a little bit of background:

The kernel uses register segments to define where userspace and kernelspace are split. Commonly, userspace is assigned to any address below 3GB, and kernelspace is assigned to any address above 3GB (up to 4GB, assuming a 32-bit architecture, and more specifically, x86 hardware). There are lots of caveats to what I just said, but you can probably assume what I said is okay in your situation.

The kernel uses the 3GB boundary to determine if an address comes from userspace (0-3GB) or kernelspace (3-4GB), and can generate an EFAULT error when it doesn't like where something is coming from.

If you change the boundary from 3GB to 4GB, so that the kernel's idea of "valid userspace addresses" is now from 0-4GB it won't have an error.

To change the boundary, you have to change the segment register in your processor (I'm assuming x86 architecture here). To do that, you have to temporarily store the original segment, replace it, call your system call (where it will think even kernelspace pointers are okay), and finally set the segment back to its original value.
mm_segment_t fs;

fs = get_fs();     /* save previous value */
set_fs (get_ds()); /* use kernel limit */

/* system calls can be invoked */

set_fs(fs); /* restore before returning to user space */


Kernel2.4のLKMのコンパイルなど分かっている部分は
そのうちまとめる。