I need to access some proc files in a module on Android kernel.
Basically i need the info shown in cat command, like cat /proc/uptime
. However i need to do it programmatically.
I tried work with proc_fs
functions, but it was just a little fuzzy for me, usually the examples are to create a proc file then read it and that is it. I need to actually use the data from proc files.
I also tred the good fopen
, but it does not seems to work on modules.
How can i do that? i'm really newbie on this. I'm working on goldfish Android kernel.
Thanks.
Procfs is an in-memory file system. It is an interface for the userspace to fetch info and put (config) info into the kernel data structures. In other words, procfs enables userspace to interact and look into the kernel data structures the way they exist during runtime.
Hence, any file inside /proc is not meant to be read from inside a kernel or a kernel module. And why would one want to do that? In a monolithic kernel like Linux, you can access the data structures of one subsystem in the kernel through another directly or through a pre-defined function.
The following function call might help:
struct timespec uptime;
do_posix_clock_monotonic_gettime(&uptime);
You can refer to the /proc/uptime implementation at the link below, it is essentially a seq_file
.
http://lxr.free-electrons.com/source/fs/proc/uptime.c
I'm responding to the original question, how can a kernel module access files in the procfs
.
I found the following to be a useful reference: https://elixir.bootlin.com/linux/latest/source/fs/proc/proc_sysctl.c#L1790
I think it's setting sysctl
values from the kernel command line. The sequence appears to be as follows:
A. Mount the procfs
filesystem
proc_fs_type = get_fs_type("proc");
*proc_mnt = kern_mount(proc_fs_type);
B. Open the file at a path relative to the root of the procfs
file = file_open_root((*proc_mnt)->mnt_root, *proc_mnt, path, O_WRONLY, 0);
C. Read/Write the file
int kernel_read_file(struct file *file, loff_t offset, void **buf, size_t buf_size, size_t *file_size, enum kernel_read_file_id id)
wret = kernel_write(file, val, len, &pos);
D. Close the file
err = filp_close(file, NULL);
D. Cleanup the filesystem mount
kern_unmount(proc_mnt);
put_filesystem(proc_fs_type);
Yes, procfs
mostly provides user space with read/write access to kernel-level data. Since a kernel module runs in the kernel, if a more direct sequence of API calls exist that allow the module to access such data, use of such API would be preferred as it is likely much cleaner, less code, and more efficient.
However, a dynamically-loaded kernel module doesn't have (clean) direct access to all symbols (or data structures) in the kernel.
A kernel module can only access functions and variables that are
defined entirely in a header file that can be included in the kernel-module source
or explicitly exposed to kernel modules through one of the macros in /include/asm-generic/export.h
:
EXPORT_SYMBOL
EXPORT_SYMBOL_GPL
EXPORT_DATA_SYMBOL
EXPORT_DATA_SYMBOL_GPL
Cases where a kernel module needs to access data that is not exposed through such EXPORTED
API but accessible through files in procfs
or any other special filesystem seem like legitimate cases for accessing such files from kernel modules.
As a general design principle, it is my understanding, that the kernel aims to implement mechanisms without forcing a particular policy. Any feature implemented in a way that forces a policy where user-space has access to data, but a kernel module does not is poorly designed.
Kernel module code, by design, run at the same privilege level as the rest of the kernel. There is no fool-proof way to deny a kernel module access to any data that any other part of the kernel can access. Any such attempts can be circumvented with beautifully ugly hacks.
As an extreme example, on x86 machines, the kernel module can use in-line assembly to directly access control registers, walk page tables, and have it's way with any region of memory it so desires. The same goes for interrupt and exception handlers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With