Linux GPIOs handling - linux-kernel

I have some question about Linux kernel and GPIOs. I know that in Linux everything is file so when I do something like
echo 30 > /sys/class/gpio/export
and
echo 1 > /sys/class/gpio/gpio30/value
what really happens? I mean how does sysfs handle that? Does it call system calls implemented in gpiolib?

The gpiolib registers the value attribute in this way:
static const DEVICE_ATTR(value, 0644, gpio_value_show, gpio_value_store);
It creates a device attribute named value, with permission 644; on read it calls gpio_value_show, on write it calls gpio_value_store
What sysfs does, is to redirect read and write to the correspondent function of a sysfs attribute.

Related

Windows Driver substitue for linux device driver sysfs interface

Let me describe what sysfs does : its a pseudo file system where files, directories are generated by the core kernel or kernel drivers. And these files have read/write access and are a mechanism to control certain kernel level parameters by user space (seperate from ioctls and file operations).
Sysfs from Kernel.org
Sysfs from Wikipedia
The following is an example of how userspace interacts with sysfs.
$ cat /sys/modules/mydriver/foo_count
1
$ echo "2" > /sys/modules/mydriver/foo_count $ cat /sys/modules/mydriver/foo_count
2
The cat command will trigger a read via the show_foo_count() kernel routine, while the echo will trigger a write via the store_foo_count() routine
The following is how the kernel driver/module might intercept the user space activity.
static ssize_t show_foo_count(struct kobject *kobj,struct kobj_attribute *attr,
char *buf)
{
/* This will perform a read operation and contents of buf will be updated*/
...
}
static ssize_t store_foo_count(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf,size_t len)
{
/* Contents are read from buf and stored within the driver's context/state */
...
}
A good example is here
How can one achieve the same sysfs usage on windows drivers ?
I see the following windows concepts, but I am unable to map them to be the equivalent of syfs :
A. Device Objects
B. File Object

NET-SNMP: custom disman monitor not sending trap

I configured in the snmpd.conf file the "extend" function to monitor a custom script.
extend shelltest /bin/sh /tmp/snmptest.sh
Then I checked the MIB for this if this "extend" function is working or not. I am able to see all Mibs for this.
snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.8072.1.3.2
If the output of my custom script returns a failed state then the following OID returns other valued then 0.
NET-SNMP-EXTEND-MIB::nsExtendResult."shelltest" = INTEGER: 3
The disman monitors looks like this:
monitor -r 30 -u internal -o ErrorMsg "False" nsExtendResult."shelltest" != 0
So from my point of view if the nsExtendResult."shelltest" return other values then 0 a trap should be triggered.
I tried several options for the monitor function but it was never working. The default monitors for example disk monitor or file monitors are working well.

Is it possible to log the output of a uboot command into a file from u-boot prompt?

I am working with an embedded board which supports u-boot.
I am trying to write and read the emmc device connected to the board,
After read, i need to have a look at the contents and compare it with the data that I have written to it.
Is there a way I can log the output of the a u-boot command, when I read a block from eMMC and store it in an address and try to view the contents of
it using:
mmc read 0x10700000 133120 1
mm.l 0x10700000
into a file and then can store the file in an emmc partition or a tftp server ?
Thank you for your time,
Nishad
The save command can be used to write memory to a file.
save file to a filesystem
save <interface> <dev[:part]> <addr> <filename> bytes [pos]
- Save binary file 'filename' to partition 'part' on device
type 'interface' instance 'dev' from addr 'addr' in memory.
'bytes' gives the size to save in bytes and is mandatory.
'pos' gives the file byte position to start writing to.
If 'pos' is 0 or omitted, the file is written from the start.
Of cause this requires the file system to be writable. For FAT this implies building with CONFIG_FAT_WRITE=y.

In linux a file is not empty but the size is 0

I test whether a file is empty in Shell.
test -s /sys/fs/cgroup/systemd/docker/d4e311735706485e748513bad611070e223cba76fdf4c72a1102d14b653da750/tasks
It returns false, and I found its size is 0 when I use ls -lh, but when I use cat, I can get 4071 in this file, this means the file is not empty. I think maybe this file is too small, I create a file in my home directory, and echo 4071 to it, I find its size is not 0. Is the file in /sys/fs/cgroup special?
The file that you are dealing with is a special file which is a part of the cgroup file system.
To understand why this happens, let's see what happens when you do test -e $filename.
We will be using strace command which prints the system calls a command does.
If you do strace test -e $filename, you will find this line in the results:
stat("$filename", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
In this case it returns st_size = 0 which is the size of the file.
But the questions is what actually happens on the other side, inside the kernel:
When you try to deal with a file, you do a system call which goes to an intermediate layer in the kernel called the virtual file system which in turn calls the part responsible for the information needed. A stat system call will try to get the status out of the inode corresponding with file. The file system can create and manipulate the inode as it wants.
Cgroup is a special file system, when it adds a file (using the cgroup_add_file function defined in kernel/cgroup.c) it always passes size 0 to __kernfs_create_file so that is why any file inside /sys/fs/cgroups (created by cgroup fs) will always has a zero size regardless of the actual contents of the file.
For the other part, when cat the file. If you do strace cat $filename, that is what you will get:
open("$filename", O_RDONLY) = 3
read(3, "...", 131072) = ###
The read system call will go through the virtual file system to the kernel file system and using the file operations associated with the file, it will get you the needed data.
Cgroup fs has functions to generate the data in its files. This is how tasks file is defined in kernel/cgroup.c
{
.name = "tasks",
.seq_start = cgroup_pidlist_start,
.seq_next = cgroup_pidlist_next,
.seq_stop = cgroup_pidlist_stop,
.seq_show = cgroup_pidlist_show,
.private = CGROUP_FILE_TASKS,
.write = cgroup_tasks_write,
},
So seq_start, seq_next, seq_stop and seq_show are the functions responsible for generating the information needed for the file. You can easily go to kernel/cgroups.c and check for what they do.
Please note that if you are trying to know if the cgroup still has tasks, an easier way is to use notify on release.
from Documentation/cgroup-v1/cgroups.txt
If the notify_on_release flag is enabled (1) in a cgroup, then whenever the last task in the cgroup leaves (exits or attaches to some other cgroup) and the last child cgroup of that cgroup is removed, then the kernel runs the command specified by the contents of the "release_agent" file in that hierarchy's root directory, supplying the pathname (relative to the mount point of the cgroup file system) of the abandoned cgroup. This enables automatic removal of abandoned cgroups. The default value of notify_on_release in the root cgroup at system boot is disabled (0). The default value of other cgroups at creation is the current value of their parents' notify_on_release settings. The default value of a cgroup hierarchy's release_agent path is empty.

why Debugfs entries not enabled?

I have a module that is cresting debugfs entries in /sys/kernel/debug/example .
But i didnt see those files in sysfs/kernel/example directory.
I see this function which do the debugfs entry creations are called in late_initcall.
late_initcall(example_debug_init);
Will this late_initcall affect the entry creation?
Sounds like you have not mount debugfs. Do it by:
mount -t debugfs none /sys/kernel/debug
For more information about using debugfs, read debugfs.txt in kernel Documentation.
Also you must enable the:
CONFIG_DEBUG_FS=y
configuration at build time, or else mount will fail.
Here is a minimal example: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/bb8f4eb79565c9771356c80e0964c8fefc163e11

Resources