看完以上的逻辑。大家是不是柳暗花明又一村,心里开朗了许多,他们之间是可以相互转换的。
通过进程pid_t可以拿到pid,通过pid可以拿到task_struct。又可以反过来通过task_struct拿到进程pid。
关闭进程接口
驱动源码是使用put_pid将进程pid*的使用次数减去1。
在Linux内核源码/kernel/pid.c下可以看到:
void put_pid(struct pid *pid){struct pid_namespace *ns;if(!pid)return;ns = pid->numbers[pid->level].ns;if((atomic_read(&pid->count) == 1) ||atomic_dec_and_test(&pid->count)) {kmem_cache_free(ns->pid_cachep, pid);put_pid_ns(ns);}}EXPORT_SYMBOL_GPL(put_pid);
读、写进程内存接口
首先根据pid*用get_pid_task取出task_struct。再用get_task_mm取出mm_struct结构。因为这个结构包含了进程的内存信息。首先检查内存是否可读if (vma->vm_flags & VM_READ)。
如果可读。那么开始计算物理内存地址位置。由于Linux内核默认开启MMU机制,所以只能以页为单位计算物理内存地址。计算物理内存地址的方法有很多。
如pagemap、pgd pud pmd pte、get_user_pages驱动里演示pagemap。
其他方法可自行参考Linux内核源码/fs/proc/task_mmu.c。
知道了物理内存地址后,读、写物理内存地址,Linux内核也有演示: driver