����14-26 linux/include/linux/sched.h
1 #ifndef _SCHED_H
2 #define _SCHED_H
3
4 #define HZ 100 // ����ϵͳʱ�ӵδ�Ƶ��(1�ٺ��ȣ�ÿ���δ�10ms)
5
6 #define NR_TASKS 64 // ϵͳ��ͬʱ��������̣�����
7 #define TASK_SIZE 0x04000000 // ÿ������ij��ȣ�64MB����
8 #define LIBRARY_SIZE 0x00400000 // ��̬���ؿⳤ�ȣ�4MB����
9
10 #if (TASK_SIZE & 0x3fffff)
11 #error "TASK_SIZE must be multiple of 4M" // ���ȱ�����4MB�ı�����
12 #endif
13
14 #if (LIBRARY_SIZE & 0x3fffff)
15 #error "LIBRARY_SIZE must be a multiple of 4M" // �ⳤ��Ҳ������4MB�ı�����
16 #endif
17
18 #if (LIBRARY_SIZE >= (TASK_SIZE/2))
19 #error "LIBRARY_SIZE too damn big!" // ���ؿ�ij��Ȳ��ô������ȵ�һ�롣
20 #endif
21
22 #if (((TASK_SIZE>>16)*NR_TASKS) != 0x10000)
23 #error "TASK_SIZE*NR_TASKS must be 4GB" // ����*�����ܸ�������Ϊ4GB��
24 #endif
25
// �ڽ�������ַ�ռ��ж�̬�ⱻ���ص�λ�ã�60MB������
26 #define LIBRARY_OFFSET (TASK_SIZE - LIBRARY_SIZE)
27
// �����CT_TO_SECS ��CT_TO_USECS���ڰ�ϵͳ��ǰ�����ת��������ֵ����ֵ��ʾ��
28 #define CT_TO_SECS(x) ((x) / HZ)
29 #define CT_TO_USECS(x) (((x) % HZ) * 1000000/HZ)
30
31 #define FIRST_TASK task[0] // ����0�Ƚ����⣬�������������������һ�����š�
32 #define LAST_TASK task[NR_TASKS-1] // ���������е����һ������
33
34 #include <linux/head.h>
35 #include <linux/fs.h>
36 #include <linux/mm.h>
37 #include <sys/param.h>
38 #include <sys/time.h>
39 #include <sys/resource.h>
40 #include <signal.h>
41
42 #if (NR_OPEN > 32)
43 #error "Currently the close-on-exec-flags and select masks are in one long, max 32 files/proc"
44 #endif
45
// ���ﶨ���˽�������ʱ���ܴ���״̬��
46 #define TASK_RUNNING 0 // ���������������������
47 #define TASK_INTERRUPTIBLE 1 // ���̴��ڿ��жϵȴ�״̬��
48 #define TASK_UNINTERRUPTIBLE 2 // ���̴��ڲ����жϵȴ�״̬����Ҫ����I/O�����ȴ���
49 #define TASK_ZOMBIE 3 // ���̴��ڽ���״̬���Ѿ�ֹͣ���У��������̻�û���źš�
50 #define TASK_STOPPED 4 // ������ֹͣ��
51
52 #ifndef NULL
53 #define NULL ((void *) 0) // ����NULLΪ��ָ�롣
54 #endif
55
// ���ƽ��̵�ҳĿ¼ҳ����Linus��Ϊ�����ں�����ӵĺ���֮һ��( mm/memory.c, 105 )
56 extern int copy_page_tables(unsigned long from, unsigned long to, long size);
// �ͷ�ҳ����ָ�����ڴ�鼰ҳ��������( mm/memory.c, 150 )
57 extern int free_page_tables(unsigned long from, unsigned long size);
58
// ���ȳ���ij�ʼ��������( kernel/sched.c, 385 )
59 extern void sched_init(void);
// ���̵��Ⱥ�����( kernel/sched.c, 104 )
60 extern void schedule(void);
// �쳣(����)�жϴ�����ʼ�������������жϵ����Ų������ж������źš�( kernel/traps.c, 181 )
61 extern void trap_init(void);
// ��ʾ�ں˳�����Ϣ��Ȼ�������ѭ����( kernel/panic.c, 16 )��
62 extern void panic(const char * str);
// ��tty��дָ�����ȵ��ַ�����( kernel/chr_drv/tty_io.c, 290 )��
63 extern int tty_write(unsigned minor,char * buf,int count);
64
65 typedef int (*fn_ptr)(); // ���庯��ָ�����͡�
66
// ��������ѧЭ������ʹ�õĽṹ����Ҫ���ڱ�������л�ʱi387��ִ��״̬��Ϣ��
67 struct i387_struct {
68 long cwd; // ������(Control word)��
69 long swd; // ״̬��(Status word)��
70 long twd; // �����(Tag word)��
71 long fip; // Э����������ָ�롣
72 long fcs; // Э����������μĴ�����
73 long foo; // �ڴ��������ƫ��λ�á�
74 long fos; // �ڴ�������Ķ�ֵ��
75 long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
76 }; /* 8��10�ֽڵ�Э�������ۼ�����*/
77
// ����״̬�����ݽṹ��
78 struct tss_struct {
79 long back_link; /* 16 high bits zero */
80 long esp0;
81 long ss0; /* 16 high bits zero */
82 long esp1;
83 long ss1; /* 16 high bits zero */
84 long esp2;
85 long ss2; /* 16 high bits zero */
86 long cr3;
87 long eip;
88 long eflags;
89 long eax,ecx,edx,ebx;
90 long esp;
91 long ebp;
92 long esi;
93 long edi;
94 long es; /* 16 high bits zero */
95 long cs; /* 16 high bits zero */
96 long ss; /* 16 high bits zero */
97 long ds; /* 16 high bits zero */
98 long fs; /* 16 high bits zero */
99 long gs; /* 16 high bits zero */
100 long ldt; /* 16 high bits zero */
101 long trace_bitmap; /* bits: trace 0, bitmap 16-31 */
102 struct i387_struct i387;
103 };
104
// �����������̣����ݽṹ�����Ϊ������������
// long state ���������״̬��-1�������У�0������(����)��>0��ֹͣ����
// long counter ��������ʱ�����(�ݼ�)���δ�����������ʱ��Ƭ��
// long priority ������������ʼ����ʱcounter=priority��Խ������Խ����
// long signal �ź�λͼ��ÿ������λ����һ���źţ��ź�ֵ=λƫ��ֵ+1��
// struct sigaction sigaction[32] �ź�ִ�����Խṹ����Ӧ�źŽ�Ҫִ�еIJ����ͱ�־��Ϣ��
// long blocked �����ź������루��Ӧ�ź�λͼ����
// -------------------
// int exit_code ����ִ��ֹͣ���˳��룬�丸���̻�ȡ��
// unsigned long start_code ����ε�ַ��
// unsigned long end_code ���볤�ȣ��ֽ�������
// unsigned long end_data ���볤�� + ���ݳ��ȣ��ֽ�������
// unsigned long brk �ܳ��ȣ��ֽ�������
// unsigned long start_stack ��ջ�ε�ַ��
// long pid ���̱�ʶ��(���̺�)��
// long pgrp ������š�
// long session �Ự�š�
// long leader �Ự���졣
// int groups[NGROUPS] ����������š�һ�����̿����ڶ���顣
// task_struct *p_pptr ָ���̵�ָ�롣
// task_struct *p_cptr ָ�������ӽ��̵�ָ�롣
// task_struct *p_ysptr ָ����Լ��������ڽ��̵�ָ�롣
// task_struct *p_osptr ָ����Լ��紴�������ڽ��̵�ָ�롣
// unsigned short uid �û���ʶ�ţ��û�id����
// unsigned short euid ��Ч�û�id��
// unsigned short suid ������û�id��
// unsigned short gid ���ʶ�ţ���id����
// unsigned short egid ����id��
// unsigned short sgid �������id��
// long timeout �ں˶�ʱ��ʱֵ��
// long alarm ������ʱֵ���δ�������
// long utime �û�̬����ʱ�䣨�δ�������
// long stime ϵͳ̬����ʱ�䣨�δ�������
// long cutime �ӽ����û�̬����ʱ�䡣
// long cstime �ӽ���ϵͳ̬����ʱ�䡣
// long start_time ���̿�ʼ����ʱ�̡�
// struct rlimit rlim[RLIM_NLIMITS] ������Դʹ��ͳ�����顣
// unsigned int flags; �����̵ı�־���������149�п�ʼ���壨��δʹ�ã���
// unsigned short used_math ��־���Ƿ�ʹ����Э��������
// ------------------------
// 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�����ż����ļ���������ֵ��
// struct desc_struct ldt[3] �ֲ�����������0-�գ�1-�����cs��2-���ݺͶ�ջ��ds&ss��
// struct tss_struct tss ���̵�����״̬����Ϣ�ṹ��
// ======================================
105 struct task_struct {
106 /* these are hardcoded - don't touch */
107 long state; /* -1 unrunnable, 0 runnable, >0 stopped */
108 long counter;
109 long priority;
110 long signal;
111 struct sigaction sigaction[32];
112 long blocked; /* bitmap of masked signals */
113 /* various fields */
114 int exit_code;
115 unsigned long start_code,end_code,end_data,brk,start_stack;
116 long pid,pgrp,session,leader;
117 int groups[NGROUPS];
118 /*
119 * pointers to parent process, youngest child, younger sibling,
120 * older sibling, respectively. (p->father can be replaced with
121 * p->p_pptr->pid)
122 */
123 struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
124 unsigned short uid,euid,suid;
125 unsigned short gid,egid,sgid;
126 unsigned long timeout,alarm;
127 long utime,stime,cutime,cstime,start_time;
128 struct rlimit rlim[RLIM_NLIMITS];
129 unsigned int flags; /* per process flags, defined below */
130 unsigned short used_math;
131 /* file system info */
132 int tty; /* -1 if no tty, so it must be signed */
133 unsigned short umask;
134 struct m_inode * pwd;
135 struct m_inode * root;
136 struct m_inode * executable;
137 struct m_inode * library;
138 unsigned long close_on_exec;
139 struct file * filp[NR_OPEN];
140 /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
141 struct desc_struct ldt[3];
142 /* tss for this task */
143 struct tss_struct tss;
144 };
145
146 /*
147 * Per process flags
148 */
/* ÿ�����̵ı�־ */ /* ��ӡ���뾯����Ϣ����δʵ�֣�������486 */
149 #define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */
150 /* Not implemented yet, only for 486*/
151
152 /*
153 * INIT_TASK is used to set up the first task table, touch at
154 * your own risk!. Base=0, limit=0x9ffff (=640kB)
155 */
/*
* INIT_TASK�������õ�1��������������ģ������Ը�J��
* ��ַBase = 0���γ�limit = 0x9ffff��=640kB����
*/
// ��Ӧ��������ṹ�ĵ�1���������Ϣ��
156 #define INIT_TASK \
157 /* state etc */ { 0,15,15, \ // state, counter, priority
158 /* signals */ 0,{{},},0, \ // signal, sigaction[32], blocked
159 /* ec,brk... */ 0,0,0,0,0,0, \ // exit_code,start_code,end_code,end_data,brk,start_stack
160 /* pid etc.. */ 0,0,0,0, \ // pid, pgrp, session, leader
161 /* suppl grps*/ {NOGROUP,}, \ // groups[]
162 /* proc links*/ &init_task.task,0,0,0, \ // p_pptr, p_cptr, p_ysptr, p_osptr
163 /* uid etc */ 0,0,0,0,0,0, \ // uid, euid, suid, gid, egid, sgid
164 /* timeout */ 0,0,0,0,0,0,0, \ // alarm,utime,stime,cutime,cstime,start_time,used_math
165 /* rlimits */ { {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \
166 {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \
167 {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}}, \
168 /* flags */ 0, \ // flags
169 /* math */ 0, \ // used_math, tty,umask,pwd,root,executable,close_on_exec
170 /* fs info */ -1,0022,NULL,NULL,NULL,NULL,0, \
171 /* filp */ {NULL,}, \ // filp[20]
172 { \ // ldt[3]
173 {0,0}, \
174 /* ldt */ {0x9f,0xc0fa00}, \ // ���볤640K����ַ0x0��G=1��D=1��DPL=3��P=1 TYPE=0xa
175 {0x9f,0xc0f200}, \ // ���ݳ�640K����ַ0x0��G=1��D=1��DPL=3��P=1 TYPE=0x2
176 }, \
177 /*tss*/ {0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&pg_dir,\ // tss
178 0,0,0,0,0,0,0,0, \
179 0,0,0x17,0x17,0x17,0x17,0x17,0x17, \
180 _LDT(0),0x80000000, \
181 {} \
182 }, \
183 }
184
185 extern struct task_struct *task[NR_TASKS]; // ����ָ�����顣
186 extern struct task_struct *last_task_used_math; // ��һ��ʹ�ù�Э�������Ľ��̡�
187 extern struct task_struct *current; // ��ǰ���н��̽ṹָ�������
188 extern unsigned long volatile jiffies; // �ӿ�����ʼ����ĵδ�����10ms/�δ𣩡�
189 extern unsigned long startup_time; // ����ʱ�䡣��1970:0:0:0��ʼ��ʱ��������
190 extern int jiffies_offset; // �����ۼ���Ҫ������ʱ���������
191
192 #define CURRENT_TIME (startup_time+(jiffies+jiffies_offset)/HZ) // ��ǰʱ�䣨��������
193
// ���Ӷ�ʱ����������ʱʱ��jiffies�δ�������ʱ��ʱ���ú���*fn()����( kernel/sched.c )
194 extern void add_timer(long jiffies, void (*fn)(void));
// �����жϵĵȴ�˯�ߡ�( kernel/sched.c )
195 extern void sleep_on(struct task_struct ** p);
// ���жϵĵȴ�˯�ߡ�( kernel/sched.c )
196 extern void interruptible_sleep_on(struct task_struct ** p);
// ��ȷ����˯�ߵĽ��̡�( kernel/sched.c )
197 extern void wake_up(struct task_struct ** p);
// ��鵱ǰ�����Ƿ���ָ�����û���grp�С�
198 extern int in_group_p(gid_t grp);
199
200 /*
201 * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall
202 * 4-TSS0, 5-LDT0, 6-TSS1 etc ...
203 */
/*
* Ѱ�ҵ�1��TSS��ȫ�ֱ��е���ڡ�0-û����nul��1-�����cs��2-���ݶ�ds��3-ϵͳ��syscall
* 4-����״̬��TSS0��5-�ֲ���LTD0��6-����״̬��TSS1���ȡ�
*/
// �Ӹ�Ӣ��ע�Ϳ��Բ��뵽��Linus��ʱ�����ϵͳ���õĴ���ר�ŷ���GDT���е�4�������Ķ��С�
// ��������û�������������Ǿ�һֱ��GDT���е�4�������������syscall�������һ�ԡ�
// ���涨��꣺ȫ�ֱ��е�1������״̬��(TSS)��������ѡ��������š�
204 #define FIRST_TSS_ENTRY 4
// ȫ�ֱ��е�1���ֲ���������(LDT)��������ѡ��������š�
205 #define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
// �궨�壬������ȫ�ֱ��е�n�������TSS����������ѡ���ֵ��ƫ��������
// ��ÿ��������ռ8�ֽڣ����FIRST_TSS_ENTRY<<3 ��ʾ����������GDT���е���ʼƫ��λ�á�
// ��Ϊÿ������ʹ��1��TSS��1��LDT����������ռ��16�ֽڣ������Ҫ n<<4 ����ʾ��Ӧ
// TSS��ʼλ�á��ú�õ���ֵ����Ҳ�Ǹ�TSS��ѡ���ֵ��
206 #define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
// �궨�壬������ȫ�ֱ��е�n�������LDT����������ѡ���ֵ��ƫ��������
207 #define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
// �궨�壬�ѵ�n�������TSS��ѡ������ص�����Ĵ���TR�С�
208 #define ltr(n) __asm__("ltr %%ax"::"a" (_TSS(n)))
// �궨�壬�ѵ�n�������LDT��ѡ������ص��ֲ����������Ĵ���LDTR�С�
209 #define lldt(n) __asm__("lldt %%ax"::"a" (_LDT(n)))
// ȡ��ǰ�������������ţ������������е�����ֵ������̺�pid��ͬ����
// ���أ�n - ��ǰ����š�����( kernel/traps.c )��
210 #define str(n) \
211 __asm__("str %%ax\n\t" \ // ������Ĵ�����TSS�ε�ѡ������Ƶ�ax�С�
212 "subl %2,%%eax\n\t" \ // (eax - FIRST_TSS_ENTRY*8)��eax
213 "shrl $4,%%eax" \ // (eax/16)��eax = ��ǰ����š�
214 :"=a" (n) \
215 :"a" (0),"i" (FIRST_TSS_ENTRY<<3))
216 /*
217 * switch_to(n) should switch tasks to task nr n, first
218 * checking that n isn't the current task, in which case it does nothing.
219 * This also clears the TS-flag if the task we switched to has used
220 * tha math co-processor latest.
221 */
/*
* switch_to(n)���л���ǰ��������nr����n�����ȼ������n���ǵ�ǰ����
* �������ʲôҲ�����˳�����������л���������������ϴ����У�ʹ�ù���ѧ
* Э�������Ļ������踴λ���ƼĴ���cr0�е�TS��־��
*/
// ��ת��һ�������TSS��ѡ�����ɵĵ�ַ�������CPU���������л�������
// ���룺%0 - ָ��__tmp�� %1 - ָ��__tmp.b�������ڴ����TSS��ѡ�����
// dx - ������n��TSS��ѡ����� ecx - ������n������ṹָ��task[n]��
// ������ʱ���ݽṹ__tmp�����齨177��Զ��ת��far jump��ָ��IJ��������ò�������4�ֽ�
// ƫ�Ƶ�ַ��2�ֽڵĶ�ѡ�����ɡ����__tmp��a��ֵ��32λƫ��ֵ����b�ĵ�2�ֽ�����
// TSS�ε�ѡ�������2�ֽڲ��ã�����ת��TSS��ѡ�������������л�����TSS��Ӧ�Ľ��̡�
// ������������л��ij���ת��aֵ���á�177���ϵ��ڴ�����תָ��ʹ��6�ֽڲ�������Ϊ��
// תĿ�ĵصij�ָ�룬���ʽΪ��jmp 16λ��ѡ�����32λƫ��ֵ�������ڴ��в������ı�ʾ˳
// �������������෴�������л�����֮�����ж�ԭ�����ϴ�ִ���Ƿ�ʹ�ù�Э������ʱ����ͨ��
// ��ԭ����ָ���뱣����last_task_used_math�����е��ϴ�ʹ�ù�Э����������ָ����бȽ϶�
// �����ģ��μ��ļ�kernel/sched.c���й�math_state_restore()������˵����
222 #define switch_to(n) {\
223 struct {long a,b;} __tmp; \
224 __asm__("cmpl %%ecx,_current\n\t" \ // ����n�ǵ�ǰ������?(current ==task[n]?)
225 "je 1f\n\t" \ // �ǣ���ʲô���������˳���
226 "movw %%dx,%1\n\t" \ // ��������TSS��16λѡ�������__tmp.b�С�
227 "xchgl %%ecx,_current\n\t" \ // current = task[n]��ecx = �����������
228 "ljmp %0\n\t" \ // ִ�г���ת��*&__tmp����������л���
// �������л�������Ż����ִ���������䡣
229 "cmpl %%ecx,_last_task_used_math\n\t" \ // ԭ�����ϴ�ʹ�ù�Э��������
230 "jne 1f\n\t" \ // û������ת���˳���
231 "clts\n" \ // ԭ�����ϴ�ʹ�ù�Э������������cr0�е�����
232 "1:" \ // �л���־TS��
233 ::"m" (*&__tmp.a),"m" (*&__tmp.b), \
234 "d" (_TSS(n)),"c" ((long) task[n])); \
235 }
236
// ҳ���ַ���������ں˴�����û���κεط�����!!��
237 #define PAGE_ALIGN(n) (((n)+0xfff)&0xfffff000)
238
// ����λ�ڵ�ַaddr���������еĸ�����ַ�ֶ�(����ַ��base)��
// %0 - ��ַaddrƫ��2��%1 - ��ַaddrƫ��4��%2 - ��ַaddrƫ��7��edx - ����ַbase��
239 #define _set_base(addr,base) \
240 __asm__("movw %%dx,%0\n\t" \ // ��ַbase��16λ(λ15-0)��[addr+2]��
241 "rorl $16,%%edx\n\t" \ // edx�л�ַ��16λ(λ31-16)��dx��
242 "movb %%dl,%1\n\t" \ // ��ַ��16λ�еĵ�8λ(λ23-16)��[addr+4]��
243 "movb %%dh,%2" \ // ��ַ��16λ�еĸ�8λ(λ31-24)��[addr+7]��
244 ::"m" (*((addr)+2)), \
245 "m" (*((addr)+4)), \
246 "m" (*((addr)+7)), \
247 "d" (base) \
248 :"dx") // ����gcc������edx�Ĵ����е�ֵ�ѱ�Ƕ�������ı��ˡ�
249
// ����λ�ڵ�ַaddr���������еĶ����ֶ�(�γ���limit)��
// %0 - ��ַaddr��%1 - ��ַaddrƫ��6����edx - �γ�ֵlimit��
250 #define _set_limit(addr,limit) \
251 __asm__("movw %%dx,%0\n\t" \ // �γ�limit��16λ(λ15-0)��[addr]��
252 "rorl $16,%%edx\n\t" \ // edx�еĶγ���4λ(λ19-16)��dl��
253 "movb %1,%%dh\n\t" \ // ȡԭ[addr+6]�ֽ���dh�����и�4λ��Щ��־��
254 "andb $0xf0,%%dh\n\t" \ // ��dh�ĵ�4λ(����Ŷγ���λ19-16)��
255 "orb %%dh,%%dl\n\t" \ // ��ԭ��4λ��־�Ͷγ��ĸ�4λ(λ19-16)�ϳ�1�ֽڣ�
256 "movb %%dl,%1" \ // ����[addr+6]����
257 ::"m" (*(addr)), \
258 "m" (*((addr)+6)), \
259 "d" (limit) \
260 :"dx")
261
// ���þֲ�����������ldt�������Ļ���ַ�ֶΡ�
262 #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )
// ���þֲ�����������ldt�������Ķγ��ֶΡ�
263 #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )
264
// �ӵ�ַaddr����������ȡ�λ���ַ��������_set_base()�����෴��
// edx - ��Ż���ַ(__base)��%1 - ��ַaddrƫ��2��%2 - ��ַaddrƫ��4��%3 - addrƫ��7��
265 #define _get_base(addr) ({\
266 unsigned long __base; \
267 __asm__("movb %3,%%dh\n\t" \ // ȡ[addr+7]����ַ��16λ�ĸ�8λ(λ31-24)��dh��
268 "movb %2,%%dl\n\t" \ // ȡ[addr+4]����ַ��16λ�ĵ�8λ(λ23-16)��dl��
269 "shll $16,%%edx\n\t" \ // ����ַ��16λ�Ƶ�edx�и�16λ����
270 "movw %1,%%dx" \ // ȡ[addr+2]����ַ��16λ(λ15-0)��dx��
271 :"=d" (__base) \ // �Ӷ�edx�к���32λ�Ķλ���ַ��
272 :"m" (*((addr)+2)), \
273 "m" (*((addr)+4)), \
274 "m" (*((addr)+7))); \
275 __base;})
276
// ȡ�ֲ�����������ldt��ָ���������еĻ���ַ��
277 #define get_base(ldt) _get_base( ((char *)&(ldt)) )
278
// ȡ��ѡ���segmentָ�����������еĶ���ֵ��
// ָ��lsl��Load Segment Limit��д������ָ������������ȡ����ɢ��������λƴ��������
// ����ֵ����ָ���Ĵ����С����õĶ�����ʵ���ֽ�����1��������ﻹ��Ҫ��1��ŷ��ء�
// %0 - ��Ŷγ�ֵ(�ֽ���)��%1 - ��ѡ���segment��
279 #define get_limit(segment) ({ \
280 unsigned long __limit; \
281 __asm__("lsll %1,%0\n\tincl %0":"=r" (__limit):"r" (segment)); \
282 __limit;})
283
284 #endif
285