Sfoglia il codice sorgente

Add description of sysfs attribute

The description of the attribute was added in sysfs section and referenced in vinput section.

In vinput section, just described the class_attribute and some macros about sysfs class.

Add file name at vinput-related examples begin.
asas1asas200 3 anni fa
parent
commit
04465b1a44
4 ha cambiato i file con 69 aggiunte e 1 eliminazioni
  1. 4 0
      examples/vinput.c
  2. 4 0
      examples/vinput.h
  3. 4 0
      examples/vkbd.c
  4. 57 1
      lkmpg.tex

+ 4 - 0
examples/vinput.c

@@ -1,3 +1,7 @@
+/*
+ * vinput.c
+ */
+
 #include <linux/cdev.h>
 #include <linux/input.h>
 #include <linux/module.h>

+ 4 - 0
examples/vinput.h

@@ -1,3 +1,7 @@
+/*
+ * vinput.h
+ */
+
 #ifndef VINPUT_H
 #define VINPUT_H
 

+ 4 - 0
examples/vkbd.c

@@ -1,3 +1,7 @@
+/*
+ * vkbd.c
+ */
+
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/module.h>

+ 57 - 1
lkmpg.tex

@@ -1257,6 +1257,40 @@ You can find sysfs directories and files under the \verb|/sys| directory on your
 ls -l /sys
 \end{codebash}
 
+Attributes can be exported for kobjects in the form of regular files in the filesystem.
+Sysfs forwards file I/O operations to methods defined for the attributes, providing a means to read and write kernel attributes.
+
+An attribute definition in simply:
+
+\begin{code}
+struct attribute {
+    char *name;
+    struct module *owner;
+    umode_t mode;
+};
+
+int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
+void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);
+\end{code}
+
+For example, the driver model defines \cpp|struct device_attribute| like:
+
+\begin{code}
+struct device_attribute {
+    struct attribute attr;
+    ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+                    char *buf);
+    ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+                    const char *buf, size_t count);
+};
+
+int device_create_file(struct device *, const struct device_attribute *);
+void device_remove_file(struct device *, const struct device_attribute *);
+\end{code}
+
+To read or write attributes, \cpp|show()| or \cpp|store()| method must be specified when declaring the attribute.
+For the common cases \src{include/linux/sysfs.h} provides convenience macros (\cpp|__ATTR|, \cpp|__ATTR_RO|, \cpp|__ATTR_WO|, etc.) to make defining attributes easier as well as making code more concise and readable.
+
 An example of a hello world module which includes the creation of a variable accessible via sysfs is given below.
 
 \samplec{examples/hello-sysfs.c}
@@ -1293,6 +1327,12 @@ Finally, remove the test module:
 sudo rmmod hello_sysfs
 \end{codebash}
 
+In the above case, we use a simple kobject to create a directory under sysfs, and communicate with its attributes.
+Since Linux v2.6.0, the \cpp|kobject| structure made its appearance.
+It was initially meant as a simple way of unifying kernel code which manages reference counted objects.
+After a bit of mission creep, it is now the glue that holds much of the device model and its sysfs interface together.
+For more information about kobject and sysfs, see \src{Documentation/driver-api/driver-model/driver.rst} and \url{https://lwn.net/Articles/51437/}.
+
 \section{Talking To Device Files}
 \label{sec:device_files}
 Device files are supposed to represent physical devices.
@@ -1897,6 +1937,23 @@ The buffer will then be copied to user.
 vinput devices are created and destroyed using sysfs.
 And, event injection is done through a \verb|/dev| node.
 The device name will be used by the userland to export a new virtual input device.
+
+The \cpp|class_attribute| structure is similar to other attribute types we talked about in section \ref{sec:sysfs}:
+
+\begin{code}
+struct class_attribute {
+    struct attribute attr;
+    ssize_t (*show)(struct class *class, struct class_attribute *attr,
+                    char *buf);
+    ssize_t (*store)(struct class *class, struct class_attribute *attr,
+                    const char *buf, size_t count);
+};
+\end{code}
+
+In \verb|vinput.c|, the macro \cpp|CLASS_ATTR_WO(export/unexport)| defined in \src{include/linux/device.h} (in this case, \verb|device.h| is included in \src{include/linux/input.h}) will generate the \cpp|class_attribute| structures which are named \verb|class_attr_export/unexport|.
+Then, put them into \cpp|vinput_class_attrs| array and the macro \cpp|ATTRIBUTE_GROUPS(vinput_class)| will generate the \cpp|struct attribute_group vinput_class_group| that should be assigned in \cpp|vinput_class|.
+Finally, call \cpp|class_register(&vinput_class)| to create attributes in sysfs.
+
 To create a \verb|vinputX| sysfs entry and \verb|/dev| node.
 
 \begin{codebash}
@@ -1933,7 +1990,6 @@ echo "-34" | sudo tee /dev/vinput0
 
 \samplec{examples/vkbd.c}
 
-% TODO: Add description of attribute
 % TODO: Add vts.c and vmouse.c example
 
 \section{Standardizing the interfaces: The Device Model}