mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-11-07 16:01:34 +00:00
Some kernel documentation I have written the past time.
Nothing really special, but here is the simplest place to keep it, especially as others may need it too. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@152 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
1 parent
8b123ff46b
commit
687f8e5fff
3 files changed
+237
No files matched your search
@@ -16,6 +16,7 @@ ask CVS about it:
|
||||
2.1.2 (199801??)
|
||||
Modules lm80.o, w83781d.o: fan-related Segmentation fault corrected
|
||||
Module gl518sm.o: yet more bug fixes. It should at long last be usable now
|
||||
Documentation in doc/kernel: NEW
|
||||
|
||||
2.1.1 (19990107)
|
||||
Module i2c-proc.o: Hack to make /proc/bus/ possible for kernels 2.0.35
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
This file documents the changes in struct file_operations throughout the 2.1
|
||||
kernel series.
|
||||
|
||||
Kernels 2.0.x:
|
||||
|
||||
struct file_operations {
|
||||
int (*lseek) (struct inode *, struct file *, off_t, int);
|
||||
int (*read) (struct inode *, struct file *, char *, int);
|
||||
int (*write) (struct inode *, struct file *, const char *, int);
|
||||
int (*readdir) (struct inode *, struct file *, void *, filldir_t);
|
||||
int (*select) (struct inode *, struct file *, int, select_table *);
|
||||
int (*ioctl) (struct inode *, struct file *, unsigned int,
|
||||
unsigned long);
|
||||
int (*mmap) (struct inode *, struct file *, struct vm_area_struct *);
|
||||
int (*open) (struct inode *, struct file *);
|
||||
void (*release) (struct inode *, struct file *);
|
||||
int (*fsync) (struct inode *, struct file *);
|
||||
int (*fasync) (struct inode *, struct file *, int);
|
||||
int (*check_media_change) (kdev_t dev);
|
||||
int (*revalidate) (kdev_t dev);
|
||||
};
|
||||
|
||||
|
||||
Kernel 2.1.0:
|
||||
|
||||
- int (*lseek) (struct inode *, struct file *, off_t, int);
|
||||
+ long long (*llseek) (struct inode *, struct file *, long long, int);
|
||||
- int (*read) (struct inode *, struct file *, char *, int);
|
||||
+ long (*read) (struct inode *, struct file *, char *, unsigned long);
|
||||
- int (*write) (struct inode *, struct file *, const char *, int);
|
||||
+ long (*write) (struct inode *, struct file *, const char *, unsigned lon
|
||||
|
||||
|
||||
Kernel 2.1.23:
|
||||
|
||||
- int (*select) (struct inode *, struct file *, int, select_table *);
|
||||
+ unsigned int (*poll) (struct file *, poll_table *);
|
||||
[The lock field is added behind the revalidate field]
|
||||
+ int (*lock) (struct inode *, struct file *, int, struct file_lock *);
|
||||
|
||||
|
||||
Kernel 2.1.31:
|
||||
|
||||
- void (*release) (struct inode *, struct file *);
|
||||
+ int (*release) (struct inode *, struct file *);
|
||||
|
||||
|
||||
Kernel 2.1.55:
|
||||
|
||||
- int (*readdir) (struct inode *, struct file *, void *, filldir_t);
|
||||
+ int (*readdir) (struct file *, void *, filldir_t);
|
||||
|
||||
|
||||
Kernel 2.1.56:
|
||||
|
||||
- long long (*llseek) (struct inode *, struct file *, long long, int);
|
||||
+ long long (*llseek) (struct file *, long long, int);
|
||||
- int (*mmap) (struct inode *, struct file *, struct vm_area_struct *);
|
||||
+ int (*mmap) (struct file *, struct vm_area_struct *);
|
||||
- int (*fsync) (struct inode *, struct file *);
|
||||
+ int (*fsync) (struct file *, struct dentry *);
|
||||
- int (*fasync) (struct inode *, struct file *, int);
|
||||
+ int (*fasync) (struct file *, int);
|
||||
- int (*lock) (struct inode *, struct file *, int, struct file_lock *);
|
||||
+ int (*lock) (struct file *, int, struct file_lock *);
|
||||
|
||||
|
||||
Kernel 2.1.70:
|
||||
|
||||
- long long (*llseek) (struct file *, long long, int);
|
||||
+ loff_t (*llseek) (struct file *, loff_t, int);
|
||||
- long (*read) (struct inode *, struct file *, char *, unsigned long);
|
||||
+ ssize_t (*read) (struct file *, char *, size_t, loff_t *);
|
||||
- long (*write) (struct inode *, struct file *, const char *,
|
||||
unsigned long);
|
||||
+ ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
|
||||
|
||||
|
||||
Kernel 2.1.72:
|
||||
|
||||
- unsigned int (*poll) (struct file *, poll_table *);
|
||||
+ unsigned int (*poll) (struct file *, struct poll_table_struct *);
|
||||
|
||||
|
||||
Kernel 2.1.118:
|
||||
|
||||
[The flush field is added behind the open field -- stupid...]
|
||||
+ int (*flush) (struct file *);
|
||||
|
||||
|
||||
Last kernel checked: 2.2.0-pre4.
|
||||
@@ -0,0 +1,145 @@
|
||||
This file documents how to handle the callback function that returns the
|
||||
information displayed in a (non-/proc/sys) /proc file.
|
||||
|
||||
For kernels before 2.1.29, you have to declare a proc_dir_entry, with
|
||||
in the get_info field the procedure handler. For kernels 2.1.29 and later,
|
||||
you can use the create_proc_entry function and assign a new value (the
|
||||
procedure handler address) to the read_proc field:
|
||||
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)
|
||||
static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
|
||||
int unused);
|
||||
static struct proc_dir_entry proc_bus_i2c_dir =
|
||||
{
|
||||
/* low_ino */ 0, /* Set by proc_register_dynamic */
|
||||
/* namelen */ 3, /* The length of the name field */
|
||||
/* name */ "i2c",
|
||||
/* mode */ S_IRUGO | S_IFREG,
|
||||
/* nlink */ 1,
|
||||
/* uid */ 0,
|
||||
/* gid */ 0,
|
||||
/* size */ 0,
|
||||
/* ops */ NULL,
|
||||
/* get_info */ &read_bus_i2c
|
||||
};
|
||||
|
||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)
|
||||
static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
|
||||
int *eof , void *private);
|
||||
#endif
|
||||
|
||||
|
||||
/* This code fragment is part of the initialization code. You should do
|
||||
several safety checks, like whether create_proc_entry does not return
|
||||
NULL. */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)
|
||||
proc_register_dynamic(&proc_root, &proc_bus_i2c_dir);
|
||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)
|
||||
proc_bus_i2c = create_proc_entry("i2c",0,proc_root);
|
||||
proc_bus_i2c->read_proc = &read_bus_i2c;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Now for the function itself.
|
||||
|
||||
LINUX KERNEL 2.0.x, and 2.1.x upto 2.1.28
|
||||
=========================================
|
||||
This function is known as the get_info function.
|
||||
|
||||
int get_info(char *buf, char **start, off_t offset, int len, int unused);
|
||||
|
||||
(INPUT)
|
||||
buf: A kernel-space buffer where we can put the information.
|
||||
len: The buffer length (we have a bit of slack here: if we write
|
||||
'a little' beyond this, things will still work out)
|
||||
(OUTPUT)
|
||||
*buf: The complete contents of the /proc file, starting at the
|
||||
beginning.
|
||||
return value: the number of chars written to buf.
|
||||
|
||||
This is all you have to do if all information fits in the buffer (it is
|
||||
about 3K in length). You can safely ignore offset and start in this case.
|
||||
|
||||
If your /proc entry gets larger, you have to do a bit more work.
|
||||
|
||||
(INPUT)
|
||||
buf: See above
|
||||
len: see above
|
||||
offset: The offset from the beginning of the /proc file where the user
|
||||
wants to start reading
|
||||
(OUTPUT)
|
||||
*buf: A part of the /proc file. The requested information does not
|
||||
have to start at the beginning.
|
||||
start: this is the place within buf where the information starts (ie.
|
||||
you must use offset to compute this!).
|
||||
return value: The number of valid characters written to buf. Begin
|
||||
counting at start, not at buf!
|
||||
|
||||
You do not have to worry about not the whole information being in buf.
|
||||
Another call will be done (with a higher offset value) if more is
|
||||
needed.
|
||||
|
||||
|
||||
LINUX KERNEL 2.1.x, from 2.1.29 upwards
|
||||
=======================================
|
||||
|
||||
This function is known as the read_proc function.
|
||||
|
||||
int read_proc(char *buf, char **start, off_t offset, int len, int *eof,
|
||||
void *private);
|
||||
(INPUT)
|
||||
buf: A kernel-space buffer where we can put the information.
|
||||
len: The buffer length (we have a bit of slack here: if we write
|
||||
'a little' beyond this, things will still work out)
|
||||
(OUTPUT)
|
||||
*buf: The complete contents of the /proc file, starting at the
|
||||
beginning.
|
||||
eof: You can set this to true (anything but 0) to indicate we have
|
||||
reached the end of the file with this read. Not strictly
|
||||
necessary, but it is more efficient (else this function may be
|
||||
called again).
|
||||
return value: The number of valid characters written to buf. Begin
|
||||
counting at start, not at buf!
|
||||
|
||||
If your /proc entry gets larger, you have to do a bit more work.
|
||||
|
||||
(INPUT)
|
||||
buf: See above
|
||||
len: See above
|
||||
offset: The offset from the beginning of the /proc file where the user
|
||||
wants to start reading
|
||||
(OUTPUT)
|
||||
*buf: A part of the /proc file. The requested information does not
|
||||
have to start at the beginning.
|
||||
eof: See above
|
||||
start: this is the place within buf where the information starts (ie.
|
||||
you must use offset to compute this!).
|
||||
return value: The number of valid characters written to buf.
|
||||
|
||||
You do not have to worry about not the whole information being in buf.
|
||||
Another call will be done (with a higher offset value) if more is
|
||||
needed. Ignore private.
|
||||
|
||||
A third way to do this:
|
||||
|
||||
(INPUT)
|
||||
buf: See above
|
||||
len: See above
|
||||
offset: The offset from the beginning of the /proc file where the user
|
||||
wants to start reading
|
||||
(OUTPUT)
|
||||
*buf: A part of the /proc file, with the requested information starting
|
||||
at the beginning.
|
||||
eof: See above
|
||||
start: (long)start is added to the offset pointer after reading. This
|
||||
allows you to play tricks with the file offset, independent of
|
||||
the number of read bytes.
|
||||
return value: the number of chars written to buf.
|
||||
|
||||
|
||||
This document was written by Frodo Looijaard <frodol@dds.nl>. I do not
|
||||
accept any responsibility for omissions or errors, but you are free to
|
||||
drop me a note if something is wrong or if you miss something.
|
||||
Reference in new issue
Block a user