linux 2.6源代码情景分析笔记之进程2
能被独立调度的每个执行上下文都必须拥有自己的进程描述符。进程和进程描述符之间有严格的对应关系,使用32位进程描述符地址标识,进程描述符指针指向这些地址,内核对进程的大部分引用是通过进程描述符指针进行的。
可以使用pid(进程标识符)来标记进程,存放在字段pid中,PID被顺序编号,新创建的进程PID通常是前一个进程的PID加一。
#define PID_MAX_DEFAULT 0x8000
一个线程租中的所有线程使用和该线程组的领头线程(thread group leader)相同的PID,也就是该组中第一个轻量级进程的PID,被存入进程描述符的tgid字段中。getpid()系统调用返回当前进程的tgid值而不是pid的值,因此一个多线程应用的所有线程共享相同的PID。绝大多数进程都属于一个线程组,包含单一的成员;线程组领头线程其tgid的值与pid的相同,因而getpid()系统调用对这类进程所其的作用和一般进程是一样的。
对每个进程来说,linux把两个不同的数据结构紧凑地存放在一个单独为进程分配的存储区域内:一个内核态的进程堆栈,另一个是紧挨进程描述符的小数据结构thread_info,叫做线程描述符,这块存储区域的大小通常为8192个字节(两个页框)。内核让这8k空间占据连续的两个页框并让第一个页框的起始地址是2^13的倍数。当几乎没有可用的动态内存空间时,就会很难找到这样的两个连续页框,因为空闲空间可能存在大量碎片。内核态的进程访问处于内核数据段的栈,这个栈不同于用户态的进程所用的栈。因为内核控制路径使用很少的栈,因此只需要几千个字节的内核态堆栈。使用task和thread_info字段使thread_info结构与task_struct结构互相关联。
esp寄存器是cpu栈指针,用来存放栈顶单元的地址。栈起始于末端,并朝这个内存区开始的方向增长。从用户态刚切换到内核态之后,进程的内核栈总是空的,因此,esp寄存器指向这个栈的顶端。一旦数据写入堆栈,esp的数值就递减。(thread_info结构是52个字节长)
union thread_union {
struct thread_info thread_info;
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
使用以上联合结构表示一个进程的线程描述符和内核栈。
struct thread_info {
struct task_struct *task; /* main task struct
相关文档:
Service Discovery Protocol(SDP)提供一种能力,让应用程序有方法发现哪种服务可用以及这种服务的特性。
服务发现协议(SDP或Bluetooth SDP)在蓝牙协议栈中对蓝牙环境中的应用程序有特殊的含意,发现哪个服务是可用的和确定这些可用服务的特征。SDP定义了bluetooth client发现可用bluetooth server服务和它们的特征的方法。 ......
VMwar ......
最开始时,ram芯片中包含的是随机数据。当开始启动时,cpu的一个引脚上会产生一个reset逻辑值。此后处理器的一些寄存器设置成固定的数值,并执行在物理地址0xfffffff0处找到的代码。硬件把这个地址映射到某个只读、持久的存储芯片中,该芯片通常称为rom(read-only memory只读内存)。rom所存放的程序集在80x86体系中通常叫做 ......
由于Linux不是中国人开发的,开发过程中也不是以中文为母语,虽有中文语言包,在软件兼容性上出现中文乱码也在所难免。我抽取网络上前人的经验,结合自己的理解,将他们加以总结,希望对后来者有所帮助。
1、html文件乱码;
&nbs ......
linux/arch/i386/boot/compressed/head.S
在setup()结束后,此函数就被移动到物理地址0x00100000处或者0x00001000处,这取决于内核映像是被高装载到ram中还是低装载到ram中。
解读函数:
startup_32:
cld
cli
&n ......