进程和进程的内核堆栈 令 Linux为每个进程分配一个8KB大小的内存区域 用于存放该进程两个不同的数据结构: Thread info ≯进程的内核堆栈 进程处于内核态时使用 Ox015fofff 不同于用户态堆栈 STACK 内核控制路径所用的堆栈 很少,因此对栈和 Thread info 08x015f00 来说,8KB足够了 0x015fa3cb Thread info 2021/2/6 Linux操作系统分析 0x015fa000
2021/2/6 Linux操作系统分析 18/65 进程和进程的内核堆栈 ❖Linux为每个进程分配一个8KB大小的内存区域 ,用于存放该进程两个不同的数据结构: ➢Thread_info ➢进程的内核堆栈 进程处于内核态时使用, 不同于用户态堆栈 内核控制路径所用的堆栈 很少,因此对栈和Thread_info 来说,8KB足够了 Thread_info
Thread union 令C语言允许用如下的一个 union结构来方便的表示 这样的一个混合体 01669: union thread union include/linux/sched.h 01670 struct thread info thread info 01671: unsigned long stack[THREAD_SIZE/sizeof(long)] 01672: 00055: #ifdef CONFIG 4KSTACKs 00056: #define THREAD SIZE 4096 00057:#else 00058:#define THREAD_SIZE(8192) 00059: # endif thread info由体系结构相关部分定义 阅读 includelasm-x86/ thread info h 以及 includelasn-x86/ thread info_32h 2021/2/6 Linux操作系统分析 嵌入式系统实验室 19/65 EM日 EDDED SYSTEM LA日口 RATORY
2021/2/6 Linux操作系统分析 19/65 Thread_union ❖C语言允许用如下的一个union结构来方便的表示 这样的一个混合体 thread_info由体系结构相关部分定义 阅读include/asm-x86/thread_info.h 以及include/asm-x86/thread_info_32.h include/linux/sched.h
◆进程描述符的分配/回收访问 00088: #ifndef HAVE ARCH TASK STRUCT ALLOCATOR 90:#define free_task_struct(tsk)kmem_cache_free(task- struct_ cache /tsk/y/ 00089:#define alloc_task_struct() kmem_cache_ alloc(task_struct_cache, GFP_KERNE 0091: static struct kmem_ cache*task_struct_cache 0002:2#endf 令 Thread info的分配/回收/访问 >alloc thread info free thread info 2021/2/6 Linux操作系统分析 20/65 嵌入式系统实验室 EM日 EDDED SYSTEM LA日口 RATORY
2021/2/6 Linux操作系统分析 20/65 ❖进程描述符的分配/回收/访问 ❖Thread_info的分配/回收/访问 ➢alloc_thread_info ➢free_thread_info
00096:/*thread information allocation * 00097: #ifdef CONFIG_DEBUG_STACK_USAGE 00098: #define alloc_thread_info(tsk)((struct thread_info get_free_pages(GFP_KERNEL I__GFP_ZERO, get_order(THREAD_SIZE) 00100:#else 00101: #define alloc_thread_info(tsk(struct thread info *) 00102: get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE))) 00103:#endf 00034: void free thread info(struct thread info *ti 00035 00036 free_thread_xstate(ti->task) 00037 free_pages((unsigned long)ti, get_order (THREAD_SIZE)) 00038: 2021/2/6 Linux操作系统分析 2165 嵌入式系统实验室 EM日 EDDED SYSTEM LA日口 RATORY
2021/2/6 Linux操作系统分析 21/65
current thread info 令从刚才看到的 thread info和内核态堆栈之间的配 对,内核可以很容易的从esp寄存器的值获得当 前在CPU上运行的进程的描述符指针 令因为这个内存区是8KB=213大小,内核必须做的 就是让esp有13位的有效位,以获得进程描述符 /k how to get the current stack pointer from C*/ register unsigned long current_stack_pointer asm("esp")_used /k how to get the thread information struct from C * static inline struct thread_info *current_ thread_info(void) return(struct thread info (current_stack_pointer &w(THREAD_SIZE 8191=8192-1=0x2000-1=0x1仟f 2021/2/6 Liux操作系取反:0xffe000(最后13位为0)
2021/2/6 Linux操作系统分析 22/65 current_thread_info ❖从刚才看到的thread_info和内核态堆栈之间的配 对,内核可以很容易的从esp寄存器的值获得当 前在CPU上运行的进程的描述符指针 ❖因为这个内存区是8KB=213大小,内核必须做的 就是让esp有13位的有效位,以获得进程描述符 的基地址 8191=8192-1=0x2000-1=0x1fff 取反:0xffffe000(最后13位为0)