============
- ᇂ147차 시작 위치
- start_kernel 1 ~/init/main.c
- proc_root_init 937 ~/init/main.c
- proc_symlink 215 ~/proc/root.c
- __proc_create 597 ent = __proc_create(&parent, name,
- calll: start_kernel()
- proc_root_init()
- proc_root_init()
- proc_init_inodecache()
- register_filesystem()
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- call: start_kernel()
- proc_root_init()
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
// ATAG,DTB 정보로 사용
...
proc_caches_init();
// sighand_struct, signal_struct, files_struct, fs_struct, mm_struct, vm_area_struct, nsproxy
// 를 사용하기 위한 kmem_cache 할당자 및 percpu list 초기화 수행
...
vfs_caches_init(totalram_pages);
// virtual file system을 위한 names, dentry, inode, filp, mount cache 생성 후
// file system 을 위한 초기화 수행 및 mount 수행, block, char dev 사용을 위한 초기화 수행
signals_init();
// signal을 사용하기 위한 kmem_cache 를 생성
/* rootfs populating might need page-writeback */
page_writeback_init();
// page writeback을 위한 global_dirty_limit, ratelimit_pages 값을 초기화 수행
#ifdef CONFIG_PROC_FS // CONFIG_PROC_FS=y
proc_root_init();
- calll: start_kernel()
- proc_root_init()
- call: call_root_init()
// ARM10C 20160604
void __init proc_root_init(void)
{
int err;
proc_init_inodecache();
// proc_init_inodecache 에서 한일:
// struct proc_inode 크기 만큼의 메모리를 할당항는 kmem_cache 할당자를 생성함
// proc_inode_cachep: kmem_cache#n#28 (struct proc_inode)
// register_filesystem(&proc_fs_type): 0
err = register_filesystem(&proc_fs_type);
// err: 0
// register_filesystem에서 한일:
// (&bd_type)->next: &proc_fs_type
//
// file system 연결 결과
// file_systems: sysfs_fs_type -> rootfs_fs_type -> shmem_fs_type -> bd_type -> proc_fs_type
// err: 0
if (err)
return;
proc_self_init();
// proc_self_init 에서 한일:
// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 2 개를 할당 받음
//
// (&(&proc_inum_ida)->idr)->id_free 이 idr object new 1번을 가르킴
// |
// |-> ---------------------------------------------------------------------------------------------------------------------------
// | idr object new 1 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 |
// ---------------------------------------------------------------------------------------------------------------------------
// | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL |
// ---------------------------------------------------------------------------------------------------------------------------
//
// (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 1)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 8
//
// (&(&proc_inum_ida)->idr)->top: kmem_cache#21-oX (struct idr_layer) (idr object 8)
// (&(&proc_inum_ida)->idr)->layers: 1
// (&(&proc_inum_ida)->idr)->id_free: (idr object new 0)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 7
//
// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 1 bit를 1로 set 수행
// (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 2
//
// kmem_cache인 kmem_cache#21 에서 할당한 object인 kmem_cache#21-oX (idr object new 1) 의 memory 공간을 반환함
//
// self_inum: 0xF0000001
// proc_symlink("mounts", NULL, "self/mounts"): kmem_cache#29-oX (struct proc_dir_entry)
proc_symlink("mounts", NULL, "self/mounts");
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
// ARM10C 20160604
// "mounts", NULL, "self/mounts"
// ARM10C 20160611
// "net", NULL, "self/net"
struct proc_dir_entry *proc_symlink(const char *name,
struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent;
// &parent, name: "mounts"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "mounts", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
// &parent, name: "net"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "net", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
ent = __proc_create(&parent, name,
(S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- call: __proc_create()
// ARM10C 20160604
// &parent, name: "mounts", 0120777, 1
// ARM10C 20160611
// &parent, name: "net", 0120777, 1
// ARM10C 20160611
// &parent, name: "sysvipc", 0040555, 2
// // ARM10C 20160611
// &parent, name: "tty/ldiscs", mode: 0100444, 1
static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
const char *name,
umode_t mode,
nlink_t nlink)
{
struct proc_dir_entry *ent = NULL;
// ent: NULL
const char *fn = name;
// fn: "mounts"
unsigned int len;
/* make sure name is valid */
// name: "mounts", strlen("mounts"): 6
if (!name || !strlen(name))
goto out;
// name: "mounts", parent: &parent, &fn: &"mounts"
// xlate_proc_name("mounts", &parent, "mounts"): 0
if (xlate_proc_name(name, parent, &fn) != 0)
goto out;
// xlate_proc_name 에서 한일:
// parent: &proc_root
/* At this point there must not be any '/' characters beyond *fn */
// fn: "mounts", strchr("mounts", '/'): NULL
if (strchr(fn, '/'))
goto out;
// fn: "mounts", strlen("mounts"): 6
len = strlen(fn);
// len: 6
// ent: NULL, sizeof(struct proc_dir_entry): 91 bytes, len: 6, GFP_KERNEL: 0xD0
// kzalloc(98, GFP_KERNEL: 0xD0): kmem_cache#29-oX
ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
// ent: kmem_cache#29-oX (struct proc_dir_entry)
// ent: kmem_cache#29-oX (struct proc_dir_entry)
if (!ent)
goto out;
// ent->name: (kmem_cache#29-oX (struct proc_dir_entry))->name, fn: "mounts", len: 6
memcpy(ent->name, fn, len + 1);
// ent->name: (kmem_cache#29-oX (struct proc_dir_entry))->name: "mounts"
// ent->namelen: (kmem_cache#29-oX (struct proc_dir_entry))->namelen, len: 6
ent->namelen = len;
// ent->namelen: (kmem_cache#29-oX (struct proc_dir_entry))->namelen: 6
// ent->mode: (kmem_cache#29-oX (struct proc_dir_entry))->mode, mode: 0120777
ent->mode = mode;
// ent->mode: (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777
// ent->nlink: (kmem_cache#29-oX (struct proc_dir_entry))->nlink, nlink: 1
ent->nlink = nlink;
// ent->nlink: (kmem_cache#29-oX (struct proc_dir_entry))->nlink: 1
// &ent->count: &(kmem_cache#29-oX (struct proc_dir_entry))->count
atomic_set(&ent->count, 1);
// atomic_set 에서 한일:
// (&(kmem_cache#29-oX (struct proc_dir_entry))->count)->counter: 1
// 2016/06/04 종료
// 2016/06/11 시작
// &ent->pde_unload_lock: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock
spin_lock_init(&ent->pde_unload_lock);
// spin_lock_init에서 한일:
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock을 이용한 spin lock 초기화 수행
//
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->raw_lock: { { 0 } }
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->magic: 0xdead4ead
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner: 0xffffffff
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner_cpu: 0xffffffff
// &ent->pde_openers: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers
INIT_LIST_HEAD(&ent->pde_openers);
// INIT_LIST_HEAD 에서 한일:
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->next: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->prev: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list
out:
// ent: kmem_cache#29-oX (struct proc_dir_entry)
return ent;
// return kmem_cache#29-oX (struct proc_dir_entry)
}
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
// ARM10C 20160604
// "mounts", NULL, "self/mounts"
// ARM10C 20160611
// "net", NULL, "self/net"
struct proc_dir_entry *proc_symlink(const char *name,
struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent;
// &parent, name: "mounts"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "mounts", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
ent = __proc_create(&parent, name,
(S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
// ent: kmem_cache#29-oX (struct proc_dir_entry)
// __proc_create 에서 한일:
// struct proc_dir_entry 만큼 메모리를 할당 받음 kmem_cache#29-oX (struct proc_dir_entry)
//
// (kmem_cache#29-oX (struct proc_dir_entry))->name: "mounts"
// (kmem_cache#29-oX (struct proc_dir_entry))->namelen: 6
// (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777
// (kmem_cache#29-oX (struct proc_dir_entry))->nlink: 1
// (&(kmem_cache#29-oX (struct proc_dir_entry))->count)->counter: 1
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock을 이용한 spin lock 초기화 수행
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->raw_lock: { { 0 } }
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->magic: 0xdead4ead
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner: 0xffffffff
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner_cpu: 0xffffffff
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->next: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->prev: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list
//
// parent: &proc_root
// ent: kmem_cache#29-oX (struct proc_dir_entry)
if (ent) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data, dest: "self/mounts", strlen("self/mounts"): 11
// ent->size: (kmem_cache#29-oX (struct proc_dir_entry))->size: 11, GFP_KERNEL: 0xD0,
// kmalloc(12, GFP_KERNEL: 0xD0): kmem_cache#30-oX
ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc() : ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL)
- call: kmalloc()
// ARM10C 20160611
// 12, GFP_KERNEL: 0xD0
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
// size: 172
if (__builtin_constant_p(size)) {
// size: 172, KMALLOC_MAX_CACHE_SIZE: 0x2000
if (size > KMALLOC_MAX_CACHE_SIZE)
return kmalloc_large(size, flags);
#ifndef CONFIG_SLOB // CONFIG_SLOB=n
// flags: 0xD0, GFP_DMA: 0x01u
if (!(flags & GFP_DMA)) {
// size: 172, kmalloc_index(172): 8
int index = kmalloc_index(size);
// index: 8
// index: 8
if (!index)
return ZERO_SIZE_PTR;
// index: 8, kmalloc_caches[8]: kmem_cache#27->name: flags: 0xD0, size: 172
return kmem_cache_alloc_trace(kmalloc_caches[index],
flags, size);
// return kmem_cache#27-o0
}
#endif
}
return __kmalloc(size, flags);
}
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc()
- return proc_symlink()
- kmalloc((ent->size=strlen(dest))+1)
- strcpy()
- proc_register()
// ARM10C 20160604
// "mounts", NULL, "self/mounts"
struct proc_dir_entry *proc_symlink(const char *name,
struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent;
// &parent, name: "mounts"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "mounts", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
ent = __proc_create(&parent, name,
(S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
// ent: kmem_cache#29-oX (struct proc_dir_entry)
// __proc_create 에서 한일:
// struct proc_dir_entry 만큼 메모리를 할당 받음 kmem_cache#29-oX (struct proc_dir_entry)
//
// (kmem_cache#29-oX (struct proc_dir_entry))->name: "mounts"
// (kmem_cache#29-oX (struct proc_dir_entry))->namelen: 6
// (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777
// (kmem_cache#29-oX (struct proc_dir_entry))->nlink: 1
// (&(kmem_cache#29-oX (struct proc_dir_entry))->count)->counter: 1
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock을 이용한 spin lock 초기화 수행
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->raw_lock: { { 0 } }
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->magic: 0xdead4ead
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner: 0xffffffff
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner_cpu: 0xffffffff
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->next: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->prev: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list
//
// parent: &proc_root
// ent: kmem_cache#29-oX (struct proc_dir_entry)
if (ent) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data, dest: "self/mounts", strlen("self/mounts"): 11
// ent->size: (kmem_cache#29-oX (struct proc_dir_entry))->size: 11, GFP_KERNEL: 0xD0,
// kmalloc(12, GFP_KERNEL: 0xD0): kmem_cache#30-oX
ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
if (ent->data) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX, dest: "self/mounts"
// strcpy(kmem_cache#30-oX, "self/mounts"): kmem_cache#30-oX: "self/mounts"
strcpy((char*)ent->data,dest);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX: "self/mounts"
// parent: &proc_root, ent: kmem_cache#29-oX (struct proc_dir_entry),
// proc_register(&proc_root, kmem_cache#29-oX (struct proc_dir_entry)): 0
if (proc_register(parent, ent) < 0) {
kfree(ent->data);
kfree(ent);
ent = NULL;
}
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc((ent->size=strlen(dest))+1)
- strcpy()
- proc_register()
- call: proc_register()
// ARM10C 20160611
// parent: &proc_root, ent: kmem_cache#29-oX (struct proc_dir_entry)
static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
struct proc_dir_entry *tmp;
int ret;
// &dp->low_ino: &(kmem_cache#29-oX (struct proc_dir_entry))->low_ino
// proc_alloc_inum(&(kmem_cache#29-oX (struct proc_dir_entry))->low_ino): 0
ret = proc_alloc_inum(&dp->low_ino);
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc((ent->size=strlen(dest))+1)
- strcpy()
- proc_register()
- call: proc_register()
- proc_alloc_inum()
- call: proc_alloc_inum()
// ARM10C 20160604
// &self_inum
int proc_alloc_inum(unsigned int *inum)
{
unsigned int i;
int error;
retry:
// GFP_KERNEL: 0xD0, ida_pre_get(&proc_inum_ida, 0xD0): 1
if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
return -ENOMEM;
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc((ent->size=strlen(dest))+1)
- strcpy()
- proc_register()
- call: proc_register()
- proc_alloc_inum()
- call: proc_alloc_inum()
- ida_pre_get()
- __idr_pre_get에서 한일: // idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 2 개를 할당 받음 // // (&(&proc_inum_ida)->idr)->id_free 이 idr object new 1번을 가르킴 // | // |-> --------------------------------------------------------------------------------------------------------------------------- // | idr object new 1 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 | // --------------------------------------------------------------------------------------------------------------------------- // | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL | // --------------------------------------------------------------------------------------------------------------------------- // // (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 1) // (&(&proc_inum_ida)->idr)->id_free_cnt: 8
// ARM10C 20160604
// &self_inum
int proc_alloc_inum(unsigned int *inum)
{
unsigned int i;
int error;
retry:
// GFP_KERNEL: 0xD0, ida_pre_get(&proc_inum_ida, 0xD0): 1
if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
return -ENOMEM;
// __idr_pre_get에서 한일:
// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 2 개를 할당 받음
//
// (&(&proc_inum_ida)->idr)->id_free 이 idr object new 1번을 가르킴
// |
// |-> ---------------------------------------------------------------------------------------------------------------------------
// | idr object new 1 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 |
// ---------------------------------------------------------------------------------------------------------------------------
// | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL |
// ---------------------------------------------------------------------------------------------------------------------------
//
// (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 1)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 8
spin_lock_irq(&proc_inum_lock);
// spin_lock_irq 에서 한일:
// &proc_inum_lock 을 사용하여 spin lock을 수행
// ida_get_new(&proc_inum_ida, &i): 0
error = ida_get_new(&proc_inum_ida, &i);
// error: 0
// ida_get_new 에서 한일:
// (&(&proc_inum_ida)->idr)->top: kmem_cache#21-oX (struct idr_layer) (idr object 8)
// (&(&proc_inum_ida)->idr)->layers: 1
// (&(&proc_inum_ida)->idr)->id_free: (idr object new 0)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 7
//
// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 1 bit를 1로 set 수행
// (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 2
//
// i: 1
//
// kmem_cache인 kmem_cache#21 에서 할당한 object인 kmem_cache#21-oX (idr object new 1) 의 memory 공간을 반환함
spin_unlock_irq(&proc_inum_lock);
// spin_unlock_irq 에서 한일:
// &proc_inum_lock 을 사용하여 spin lock을 수행
// error: 0
if (error == -EAGAIN)
goto retry;
else if (error)
return error;
// i: 1, UINT_MAX: 0xFFFFFFFF, PROC_DYNAMIC_FIRST: 0xF0000000
if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
spin_lock_irq(&proc_inum_lock);
ida_remove(&proc_inum_ida, i);
spin_unlock_irq(&proc_inum_lock);
return -ENOSPC;
}
// *inum: self_inum, PROC_DYNAMIC_FIRST: 0xF0000000, i: 1
*inum = PROC_DYNAMIC_FIRST + i;
// *inum: self_inum: 0xF0000001
return 0;
// return 0
}
- return:
// ARM10C 20160604
// &proc_inum_ida, GFP_KERNEL: 0xD0
int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
{
/* allocate idr_layers */
// &ida->idr: &(&unnamed_dev_ida)->idr, gfp_mask: 0x20
// __idr_pre_get(&(&unnamed_dev_ida)->idr, 0x20): 1
if (!__idr_pre_get(&ida->idr, gfp_mask))
return 0;
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc((ent->size=strlen(dest))+1)
- strcpy()
- proc_register()
- call: proc_register()
- proc_alloc_inum()
- call: proc_alloc_inum()
- ida_pre_get()
- call: ida_pre_get()
- __idr_pre_get()
- call: __idr_pre_get()
// ARM10C 20160604
// "mounts", NULL, "self/mounts"
struct proc_dir_entry *proc_symlink(const char *name,
struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent;
// &parent, name: "mounts"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "mounts", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
ent = __proc_create(&parent, name,
(S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
// ent: kmem_cache#29-oX (struct proc_dir_entry)
- __proc_create 에서 한일:
// struct proc_dir_entry 만큼 메모리를 할당 받음 kmem_cache#29-oX (struct proc_dir_entry) // // (kmem_cache#29-oX (struct proc_dir_entry))->name: "mounts" // (kmem_cache#29-oX (struct proc_dir_entry))->namelen: 6 // (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777 // (kmem_cache#29-oX (struct proc_dir_entry))->nlink: 1 // (&(kmem_cache#29-oX (struct proc_dir_entry))->count)->counter: 1 // &(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock을 이용한 spin lock 초기화 수행 // ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->raw_lock: { { 0 } } // ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->magic: 0xdead4ead // ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner: 0xffffffff // ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner_cpu: 0xffffffff // &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->next: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list // &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->prev: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list // // parent: &proc_root
// ARM10C 20160604
// "mounts", NULL, "self/mounts"
struct proc_dir_entry *proc_symlink(const char *name,
struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent;
// &parent, name: "mounts"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "mounts", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
ent = __proc_create(&parent, name,
(S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
// ent: kmem_cache#29-oX (struct proc_dir_entry)
// ent: kmem_cache#29-oX (struct proc_dir_entry)
if (ent) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data, dest: "self/mounts", strlen("self/mounts"): 11
// ent->size: (kmem_cache#29-oX (struct proc_dir_entry))->size: 11, GFP_KERNEL: 0xD0,
// kmalloc(12, GFP_KERNEL: 0xD0): kmem_cache#30-oX
ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
if (ent->data) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX, dest: "self/mounts"
// strcpy(kmem_cache#30-oX, "self/mounts"): kmem_cache#30-oX: "self/mounts"
strcpy((char*)ent->data,dest);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX: "self/mounts"
// parent: NULL, ent: kmem_cache#29-oX (struct proc_dir_entry),
// proc_register(NULL, kmem_cache#29-oX (struct proc_dir_entry)): 0
if (proc_register(parent, ent) < 0) {
kfree(ent->data);
kfree(ent);
ent = NULL;
}
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc()
- strcpy()
- proc_register()
- call: proc_register()
// ARM10C 20160611
// parent: &proc_root, ent: kmem_cache#29-oX (struct proc_dir_entry)
static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
struct proc_dir_entry *tmp;
int ret;
// &dp->low_ino: &(kmem_cache#29-oX (struct proc_dir_entry))->low_ino
// proc_alloc_inum(&(kmem_cache#29-oX (struct proc_dir_entry))->low_ino): 0
ret = proc_alloc_inum(&dp->low_ino);
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc()
- strcpy()
- proc_register()
- call: proc_register()
- proc_alloc_inum()
- call: proc_alloc_inum()
// ARM10C 20160611
// &dp->low_ino: &(kmem_cache#29-oX (struct proc_dir_entry))->low_ino
int proc_alloc_inum(unsigned int *inum)
{
unsigned int i;
int error;
retry:
// GFP_KERNEL: 0xD0, ida_pre_get(&proc_inum_ida, 0xD0): 1
if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
return -ENOMEM;
// __idr_pre_get에서 한일:
// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 2 개를 할당 받음
//
// (&(&proc_inum_ida)->idr)->id_free 이 idr object new 1번을 가르킴
// |
// |-> ---------------------------------------------------------------------------------------------------------------------------
// | idr object new 1 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 |
// ---------------------------------------------------------------------------------------------------------------------------
// | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL |
// ---------------------------------------------------------------------------------------------------------------------------
//
// (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 1)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 8
spin_lock_irq(&proc_inum_lock);
// spin_lock_irq 에서 한일:
// &proc_inum_lock 을 사용하여 spin lock을 수행
// ida_get_new(&proc_inum_ida, &i): 0
error = ida_get_new(&proc_inum_ida, &i);
// error: 0
// ida_get_new 에서 한일:
// (&(&proc_inum_ida)->idr)->top: kmem_cache#21-oX (struct idr_layer) (idr object 8)
// (&(&proc_inum_ida)->idr)->layers: 1
// (&(&proc_inum_ida)->idr)->id_free: (idr object new 0)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 7
//
// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 1 bit를 1로 set 수행
// (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 2
//
// i: 1
//
// kmem_cache인 kmem_cache#21 에서 할당한 object인 kmem_cache#21-oX (idr object new 1) 의 memory 공간을 반환함
spin_unlock_irq(&proc_inum_lock);
// spin_unlock_irq 에서 한일:
// &proc_inum_lock 을 사용하여 spin lock을 수행
// error: 0
if (error == -EAGAIN)
goto retry;
else if (error)
return error;
// i: 1, UINT_MAX: 0xFFFFFFFF, PROC_DYNAMIC_FIRST: 0xF0000000
if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
spin_lock_irq(&proc_inum_lock);
ida_remove(&proc_inum_ida, i);
spin_unlock_irq(&proc_inum_lock);
return -ENOSPC;
}
// *inum: self_inum, PROC_DYNAMIC_FIRST: 0xF0000000, i: 1
*inum = PROC_DYNAMIC_FIRST + i;
// *inum: self_inum: 0xF0000001
return 0;
// return 0
}
- return: proc_alloc_inum()->proc_register()
- call: start_kernel()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
- __proc_create()
- kmalloc((ent->size=strlen(dest))+1)
- strcpy()
- proc_register()
- call: proc_register()
- proc_alloc_inum()
-
return: proc_alloc_inum()->proc_register()
-
proc_alloc_inum 에서 한일:
// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 1 개를 할당 받음 // // (&(&proc_inum_ida)->idr)->id_free 이 idr object new 2번을 가르킴 // | // |-> --------------------------------------------------------------------------------------------------------------------------- // | idr object new 2 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 | // --------------------------------------------------------------------------------------------------------------------------- // | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL | // --------------------------------------------------------------------------------------------------------------------------- // // (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 2) // (&(&proc_inum_ida)->idr)->id_free_cnt: 8 // // (&(&proc_inum_ida)->idr)->top: kmem_cache#21-oX (struct idr_layer) (idr object 8) // (&(&proc_inum_ida)->idr)->layers: 1 // (&(&proc_inum_ida)->idr)->id_free: (idr object new 0) // (&(&proc_inum_ida)->idr)->id_free_cnt: 7 // // (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 2 bit를 1로 set 수행 // (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 3 // // kmem_cache인 kmem_cache#21 에서 할당한 object인 kmem_cache#21-oX (idr object new 2) 의 memory 공간을 반환함 // // (kmem_cache#29-oX (struct proc_dir_entry))->low_ino: 0xF0000002
- call: proc_register()
- proc_alloc_inum()
// ARM10C 20160611
// parent: &proc_root, ent: kmem_cache#29-oX (struct proc_dir_entry)
static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
struct proc_dir_entry *tmp;
int ret;
// &dp->low_ino: &(kmem_cache#29-oX (struct proc_dir_entry))->low_ino
// proc_alloc_inum(&(kmem_cache#29-oX (struct proc_dir_entry))->low_ino): 0
ret = proc_alloc_inum(&dp->low_ino);
// ret: 0
// ret: 0
if (ret)
return ret;
// dp->mode: (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777,
// S_ISDIR(0120777): 0, S_ISLNK(0120777): 1
if (S_ISDIR(dp->mode)) {
dp->proc_fops = &proc_dir_operations;
dp->proc_iops = &proc_dir_inode_operations;
dir->nlink++;
// ARM10C 20160611
// parent: &proc_root, ent: kmem_cache#29-oX (struct proc_dir_entry)
static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
struct proc_dir_entry *tmp;
int ret;
// &dp->low_ino: &(kmem_cache#29-oX (struct proc_dir_entry))->low_ino
// proc_alloc_inum(&(kmem_cache#29-oX (struct proc_dir_entry))->low_ino): 0
ret = proc_alloc_inum(&dp->low_ino);
// ret: 0
// ret: 0
if (ret)
return ret;
// dp->mode: (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777,
// S_ISDIR(0120777): 0, S_ISLNK(0120777): 1
if (S_ISDIR(dp->mode)) {
dp->proc_fops = &proc_dir_operations;
dp->proc_iops = &proc_dir_inode_operations;
dir->nlink++;
} else if (S_ISLNK(dp->mode)) {
// dp->proc_iops: (kmem_cache#29-oX (struct proc_dir_entry))->proc_iops
dp->proc_iops = &proc_link_inode_operations;
// dp->proc_iops: (kmem_cache#29-oX (struct proc_dir_entry))->proc_iops: &proc_link_inode_operations
} else if (S_ISREG(dp->mode)) {
BUG_ON(dp->proc_fops == NULL);
dp->proc_iops = &proc_file_inode_operations;
} else {
WARN_ON(1);
return -EINVAL;
}
spin_lock(&proc_subdir_lock);
// spin_lock 에서 한일:
// &proc_subdir_lock 을 이용하여 spin lock 을 수행
// dir: &proc_root, dir->subdir: (&proc_root)->subdir: NULL
for (tmp = dir->subdir; tmp; tmp = tmp->next)
if (strcmp(tmp->name, dp->name) == 0) {
WARN(1, "proc_dir_entry '%s/%s' already registered\n",
dir->name, dp->name);
break;
}
// dp->next: (kmem_cache#29-oX (struct proc_dir_entry))->next, dir->subdir: (&proc_root)->subdir: NULL
dp->next = dir->subdir;
// dp->next: (kmem_cache#29-oX (struct proc_dir_entry))->next: NULL
// dp->parent: (kmem_cache#29-oX (struct proc_dir_entry))->parent, dir: &proc_root
dp->parent = dir;
// dp->parent: (kmem_cache#29-oX (struct proc_dir_entry))->parent: &proc_root
// dir->subdir: (&proc_root)->subdir, dp: kmem_cache#29-oX (struct proc_dir_entry)
dir->subdir = dp;
// dir->subdir: (&proc_root)->subdir: kmem_cache#29-oX (struct proc_dir_entry)
spin_unlock(&proc_subdir_lock);
// spin_unlock 에서 한일:
// &proc_subdir_lock 을 이용하여 spin unlock 을 수행
return 0;
// return 0
}
- S_ISDIR()
// ARM10C 20160611
// dp->mode: (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
- S_ISLNK()
// ARM10C 20160611
// S_IFMT: 00170000
// S_IFLNK: 0120000
// dp->mode: (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
- call: start_kernel()
- page_writeback_init()
- proc_root_init()
- call: call_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- call: proc_symlink()
// ARM10C 20160604
// "mounts", NULL, "self/mounts"
struct proc_dir_entry *proc_symlink(const char *name,
struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent;
// &parent, name: "mounts"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "mounts", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
ent = __proc_create(&parent, name,
(S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
// ent: kmem_cache#29-oX (struct proc_dir_entry)
// ent: kmem_cache#29-oX (struct proc_dir_entry)
if (ent) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data, dest: "self/mounts", strlen("self/mounts"): 11
// ent->size: (kmem_cache#29-oX (struct proc_dir_entry))->size: 11, GFP_KERNEL: 0xD0,
// kmalloc(12, GFP_KERNEL: 0xD0): kmem_cache#30-oX
ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
if (ent->data) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX, dest: "self/mounts"
// strcpy(kmem_cache#30-oX, "self/mounts"): kmem_cache#30-oX: "self/mounts"
strcpy((char*)ent->data,dest);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX: "self/mounts"
// parent: NULL, ent: kmem_cache#29-oX (struct proc_dir_entry),
// proc_register(NULL, kmem_cache#29-oX (struct proc_dir_entry)): 0
if (proc_register(parent, ent) < 0) {
kfree(ent->data);
kfree(ent);
ent = NULL;
}
- // proc_register 에서 한일:
// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 1 개를 할당 받음 // // (&(&proc_inum_ida)->idr)->id_free 이 idr object new 2번을 가르킴 // | // |-> --------------------------------------------------------------------------------------------------------------------------- // | idr object new 2 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 | // --------------------------------------------------------------------------------------------------------------------------- // | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL | // --------------------------------------------------------------------------------------------------------------------------- // // (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 2) // (&(&proc_inum_ida)->idr)->id_free_cnt: 8 // // (&(&proc_inum_ida)->idr)->top: kmem_cache#21-oX (struct idr_layer) (idr object 8) // (&(&proc_inum_ida)->idr)->layers: 1 // (&(&proc_inum_ida)->idr)->id_free: (idr object new 0) // (&(&proc_inum_ida)->idr)->id_free_cnt: 7 // // (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 2 bit를 1로 set 수행 // (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 3 // // kmem_cache인 kmem_cache#21 에서 할당한 object인 kmem_cache#21-oX (idr object new 2) 의 memory 공간을 반환함 // // (kmem_cache#29-oX (struct proc_dir_entry))->low_ino: 0xF0000002 // (kmem_cache#29-oX (struct proc_dir_entry))->proc_iops: &proc_link_inode_operations // (kmem_cache#29-oX (struct proc_dir_entry))->next: NULL // (kmem_cache#29-oX (struct proc_dir_entry))->parent: &proc_root // // (&proc_root)->subdir: kmem_cache#29-oX (struct proc_dir_entry)
// ARM10C 20160604
// "mounts", NULL, "self/mounts"
struct proc_dir_entry *proc_symlink(const char *name,
struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent;
// &parent, name: "mounts"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "mounts", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
ent = __proc_create(&parent, name,
(S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
// ent: kmem_cache#29-oX (struct proc_dir_entry)
// ent: kmem_cache#29-oX (struct proc_dir_entry)
if (ent) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data, dest: "self/mounts", strlen("self/mounts"): 11
// ent->size: (kmem_cache#29-oX (struct proc_dir_entry))->size: 11, GFP_KERNEL: 0xD0,
// kmalloc(12, GFP_KERNEL: 0xD0): kmem_cache#30-oX
ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
if (ent->data) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX, dest: "self/mounts"
// strcpy(kmem_cache#30-oX, "self/mounts"): kmem_cache#30-oX: "self/mounts"
strcpy((char*)ent->data,dest);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX: "self/mounts"
// parent: NULL, ent: kmem_cache#29-oX (struct proc_dir_entry),
// proc_register(NULL, kmem_cache#29-oX (struct proc_dir_entry)): 0
if (proc_register(parent, ent) < 0) {
kfree(ent->data);
kfree(ent);
ent = NULL;
}
} else {
kfree(ent);
ent = NULL;
}
}
// ent: kmem_cache#29-oX (struct proc_dir_entry)
return ent;
// return kmem_cache#29-oX (struct proc_dir_entry)
}
EXPORT_SYMBOL(proc_symlink);
- call: start_kernel()
- page_writeback_init()
- proc_root_init()
- call: proc_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- proc_symlink 에서 한일:
// struct proc_dir_entry 만큼 메모리를 할당 받음 kmem_cache#29-oX (struct proc_dir_entry) // // (kmem_cache#29-oX (struct proc_dir_entry))->name: "mounts" // (kmem_cache#29-oX (struct proc_dir_entry))->namelen: 6 // (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777 // (kmem_cache#29-oX (struct proc_dir_entry))->nlink: 1 // (&(kmem_cache#29-oX (struct proc_dir_entry))->count)->counter: 1 // &(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock을 이용한 spin lock 초기화 수행 // ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->raw_lock: { { 0 } } // ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->magic: 0xdead4ead // ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner: 0xffffffff // ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner_cpu: 0xffffffff // &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->next: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list // &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->prev: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list // // parent: &proc_root // // (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX: "self/mounts" // // idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 1 개를 할당 받음 // // (&(&proc_inum_ida)->idr)->id_free 이 idr object new 2번을 가르킴 // | // |-> --------------------------------------------------------------------------------------------------------------------------- // | idr object new 2 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 | // --------------------------------------------------------------------------------------------------------------------------- // | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL | // --------------------------------------------------------------------------------------------------------------------------- // // (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 2) // (&(&proc_inum_ida)->idr)->id_free_cnt: 8 // // (&(&proc_inum_ida)->idr)->top: kmem_cache#21-oX (struct idr_layer) (idr object 8) // (&(&proc_inum_ida)->idr)->layers: 1 // (&(&proc_inum_ida)->idr)->id_free: (idr object new 0) // (&(&proc_inum_ida)->idr)->id_free_cnt: 7 // // (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 2 bit를 1로 set 수행 // (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 3 // // kmem_cache인 kmem_cache#21 에서 할당한 object인 kmem_cache#21-oX (idr object new 2) 의 memory 공간을 반환함 // // (kmem_cache#29-oX (struct proc_dir_entry))->low_ino: 0xF0000002 // (kmem_cache#29-oX (struct proc_dir_entry))->proc_iops: &proc_link_inode_operations // (kmem_cache#29-oX (struct proc_dir_entry))->next: NULL // (kmem_cache#29-oX (struct proc_dir_entry))->parent: &proc_root // // (&proc_root)->subdir: kmem_cache#29-oX (struct proc_dir_entry)
// ARM10C 20160604
void __init proc_root_init(void)
{
int err;
proc_init_inodecache();
// proc_init_inodecache 에서 한일:
// struct proc_inode 크기 만큼의 메모리를 할당항는 kmem_cache 할당자를 생성함
// proc_inode_cachep: kmem_cache#n#28 (struct proc_inode)
// register_filesystem(&proc_fs_type): 0
err = register_filesystem(&proc_fs_type);
// err: 0
// register_filesystem에서 한일:
// (&bd_type)->next: &proc_fs_type
//
// file system 연결 결과
// file_systems: sysfs_fs_type -> rootfs_fs_type -> shmem_fs_type -> bd_type -> proc_fs_type
// err: 0
if (err)
return;
proc_self_init();
// proc_self_init 에서 한일:
// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 2 개를 할당 받음
//
// (&(&proc_inum_ida)->idr)->id_free 이 idr object new 1번을 가르킴
// |
// |-> ---------------------------------------------------------------------------------------------------------------------------
// | idr object new 1 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 |
// ---------------------------------------------------------------------------------------------------------------------------
// | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL |
// ---------------------------------------------------------------------------------------------------------------------------
//
// (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 1)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 8
//
// (&(&proc_inum_ida)->idr)->top: kmem_cache#21-oX (struct idr_layer) (idr object 8)
// (&(&proc_inum_ida)->idr)->layers: 1
// (&(&proc_inum_ida)->idr)->id_free: (idr object new 0)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 7
//
// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 1 bit를 1로 set 수행
// (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 2
//
// kmem_cache인 kmem_cache#21 에서 할당한 object인 kmem_cache#21-oX (idr object new 1) 의 memory 공간을 반환함
//
// self_inum: 0xF0000001
// proc_symlink("mounts", NULL, "self/mounts"): kmem_cache#29-oX (struct proc_dir_entry)
proc_symlink("mounts", NULL, "self/mounts");
proc_net_init();
- call: start_kernel()
- proc_root_init()
- call: proc_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- proc_net_init()
- call: proc_net_init()
#ifdef CONFIG_NET
extern int proc_net_init(void);
#else
static inline int proc_net_init(void) { return 0; }
#endif
int __init proc_net_init(void)
{
proc_symlink("net", NULL, "self/net");
return register_pernet_subsys(&proc_net_ns_ops);
}
- call: start_kernel()
- proc_root_init()
- call: proc_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- proc_net_init()
- call: proc_net_init()
- proc_symlink(): net, self/net
// ARM10C 20160604
// "mounts", NULL, "self/mounts"
struct proc_dir_entry *proc_symlink(const char *name,
struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent;
// &parent, name: "mounts"
// S_IFLNK: 0120000, S_IRUGO: 00444, S_IWUGO: 00222, S_IXUGO: 00111
// __proc_create(NULL, "mounts", 0120777, 1): kmem_cache#29-oX (struct proc_dir_entry)
ent = __proc_create(&parent, name,
(S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
// ent: kmem_cache#29-oX (struct proc_dir_entry)
// __proc_create 에서 한일:
// struct proc_dir_entry 만큼 메모리를 할당 받음 kmem_cache#29-oX (struct proc_dir_entry)
//
// (kmem_cache#29-oX (struct proc_dir_entry))->name: "mounts"
// (kmem_cache#29-oX (struct proc_dir_entry))->namelen: 6
// (kmem_cache#29-oX (struct proc_dir_entry))->mode: 0120777
// (kmem_cache#29-oX (struct proc_dir_entry))->nlink: 1
// (&(kmem_cache#29-oX (struct proc_dir_entry))->count)->counter: 1
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock을 이용한 spin lock 초기화 수행
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->raw_lock: { { 0 } }
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->magic: 0xdead4ead
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner: 0xffffffff
// ((&(kmem_cache#29-oX (struct proc_dir_entry))->pde_unload_lock)->rlock)->owner_cpu: 0xffffffff
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->next: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list
// &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list->prev: &(kmem_cache#29-oX (struct proc_dir_entry))->pde_openers->i_sb_list
//
// parent: &proc_root
// ent: kmem_cache#29-oX (struct proc_dir_entry)
if (ent) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data, dest: "self/mounts", strlen("self/mounts"): 11
// ent->size: (kmem_cache#29-oX (struct proc_dir_entry))->size: 11, GFP_KERNEL: 0xD0,
// kmalloc(12, GFP_KERNEL: 0xD0): kmem_cache#30-oX
ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX
if (ent->data) {
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX, dest: "self/mounts"
// strcpy(kmem_cache#30-oX, "self/mounts"): kmem_cache#30-oX: "self/mounts"
strcpy((char*)ent->data,dest);
// ent->data: (kmem_cache#29-oX (struct proc_dir_entry))->data: kmem_cache#30-oX: "self/mounts"
// parent: NULL, ent: kmem_cache#29-oX (struct proc_dir_entry),
// proc_register(NULL, kmem_cache#29-oX (struct proc_dir_entry)): 0
if (proc_register(parent, ent) < 0) {
kfree(ent->data);
kfree(ent);
ent = NULL;
}
// proc_register 에서 한일:
// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-oX를 1 개를 할당 받음
//
// (&(&proc_inum_ida)->idr)->id_free 이 idr object new 2번을 가르킴
// |
// |-> ---------------------------------------------------------------------------------------------------------------------------
// | idr object new 2 | idr object new 0 | idr object 6 | idr object 5 | .... | idr object 0 |
// ---------------------------------------------------------------------------------------------------------------------------
// | ary[0]: idr object new 0 | ary[0]: idr object 6 | ary[0]: idr object 5 | ary[0]: idr object 4 | .... | ary[0]: NULL |
// ---------------------------------------------------------------------------------------------------------------------------
//
// (&(&proc_inum_ida)->idr)->id_free: kmem_cache#21-oX (idr object new 2)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 8
//
// (&(&proc_inum_ida)->idr)->top: kmem_cache#21-oX (struct idr_layer) (idr object 8)
// (&(&proc_inum_ida)->idr)->layers: 1
// (&(&proc_inum_ida)->idr)->id_free: (idr object new 0)
// (&(&proc_inum_ida)->idr)->id_free_cnt: 7
//
// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 2 bit를 1로 set 수행
// (kmem_cache#27-oX (struct ida_bitmap))->nr_busy: 3
//
// kmem_cache인 kmem_cache#21 에서 할당한 object인 kmem_cache#21-oX (idr object new 2) 의 memory 공간을 반환함
//
// (kmem_cache#29-oX (struct proc_dir_entry))->low_ino: 0xF0000002
// (kmem_cache#29-oX (struct proc_dir_entry))->proc_iops: &proc_link_inode_operations
// (kmem_cache#29-oX (struct proc_dir_entry))->next: NULL
// (kmem_cache#29-oX (struct proc_dir_entry))->parent: &proc_root
//
// (&proc_root)->subdir: kmem_cache#29-oX (struct proc_dir_entry)
} else {
kfree(ent);
ent = NULL;
}
}
// ent: kmem_cache#29-oX (struct proc_dir_entry)
return ent;
// return kmem_cache#29-oX (struct proc_dir_entry)
}
EXPORT_SYMBOL(proc_symlink);
- call: start_kernel()
- proc_root_init()
- call: proc_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- proc_net_init()
- call: proc_net_init()
- proc_symlink(): net, self/net
- register_pernet_subsys()
- call: register_pernet_subsys()
int register_pernet_subsys(struct pernet_operations *ops)
{
int error;
mutex_lock(&net_mutex);
error = register_pernet_operations(first_device, ops);
mutex_unlock(&net_mutex);
return error;
}
EXPORT_SYMBOL_GPL(register_pernet_subsys);
- call: start_kernel()
- proc_root_init()
- call: proc_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- proc_net_init()
- call: proc_net_init()
- proc_symlink(): net, self/net
- register_pernet_subsys()
- call: register_pernet_subsys()
- mutex_lock()
- register_pernet_operations()
- call: register_pernet_operations()
static int register_pernet_operations(struct list_head *list,
struct pernet_operations *ops)
{
int error;
if (ops->id) {
again:
error = ida_get_new_above(&net_generic_ids, 1, ops->id);
if (error < 0) {
if (error == -EAGAIN) {
ida_pre_get(&net_generic_ids, GFP_KERNEL);
goto again;
}
return error;
}
max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id);
}
error = __register_pernet_operations(list, ops);
if (error) {
rcu_barrier();
if (ops->id)
ida_remove(&net_generic_ids, *ops->id);
}
return error;
}
- call: start_kernel()
- proc_root_init()
- call: proc_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- proc_net_init()
- call: proc_net_init()
- proc_symlink(): net, self/net
- register_pernet_subsys()
- call: register_pernet_subsys()
- mutex_lock()
- register_pernet_operations()
- call: register_pernet_operations()
#ifdef CONFIG_NET_NS
static int __register_pernet_operations(struct list_head *list,
struct pernet_operations *ops)
{
struct net *net;
int error;
LIST_HEAD(net_exit_list);
list_add_tail(&ops->list, list);
if (ops->init || (ops->id && ops->size)) {
for_each_net(net) {
error = ops_init(ops, net);
if (error)
goto out_undo;
list_add_tail(&net->exit_list, &net_exit_list);
}
}
return 0;
out_undo:
/* If I have an error cleanup all namespaces I initialized */
list_del(&ops->list);
ops_exit_list(ops, &net_exit_list);
ops_free_list(ops, &net_exit_list);
return error;
}
- call: start_kernel()
- proc_root_init()
- call: proc_root_init()
- proc_init_inodecache()
- register_filesystem(&proc_fs_type)
- proc_self_init()
- proc_symlink()
- proc_net_init()
- call: proc_net_init()
- proc_symlink(): net, self/net
- register_pernet_subsys()
- call: register_pernet_subsys()
- mutex_lock()
- register_pernet_operations()
- call: register_pernet_operations()
- ida_get_new_above()
- __register_pernet_operaitions()
- return: register_pernet_subsys()
int register_pernet_subsys(struct pernet_operations *ops)
{
int error;
mutex_lock(&net_mutex);
error = register_pernet_operations(first_device, ops);
mutex_unlock(&net_mutex);
return error;
}
EXPORT_SYMBOL_GPL(register_pernet_subsys);
- 1st
3b41bb2..540aca8 master -> origin/master
Updating 3b41bb2..540aca8
Fast-forward
fs/proc/generic.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
fs/proc/internal.h | 1 +
fs/proc/root.c | 52 ++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 1 +
include/linux/gfp.h | 1 +
include/linux/idr.h | 16 +++++++++++
include/linux/list.h | 2 ++
include/linux/slab.h | 2 ++
include/linux/spinlock.h | 4 +++
include/uapi/linux/stat.h | 8 ++++++
lib/idr.c | 4 +++
11 files changed, 289 insertions(+), 12 deletions(-)
- 2nd
540aca8..a562949 master -> origin/master
Updating 540aca8..a562949
Fast-forward
drivers/of/base.c | 34 +++++++++++++++++++++
fs/proc/generic.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
fs/proc/internal.h | 8 +++--
fs/proc/proc_devtree.c | 54 ++++++++++++++++++++++++++++++++-
fs/proc/proc_net.c | 59 ++++++++++++++++++++++++++++++++++++
fs/proc/proc_sysctl.c | 58 ++++++++++++++++++++++++++++++++++++
fs/proc/proc_tty.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/proc/root.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
include/linux/kernel.h | 1 +
include/linux/list.h | 11 +++++++
include/linux/mutex.h | 18 +++++++++++
include/linux/of.h | 10 +++++--
include/linux/proc_fs.h | 58 ++++++++++++++++++++++++++++++++++++
include/linux/spinlock.h | 4 +++
include/linux/stat.h | 9 ++++++
include/linux/sysctl.h | 5 ++++
include/net/net_namespace.h | 32 +++++++++++++-------
include/uapi/linux/stat.h | 11 +++++++
kernel/locking/mutex.c | 2 ++
kernel/sysctl.c | 3 ++
lib/string.c | 1 +
net/core/net_namespace.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++-
22 files changed, 1188 insertions(+), 23 deletions(-)