mirror of
https://github.com/54shady/kernel_drivers_examples.git
synced 2025-08-08 08:23:56 +00:00
Get task_struct according to the PID
Change-Id: I2dbb0dca24465b8684e1a0a88b59379926f751ab
This commit is contained in:
@ -117,7 +117,7 @@ parameter里分区如下
|
||||
|
||||
如何确定开发板上调试串口电平是3.0v还是1.8v的
|
||||
|
||||

|
||||

|
||||
|
||||
硬件原理图连接如下
|
||||
|
||||
|
@ -18,6 +18,8 @@ obj-m := skeleton_ss.o
|
||||
obj-m += kset_skeleton.o
|
||||
obj-m += seq_test.o
|
||||
obj-m += seq_test2.o
|
||||
obj-m += seq_test3.o
|
||||
obj-m += pid2task.o
|
||||
|
||||
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
|
||||
KERNEL_BUID_OUTPUT ?=$(KERNEL_DIR)
|
||||
|
232
debug/platform_driver_test/pid2task.c
Normal file
232
debug/platform_driver_test/pid2task.c
Normal file
@ -0,0 +1,232 @@
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
/* Self define object struct */
|
||||
struct skeleton_kobject {
|
||||
struct kobject kobj;
|
||||
int value;
|
||||
char buf[1024];
|
||||
};
|
||||
#define to_skeleton_kobject(x) container_of(x, struct skeleton_kobject, kobj)
|
||||
|
||||
/* a custom attribute that works just for a struct skeleton_kobject. */
|
||||
struct skeleton_attribute {
|
||||
struct attribute attr;
|
||||
ssize_t (*show)(struct skeleton_kobject *foo, struct skeleton_attribute *attr, char *buf);
|
||||
ssize_t (*store)(struct skeleton_kobject *foo, struct skeleton_attribute *attr, const char *buf, size_t count);
|
||||
};
|
||||
#define to_foo_attr(x) container_of(x, struct skeleton_attribute, attr)
|
||||
|
||||
/* global variable */
|
||||
static struct kset *g_skeleton_kset;
|
||||
static struct skeleton_kobject *g_ske_obj;
|
||||
|
||||
/*
|
||||
* The default show function that must be passed to sysfs. This will be
|
||||
* called by sysfs for whenever a show function is called by the user on a
|
||||
* sysfs file associated with the kobjects we have registered. We need to
|
||||
* transpose back from a "default" kobject to our custom struct skeleton_kobject and
|
||||
* then call the show function for that specific object.
|
||||
*/
|
||||
static ssize_t skeleton_sysfs_show(struct kobject *kobj,
|
||||
struct attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct skeleton_attribute *attribute;
|
||||
struct skeleton_kobject *ske_obj;
|
||||
|
||||
attribute = to_foo_attr(attr);
|
||||
ske_obj = to_skeleton_kobject(kobj);
|
||||
|
||||
if (!attribute->show)
|
||||
return -EIO;
|
||||
|
||||
return attribute->show(ske_obj, attribute, buf);
|
||||
}
|
||||
|
||||
/* echo pid > /sys/kernel/KSET_NAME/KOBJECT_NAME/attr_one */
|
||||
static ssize_t skeleton_sysfs_store(struct kobject *kobj,
|
||||
struct attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
int pid;
|
||||
struct skeleton_attribute *attribute;
|
||||
struct skeleton_kobject *ske_obj;
|
||||
struct pid *pid_t;
|
||||
struct task_struct *task;
|
||||
|
||||
/* get task_struct according the PID */
|
||||
sscanf(buf, "%d", &pid);
|
||||
pid_t = find_get_pid(pid);
|
||||
task = get_pid_task(pid_t, PIDTYPE_PID);
|
||||
|
||||
pr_debug("pid:%d user:%lld gtime:%lld sys:%lld, %s (%d-%d-%d)",
|
||||
task->pid,
|
||||
task->utime,
|
||||
task->gtime,
|
||||
task->stime,
|
||||
task->comm,
|
||||
task->prio,
|
||||
task->static_prio,
|
||||
task->normal_prio);
|
||||
|
||||
attribute = to_foo_attr(attr);
|
||||
ske_obj = to_skeleton_kobject(kobj);
|
||||
|
||||
sprintf(ske_obj->buf, "pid:%d user:%lld gtime:%lld sys:%lld, %s (%d-%d-%d)",
|
||||
task->pid,
|
||||
task->utime,
|
||||
task->gtime,
|
||||
task->stime,
|
||||
task->comm,
|
||||
task->prio,
|
||||
task->static_prio,
|
||||
task->normal_prio);
|
||||
|
||||
if (!attribute->store)
|
||||
return -EIO;
|
||||
|
||||
return attribute->store(ske_obj, attribute, buf, len);
|
||||
}
|
||||
|
||||
/* Our custom sysfs_ops that we will associate with our ktype later on */
|
||||
static const struct sysfs_ops skeleton_sysfs_ops = {
|
||||
.show = skeleton_sysfs_show,
|
||||
.store = skeleton_sysfs_store,
|
||||
};
|
||||
|
||||
/*
|
||||
* The release function for our object. This is REQUIRED by the kernel to
|
||||
* have. We free the memory held in our object here.
|
||||
*
|
||||
* NEVER try to get away with just a "blank" release function to try to be
|
||||
* smarter than the kernel. Turns out, no one ever is...
|
||||
*/
|
||||
static void skeleton_release(struct kobject *kobj)
|
||||
{
|
||||
struct skeleton_kobject *ske_obj;
|
||||
|
||||
ske_obj = to_skeleton_kobject(kobj);
|
||||
kfree(ske_obj);
|
||||
}
|
||||
|
||||
/* cat /sys/kernel/KSET_NAME/KOBJECT_NAME/attr_one */
|
||||
static ssize_t attr_one_show(struct skeleton_kobject *ske_obj, struct skeleton_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n", ske_obj->buf);
|
||||
}
|
||||
|
||||
static ssize_t attr_one_store(struct skeleton_kobject *ske_obj, struct skeleton_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Sysfs attributes cannot be world-writable. */
|
||||
static struct skeleton_attribute attribute_one =
|
||||
__ATTR(attr_one, 0664, attr_one_show, attr_one_store);
|
||||
|
||||
/*
|
||||
* More complex function where we determine which variable is being accessed by
|
||||
* looking at the attribute for the "baz" and "bar" files.
|
||||
*/
|
||||
/*
|
||||
* Create a group of attributes so that we can create and destroy them all
|
||||
* at once.
|
||||
*/
|
||||
static struct attribute *skeleton_default_attrs[] = {
|
||||
&attribute_one.attr,
|
||||
NULL, /* need to NULL terminate the list of attributes */
|
||||
};
|
||||
|
||||
/*
|
||||
* Our own ktype for our kobjects. Here we specify our sysfs ops, the
|
||||
* release function, and the set of default attributes we want created
|
||||
* whenever a kobject of this type is registered with the kernel.
|
||||
*/
|
||||
static struct kobj_type skeleton_ktype = {
|
||||
.sysfs_ops = &skeleton_sysfs_ops,
|
||||
.release = skeleton_release,
|
||||
.default_attrs = skeleton_default_attrs,
|
||||
};
|
||||
|
||||
static struct skeleton_kobject *create_kobject_skeleton(const char *kobj_name)
|
||||
{
|
||||
struct skeleton_kobject *ske_obj;
|
||||
int retval;
|
||||
|
||||
/* allocate the memory for the whole object */
|
||||
ske_obj = kzalloc(sizeof(struct skeleton_kobject), GFP_KERNEL);
|
||||
if (!ske_obj)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* As we have a kset for this kobject, we need to set it before calling
|
||||
* the kobject core.
|
||||
*/
|
||||
ske_obj->kobj.kset = g_skeleton_kset;
|
||||
|
||||
/*
|
||||
* Initialize and add the kobject to the kernel. All the default files
|
||||
* will be created here. As we have already specified a kset for this
|
||||
* kobject, we don't have to set a parent for the kobject, the kobject
|
||||
* will be placed beneath that kset automatically.
|
||||
*/
|
||||
retval = kobject_init_and_add(&ske_obj->kobj, &skeleton_ktype, NULL, "%s", kobj_name);
|
||||
if (retval) {
|
||||
kobject_put(&ske_obj->kobj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are always responsible for sending the uevent that the kobject
|
||||
* was added to the system.
|
||||
*/
|
||||
kobject_uevent(&ske_obj->kobj, KOBJ_ADD);
|
||||
|
||||
return ske_obj;
|
||||
}
|
||||
|
||||
static void destroy_skeleton_kobject(struct skeleton_kobject *ske_obj)
|
||||
{
|
||||
kobject_put(&ske_obj->kobj);
|
||||
}
|
||||
|
||||
static int example_init(void)
|
||||
{
|
||||
/*
|
||||
* Create a kset with the name of "KSET_NAME",
|
||||
* located under /sys/kernel/
|
||||
*/
|
||||
g_skeleton_kset = kset_create_and_add("KSET_NAME", NULL, kernel_kobj);
|
||||
if (!g_skeleton_kset)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Create a object and register with our kset */
|
||||
g_ske_obj = create_kobject_skeleton("KOBJECT_NAME");
|
||||
if (!g_ske_obj)
|
||||
{
|
||||
kset_unregister(g_skeleton_kset);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void example_exit(void)
|
||||
{
|
||||
destroy_skeleton_kobject(g_ske_obj);
|
||||
kset_unregister(g_skeleton_kset);
|
||||
}
|
||||
|
||||
module_init(example_init);
|
||||
module_exit(example_exit);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("zeroway <M_O_Bz@163.com>");
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Reference in New Issue
Block a user