kernel常用API源码分析
文章平均质量分 63
tiantao2012
这个作者很懒,什么都没留下…
展开
-
模块API之__module_address
在kernel中的__module_address 可以根据一个跟定的内存地址,获得该内存地址所在的门口。例如下面的例子,源码在kernel/jump_lable.c 中jump_label_add_module函数preempt_disable();jlm2->mod = __module_address((unsigned long)key);preempt_enable();可以看原创 2017-10-27 17:03:30 · 1337 阅读 · 0 评论 -
模块API之__module_text_address
__module_text_addres函数根据位于模块代码段的地址,返回这个模块具体例子在kernel/jump_label.c struct module *mod; preempt_disable(); mod = __module_text_address((unsigned long)start); WARN_ON_ONCE(__module_text_address((un原创 2017-10-28 17:30:08 · 679 阅读 · 0 评论 -
模块API之lookup_module_symbol_name
int lookup_module_symbol_name(unsigned long addr, char *symname) 用于返回addr 对应symbol的name使用的例子如下:int lookup_symbol_name(unsigned long addr, char *symname){ symname[0] = '\0'; symname[KSYM_NAME_LEN原创 2017-11-07 14:03:17 · 921 阅读 · 0 评论 -
模块API之find_module
find_module 函数根据模块的name返回指向这个模块的指针其用法如下: if (mutex_lock_interruptible(&module_mutex) != 0) return -EINTR; mod = find_module(name); if (!mod) { ret = -ENOENT; goto out; } mutex_原创 2017-10-30 15:17:17 · 1279 阅读 · 0 评论 -
模块API之lookup_module_symbol_attrs
static inline int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)的作用是返回addr所在模块的size和offset,并返回模块的name和addr代表symbol的name使用的例子如下:原创 2017-11-08 08:46:07 · 477 阅读 · 0 评论 -
模块API之module_is_live
module_is_live 用于判断模块是否处于活动状态使用的实例如下所示:bool try_module_get(struct module *module){ bool ret = true; if (module) { preempt_disable(); /* Note: here, we can fail to get a reference */ if (li原创 2017-10-31 14:11:21 · 485 阅读 · 0 评论 -
模块API之module_get_kallsym
static inline int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, char *name, char *module_name, int *exported)用于找到第一个模块的symbol list中找到第一个大于symnum的模块的value,type,na原创 2017-11-09 08:58:16 · 1028 阅读 · 0 评论 -
模块API之module_put/__module_get
module_put和__module_get 是一对函数,用于减少或者增加模块的引用计数.具体使用的例子如下:void nfs4_schedule_state_manager(struct nfs_client *clp){ struct task_struct *task; char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1];原创 2017-11-01 14:55:54 · 3133 阅读 · 0 评论 -
模块API之print_modules
static inline void print_modules(void)用于曾经在kernel中存在的模块的name和flag其使用的例子如下:static noinline void __schedule_bug(struct task_struct *prev){ /* Save this before calling printk(), since that will clobb原创 2017-11-10 14:41:04 · 1043 阅读 · 0 评论 -
模块API之ref_module
int ref_module(struct module *a, struct module *b)实现模块a使用模块b,同时增加模块b的引用计数其使用的例子如下:/* Resolve a symbol for this module. I.e. if we find one, record usage. */static const struct kernel_symbol *resol原创 2017-11-10 14:41:53 · 896 阅读 · 0 评论 -
模块API之module_refcount
module_refcount用来显示该模块被其他模块引用的计数.使用的实例如下:static int kdb_lsmod(int argc, const char **argv){ struct module *mod; if (argc != 0) return KDB_ARGCOUNT; kdb_printf("Module Size原创 2017-11-02 09:43:43 · 835 阅读 · 0 评论 -
模块API之try_module_get
try_module_get的作用是如果一个模块处于活动状态,则对其引用计数加1.在kernel中使用的例程如下:struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags){ struct qstr this; st原创 2017-11-03 09:23:28 · 974 阅读 · 0 评论 -
模块API之register_module_notifier
int register_module_notifier(struct notifier_block *nb)函数用于注册需要知道当前模块的状态,然后触发一个回调函数使用的例子如下:static __init int jump_label_init_module(void){return register_module_notifier(&jump_label_module_n原创 2017-11-14 08:59:13 · 2478 阅读 · 0 评论 -
模块API之each_symbol_section
bool each_symbol_section(bool (*fn)(const struct symsearch *arr, struct module *owner, void *data), void *data);函数用于在kernel中所有的symbol的区域执行fn这个函数,目前只有看到在find_symbol 这个函数中使用,用于找到对应的symb原创 2017-11-14 09:24:06 · 563 阅读 · 0 评论 -
进程管理API之get_task_mm
struct mm_struct *get_task_mm(struct task_struct *task) 其作用是得到task_struct *task的成员变量mm,如果是user space的task的话,通过将得到mm_struct *mm 结构体的mm_users成员变量加1如果是kernel space的task的话,其mm为null其使用的例子如下:int access_原创 2017-11-29 08:54:09 · 3388 阅读 · 1 评论 -
模块API之__symbol_get/__symbol_put
__symbol_get/__symbol_put 是一对函数。分别用于根据一个symbol 找到对应的模块后,将模块的引用计数增加1或者减小1.其源码分析如下:void *__symbol_get(const char *symbol){ struct module *owner; const struct kernel_symbol *sym;//find_symbol 会查找原创 2017-11-15 08:44:43 · 2336 阅读 · 0 评论 -
模块API之print_symbol
inline void print_symbol(const char *fmt, unsigned long addr) 由于根据客户给定的格式将addr对应的symbol打印出来。其使用的例子如下:例如这里就将dev_attr->show地址中保存的symbol 用%s打印出来.static ssize_t dev_attr_show(struct kobject *kobj, stru原创 2017-11-20 10:29:02 · 1116 阅读 · 0 评论 -
模块API之module_address_lookup
static inline const char *module_address_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char **modname, char *namebuf)用于查找addr代表的symbol name,原创 2017-11-06 14:14:59 · 1129 阅读 · 0 评论 -
进程管理API之ns_of_pid
inline struct pid_namespace *ns_of_pid(struct pid *pid)其作用是根据struct pid返回其所在的namespace其使用的例子如下:struct pid_namespace *task_active_pid_ns(struct task_struct *tsk){ return ns_of_pid(task_pid(tsk));}原创 2017-11-30 08:39:24 · 537 阅读 · 0 评论 -
进程调度API之__wake_up_sync
void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)和__wake_up 函数的形参和作用一样。不同在于会根据是如果nr_exclusive等于1的话,传递给wakup 后要执行函数的wake_flags 等于1.而__wake_up 传递的wake_flags always是0void原创 2017-12-08 14:41:35 · 1311 阅读 · 0 评论 -
进程管理API之__task_pid_nr_ns
pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,struct pid_namespace *ns)此函数用于根据task和pid_namespace得到符合条件的进程号也就是pid号。使用的例子如下:task_pid_nr_ns 函数通过调用__task_pid_nr_ns 得到符合task_struct原创 2017-11-21 14:31:20 · 2259 阅读 · 0 评论 -
模块API之symbol_put_addr
void symbol_put_addr(void *addr)的作用是根据addr找到所在的模块,然后将模块的应用计数减1这里有假定addr是一个函数的地址。其源码如下:/* Note this assumes addr is a function, which it currently always is. */void symbol_put_addr(void *addr){ s原创 2017-11-16 08:45:26 · 707 阅读 · 0 评论 -
进程管理API之pid_nr/pid_vnr/pid_nr_ns
inline pid_t pid_nr(struct pid *pid) 的主要是获得进程的全局pid号,也就是从init 所在的namespace看到的pid号pid_nr() : global id, i.e. the id seen from the init namespace;static inline pid_t pid_nr(struct pid *pid){ pid_原创 2017-12-01 08:46:15 · 1674 阅读 · 0 评论 -
进程管理API之find_get_pid
struct pid *find_get_pid(pid_t nr)根据进程号pid_t nr nr得到进程描述符struct pid ,并将进程描述符中的字段count加1这里的进程描述符定义如下:struct pid{ atomic_t count; unsigned int level; /* lists of tasks that use this pid */ struct原创 2017-11-22 08:51:14 · 6158 阅读 · 0 评论 -
模块API之sprint_symbol
int sprint_symbol(char *buffer, unsigned long address)的作用是根据内存中地址address查找这个地址对应的symbol,并加此symbol的name,offset,size等基本信息连成字符串赋值给buffer.其使用的例子如下:static void hist_trigger_stacktrace_print(struct seq_f原创 2017-11-17 09:34:07 · 1671 阅读 · 0 评论 -
进程调度API之preempt_count_add(val)/preempt_count_sub(val)
preempt_count_add(val)/preempt_count_sub(val)分别用于增加和减小当前进程的引用计数如果治理的val等于1的话,则等同于下面这两个宏#define preempt_count_inc() preempt_count_add(1)#define preempt_count_dec() preempt_count_sub(1)使用的例子如下:例如我们原创 2017-12-11 08:59:36 · 1071 阅读 · 0 评论 -
进程调度API之preempt_count_dec_and_test
preempt_count_dec_and_test()用于判断当前thread的preempt_count是否零从而决定当前thread是否可以被抢占其使用的例子如下:#define preempt_enable() \do { \ barrier(); \ if (unlikely(preempt_count_dec_and_test())) \ __preempt_schedu原创 2017-12-11 09:24:32 · 1067 阅读 · 0 评论 -
进程调度API之preempt_notifier_register/preempt_notifier_unregister
void preempt_notifier_register(struct preempt_notifier *notifier)用于简单thread是否被抢占或者重新调度形参preempt_notifier的定义如下:struct preempt_notifier { struct hlist_node link; struct preempt_ops *ops;};其中stru原创 2017-12-19 17:12:43 · 1170 阅读 · 0 评论 -
进程管理API之find_pid_ns
struct pid *find_pid_ns(int nr, struct pid_namespace *ns) 用于从namespace 下的pid找到对应的pid结构体其中pid结构体定义如下:struct pid{ atomic_t count; unsigned int level; /* lists of tasks that use this pid */ struct原创 2017-11-23 08:52:16 · 1614 阅读 · 0 评论 -
进程调度API之set_cpus_allowed_ptr
int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)此函数的作用是改变进程struct task_struct *p 执行时所占的cpu资源其使用的例程如下:在kernel中的main函数中 /* * init can run on any cpu. */ set_cpus_原创 2017-12-20 09:15:08 · 4448 阅读 · 0 评论 -
进程调度API之set_user_nice
void set_user_nice(struct task_struct *p, long nice)用于设置进程的nice值.其使用的例程如下:static int kmemleak_scan_thread(void *arg){ static int first_run = 1; pr_info("Automatic memory scanning thread started原创 2017-12-20 09:41:33 · 8741 阅读 · 1 评论 -
进程调度API之should_resched
static __always_inline bool should_resched(int preempt_offset)用于判断当前函数能否被抢占.其使用的例子如下:本例中中通过should_resched的返回值resched 来决定当前thread 是否可以被调度int __cond_resched_lock(spinlock_t *lock){ int resched = s原创 2017-12-12 08:55:39 · 1230 阅读 · 0 评论 -
进程管理API之find_task_by_pid_ns
struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)根据nr和其对应的ns找到对应的task。其使用的例子如下:struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags原创 2017-11-24 09:51:38 · 3034 阅读 · 0 评论 -
进程调度API之preempt_schedule
asmlinkage __visible void __sched notrace preempt_schedule(void)这个函数用于检查当前thread是否可以主动让出cpu给其他thread 运行其使用的例子如下:static void torture_rwsem_write_delay(struct torture_random_state *trsp){ const uns原创 2017-12-12 13:56:07 · 2319 阅读 · 0 评论 -
进程管理API之pid_task
struct task_struct *pid_task(struct pid *pid, enum pid_type type) 用于根据pid和其类型找到对应的task_struct其中pid的类型如下:enum pid_type{ PIDTYPE_PID, PIDTYPE_PGID, PIDTYPE_SID, PIDTYPE_MAX};其使用的例子如下:int kill_原创 2017-12-04 09:16:46 · 3468 阅读 · 0 评论 -
进程管理API之kernel_thread
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) 用于创建一个kernel thread,这个thread的回调函数是fn,返回值是新创建thread的pid其使用的例子如下:static noinline void __ref rest_init(void){ int pid; rcu_sc原创 2017-12-04 14:09:29 · 640 阅读 · 0 评论 -
进程调度API之sleep_on_spinunlock
sleep_on_spinunlock 是一个宏,是等待队列使用的一个包装,这个函数重点是sleep和spinunlock这两个操作可以看到sleep_on_spinunlock 有两个参数,第一个参数是要等待的队列,第二个参数表示要执行spin_unlock的锁#define sleep_on_spinunlock(wq, s) \ do { \ DECLARE_WA原创 2017-12-21 08:47:00 · 424 阅读 · 0 评论 -
进程调度API之preempt_count_add/preempt_count_sub
void preempt_count_add(int val) 用于增加当前进程的引用计数,这样可以避免当前进程被抢占与之对应的是void preempt_count_sub(int val)用来当前进程的引用计数,这样当引用计数为0时,当前进程就可以被抢占.这两个函数是一对的,一般一起使用其使用的例程如下:#define __irq_enter() \ do { \原创 2017-12-21 09:10:16 · 2127 阅读 · 0 评论 -
进程调度API之add_wait_queue/remove_wait_queue
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)用于将等待元素wait插入到等待队列的头部其使用的例子如下:static long bt_sock_data_wait(struct sock *sk, long timeo){ DECLARE_WAITQUEUE(wait, current);//加入等待队列原创 2017-12-13 09:05:47 · 2680 阅读 · 0 评论 -
进程调度API之add_wait_queue_exclusive
void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait)函数的作用和add_wait_queue的区别在与add_wait_queue_exclusive会设置flag WQ_FLAG_EXCLUSIVE表明此进程是高优先级的进程。void add_wait_queue_exclusive(wait_原创 2017-12-13 14:11:57 · 1228 阅读 · 0 评论