//数学协处理器使用的结构,主要用于保存进程切换时i387的执行状态信息 struct i387_struct { long cwd; // 控制字(Control word) long swd; // 状态字(Status word) long twd; // 标记字(Tag word) long fip; // 协处理器代码指针 long fcs; // 协处理器代码段寄存器 long foo; long fos; long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ };
struct tss_struct { long back_link; /* 16 high bits zero */ long esp0; long ss0; /* 16 high bits zero */ long esp1; long ss1; /* 16 high bits zero */ long esp2; long ss2; /* 16 high bits zero */ long cr3; long eip; long eflags; long eax,ecx,edx,ebx; long esp; long ebp; long esi; long edi; long es; /* 16 high bits zero */ long cs; /* 16 high bits zero */ long ss; /* 16 high bits zero */ long ds; /* 16 high bits zero */ long fs; /* 16 high bits zero */ long gs; /* 16 high bits zero */ long ldt; /* 16 high bits zero */ long trace_bitmap; /* bits: trace 0, bitmap 16-31 */ struct i387_struct i387; };
setup_gdt: lgdt gdt_descr # 加载全局描述符表寄存器(内容已设置好) ret
gdt_descr: .word 256*8-1 # so does gdt(not that that's any .long _gdt # magic number, but it works for me :^) .align 3 _gdt: .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x00c09a0000000fff /* 16Mb */ .quad 0x00c0920000000fff /* 16Mb */ .quad 0x0000000000000000 /* TEMPORARY - don't use */ .fill 252,8,0/* space for LDT's and TSS's etc */
#if (((TASK_SIZE>>16)*NR_TASKS) != 0x10000) #error "TASK_SIZE*NR_TASKS must be 4GB"// 任务长度*任务总个数必须为 4GB #endif
...
//任务(进程)数据结构 !!! struct task_struct { /* these are hardcoded - don't touch */ long state; /* 任务的运行状态(-1 不可运行,0 可运行(就绪),>0 已停止) */ long counter;/* 运行时间片,每经过一次时钟中断, counter就会减去1*/ long priority;/* 运行优先数,任务开始运行时counter = priority,越大运行越长 */ long signal;//信号位图 struct sigaction sigaction[32];//信号执行属性结构,对应信号将要执行的操作和标志信息 long blocked; /* bitmap of masked signals */ /* various fields */ int exit_code; //任务执行停止的退出码 unsigned long start_code,end_code,end_data,brk,start_stack; // unsigned long start_code 代码段地址。 // unsigned long end_code 代码长度(字节数)。 // unsigned long end_data 代码长度 + 数据长度(字节数)。 // unsigned long brk 总长度(字节数)。 // unsigned long start_stack 堆栈段地址 long pid,pgrp,session,leader; // long pid 进程标识号(进程号)!!! // long pgrp 进程组号。 // long session 会话号。 // long leader 会话leader
int groups[NGROUPS];//进程所属组号。一个进程可以属于多个组 /* * pointers to parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with * p->p_pptr->pid) */ struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr; // task_struct *p_pptr 指向父进程的指针。 // task_struct *p_cptr 指向最新子进程的指针。 // task_struct *p_ysptr 指向比自己后创建的相邻进程的指针。 // task_struct *p_osptr 指向比自己早创建的相邻进程的指针 unsigned short uid,euid,suid; // unsigned short uid 用户标识号(用户 id)。 // unsigned short euid 有效用户 id。 // unsigned short suid 保存的用户 id unsigned short gid,egid,sgid; // unsigned short gid 组标识号(组 id)。 // unsigned short egid 有效组 id。 // unsigned short sgid 保存的组 id。 unsigned long timeout,alarm; // long timeout 内核定时超时值。 // long alarm 报警定时值(滴答数) long utime,stime,cutime,cstime,start_time; // long utime 用户态运行时间(滴答数)。 // long stime 系统态运行时间(滴答数)。 // long cutime 子进程用户态运行时间。 // long cstime 子进程系统态运行时间。 // long start_time 进程开始运行时刻。 struct rlimit rlim[RLIM_NLIMITS]; //进程资源使用统计数组
unsigned int flags; /* 各进程的标志*/ unsigned short used_math; //标志:是否使用了协处理器 /* file system info */ int tty; /* 进程使用 tty 终端的子设备号。必须设置;-1 表示没有使用*/ unsigned short umask; //文件创建属性屏蔽位 struct m_inode * pwd; //当前工作目录 i 节点结构指针 struct m_inode * root; //根目录 i 节点结构指针 struct m_inode * executable; //执行文件 i 节点结构指针 struct m_inode * library; //被加载库文件 i 节点结构指针 unsigned long close_on_exec; //执行时关闭文件句柄位图标志。(参见 include/fcntl.h) struct file * filp[NR_OPEN]; //文件结构指针表,最多 32 项。表项号即是文件描述符的值。 /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */ struct desc_struct ldt[3]; //局部描述符表。0-空,1-代码段 cs,2-数据段和堆栈段 ds&ss !!! /* tss for this task */ struct tss_struct tss; //进程的任务状态段信息结构 };