进程和进程的内核堆栈 Linux为每个进程分配一个8KB大小的内存区域 ,用于存放该进程两个不同的数据结构: >Thread info >进程的内核堆栈 进程处于内核态时使用, 0x015fbfff 不同于用户态堆栈 STACK 内核控制路径所用的堆栈 很少,因此对栈和Thread info 0x0156000 来说,8KB足够了 0x015B878 esp- Cience an 0x015B3b Thread info 2023/7/14 Linux操作系统分析 0x015fa000
2023/7/14 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由体系结构相关部分定义 阅读include/asm-x86/thread_info.h Ence and Technoly 以及include/asm-x86/thread_info32.h 嵌入式系统实验室 2023/7/14 Linux操作系统分析 19/65 EMBEDDED SYSTEM LABORATORY SUZHOU INSTITUTE FON ADVANCED STUDY OF USTC
2023/7/14 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 00089:define alloc_task_struct()kmem_cache_alloc(task_struct_cachep,GFP_KERNEL 00090:#define free_task_struct(tsk)kmem_cache_free(task_struct_cachep,(tsk)) 00091:static struct kmem cache *task_struct_cachep; 00092:#endif cience and Technol Thread info的分配/回收/访问 >alloc thread info >free thread info 嵌入式系统实验室 2023/7/14 Linux操作系统分析 20/65 EMBEDDED SYSTEM LABORATORY SUZHOU INSTITUTE FON ADVANCED STUDY OF USTC
2023/7/14 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 * 00099: get_free_pages(GFP_KERNELGFP_ZERO,get_order(THREAD_SIZE)) 00100:#ese 00101:#define alloc_thread_info(tsk)((struct thread_info * 00102: get_free_pages(GFP_KERNEL,get_order(THREAD_SIZE))) 00103:#endi 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: 2023/7/14 Linux操作系统分析 21/65 嵌入式系统实验室 EMBEDDED SYSTEM LABORATORY SUZHOU INSTITUTE FON ADVANCED STUDY OF USTC
2023/7/14 Linux操作系统分析 21/65
current thread info 从刚才看到的thread info和内核态堆栈之间的配 对,内核可以很容易的从esp寄存器的值获得当 前在CPU上运行的进程的描述符指针 因为这个内存区是8KB=213大小,内核必须做的 就是让esp有13位的有效位,以获得进程描述符 /how to get the current stack pointer from C * register unsigned long current_stack_pointer asm("esp")__used; /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 &~(THREAD_SIZE-1)); ence 8191=8192-1=0x2000-1=0x1ff 2023/7/14 Linux操作系: 取反:0xfe000(最后13位为0)
2023/7/14 Linux操作系统分析 22/65 current_thread_info ❖从刚才看到的thread_info和内核态堆栈之间的配 对,内核可以很容易的从esp寄存器的值获得当 前在CPU上运行的进程的描述符指针 ❖因为这个内存区是8KB=213大小,内核必须做的 就是让esp有13位的有效位,以获得进程描述符 的基地址 8191=8192-1=0x2000-1=0x1fff 取反:0xffffe000(最后13位为0)