����6-3 linux/boot/head.s
1 /*
2 * linux/boot/head.s
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7 /*
8 * head.s contains the 32-bit startup code.
9 *
10 * NOTE!!! Startup happens at absolute address 0x00000000, which is also where
11 * the page directory will exist. The startup code will be overwritten by
12 * the page directory.
13 */
/*
* head.s����32λ�������롣
* ע��!!! 32λ���������ǴӾ��Ե�ַ0x00000000��ʼ�ģ�����Ҳͬ����ҳĿ¼�����ڵĵط���
* ���������������뽫��ҳĿ¼���ǵ���
*/
14 .text
15 .globl _idt,_gdt,_pg_dir,_tmp_floppy_area
16 _pg_dir: # ҳĿ¼�����������
# �ٴ�ע��!!! �����Ѿ�����32λ����ģʽ����������$0x10�����ǰѵ�ַ0x10װ�����
# �μĴ�������������ʵ��ȫ�ֶ����������е�ƫ��ֵ�����߸�ȷ��˵��һ������������
# ��ѡ������й�ѡ�����˵����μ�setup.s��193���µ�˵��������$0x10�ĺ���������
# ��Ȩ��0(λ0-1=0)��ѡ��ȫ����������(λ2=0)��ѡ����е�2��(λ3-15=2)��������ָ
# ����е����ݶ�����������������ľ�����ֵ�μ�ǰ��setup.s��212��213�У�
# �������ĺ����ǣ�����ds,es,fs,gsΪsetup.s �й�������ݶΣ�ȫ�ֶ�����������2�
# ��ѡ���=0x10��������ջ������stack_startָ���user_stack��������Ȼ��ʹ�ñ�����
# ���涨������ж�����������ȫ�ֶ�����������ȫ�ֶ��������г�ʼ������setup.s�еĻ���
# һ������������8MB�ij���16MB��stack_start������kernel/sched.c��69�С�����ָ��
# user_stack����ĩ�˵�һ����ָ�롣��23����������ʹ�õ�ջ�����ҳ�Ϊϵͳջ�������ƶ���
# ����0ִ�У�init/main.c��137�У��Ժ��ջ�ͱ���������0������1��ͬʹ�õ��û�ջ�ˡ�
17 startup_32: # 18-22�����ø������ݶμĴ�����
18 movl $0x10,%eax # ����GNU��࣬ÿ��ֱ�Ӳ�����Ҫ��'$'��ʼ�������ʾ��ַ��
# ÿ���Ĵ�������Ҫ��'%'��ͷ��eax��ʾ��32λ��ax�Ĵ�����
19 mov %ax,%ds
20 mov %ax,%es
21 mov %ax,%fs
22 mov %ax,%gs
23 lss _stack_start,%esp # ��ʾ_stack_start��ss:esp������ϵͳ��ջ��
# stack_start������kernel/sched.c��69��
24 call setup_idt # ���������ж����������ӳ���
25 call setup_gdt # ��������ȫ�����������ӳ���
26 movl $0x10,%eax # reload all the segment registers
27 mov %ax,%ds # after changing gdt. CS was already
28 mov %ax,%es # reloaded in 'setup_gdt'
29 mov %ax,%fs # ��Ϊ����gdt��������Ҫ����װ�����еĶμĴ�����
30 mov %ax,%gs # CS����μĴ����Ѿ���setup_gdt�����¼��ع��ˡ�
# ���ڶ��������еĶ�����setup.s�е�8MB�ij��˱��������õ�16MB����setup.s��208-216
# �ͱ���������235-236�У�����������ٴζ����жμĴ���ִ�м��ز����DZ���ġ����⣬ͨ��
# ʹ��bochs���ٹ۲죬�������CS�ٴ�ִ�м��أ���ô��ִ�е�26��ʱCS����β��ɼ�������
# ��������8MB����������Ӧ�����¼���CS����������setup.s�е��ں˴�����������뱾������
# �������õĴ�������������˶����������ಿ����ȫһ����8MB�������ں˳�ʼ���β�����
# ���⣬�������Ժ��ں�ִ�й����жμ���תʱ�����¼���CS���������û�м�������û���ó���
# ������
# ��Ը����⣬Ŀǰ�ں��о��ڵ�25��֮��������һ������תָ�'ljmp $(__KERNEL_CS),$1f'��
# ��ת����26����ȷ��CSȷʵ�ֱ����¼��ء�
31 lss _stack_start,%esp
# 32-36�����ڲ���A20��ַ���Ƿ��Ѿ����������õķ��������ڴ��ַ0x000000��д������
# һ����ֵ��Ȼ���ڴ��ַ0x100000(1M)���Ƿ�Ҳ�������ֵ�����һֱ��ͬ�Ļ�����һֱ
# �Ƚ���ȥ��Ҳ����ѭ������������ʾ��ַA20��û��ѡͨ������ں˾Ͳ���ʹ��1MB�����ڴ档
#
# 33���ϵ�'1:'��һ���ֲ����Ź��ɵı�š�����ɷ��ź��һ��ð����ɡ���ʱ�÷��ű�ʾ�
# λ�ü�����Active location counter���ĵ�ǰֵ����������Ϊָ��IJ��������ֲ��������ڰ���
# �������ͱ����Ա��ʱʹ��һЩ���ơ�����10���ֲ������������������������ظ�ʹ�á���Щ����
# ��ʹ������'0'��'1'��...��'9'�����á�Ϊ�˶���һ���ֲ����ţ���ѱ��д��'N:'��ʽ������N
# ��ʾһ�����֣���Ϊ��������ǰ��������������ţ���Ҫд��'Nb'������N�Ƕ�����ʱʹ�õ�
# ���֡�Ϊ������һ���ֲ���ŵ���һ�����壬��Ҫд��'Nf'������N��10��ǰ������֮һ������
# 'b'��ʾ�����backwards������'f'��ʾ����ǰ��forwards�������ڻ������ijһ�����������
# �������/��ǰ����10����ţ���Զ��10������
32 xorl %eax,%eax
33 1: incl %eax # check that A20 really IS enabled
34 movl %eax,0x000000 # loop forever if it isn't
35 cmpl %eax,0x100000
36 je 1b # '1b'��ʾ���(backward)��ת�����1ȥ��33�У���
# ����'5f'���ʾ��ǰ(forward)��ת�����5ȥ��
37 /*
38 * NOTE! 486 should set bit 16, to check for write-protect in supervisor
39 * mode. Then it would be unnecessary with the "verify_area()"-calls.
40 * 486 users probably want to set the NE (#5) bit also, so as to use
41 * int 16 for math errors.
42 */
/*
* ע��! ��������γ����У�486Ӧ�ý�λ16��λ���Լ���ڳ����û�ģʽ�µ�д����,
* �˺� "verify_area()" ���þͲ���Ҫ�ˡ�486���û�ͨ��Ҳ���뽫NE(#5)��λ���Ա�
* ����ѧЭ�������ij���ʹ��int 16��
*/
# ����ԭע�����ᵽ��486 CPU��CR0���ƼĴ�����λ16��д������־WP��Write-Protect����
# ���ڽ�ֹ�����û����ij�����һ���û�ֻ��ҳ���н���д�������ñ�־��Ҫ���ڲ���ϵͳ�ڴ���
# �½���ʱʵ��дʱ���ƣ�copy-on-write��������
# ������γ���43-65�����ڼ����ѧЭ������оƬ�Ƿ���ڡ��������Ŀ��ƼĴ���CR0����
# �������Э�������������ִ��һ��Э������ָ���������Ļ���˵��Э������оƬ�����ڣ�
# ��Ҫ����CR0�е�Э����������λEM��λ2��������λЭ���������ڱ�־MP��λ1����
43 movl %cr0,%eax # check math chip
44 andl $0x80000011,%eax # Save PG,PE,ET
45 /* "orl $0x10020,%eax" here for 486 might be good */
46 orl $2,%eax # set MP
47 movl %eax,%cr0
48 call check_x87
49 jmp after_page_tables # ��ת��135�С�
50
51 /*
52 * We depend on ET to be correct. This checks for 287/387.
53 */
/*
* ����������ET��־����ȷ�������287/387�������
*/
# ����fninit��fstsw����ѧЭ��������80287/80387����ָ�
# finit ��Э������������ʼ����������Э����������һ��δ����ǰ����Ӱ�����֪״̬������
# �������ΪĬ��ֵ�����״̬�ֺ����и���ջʽ�Ĵ������ǵȴ���ʽ������ָ�fninit��������
# Э��������ִֹ�е�ǰ����ִ�е��κ���ǰ������������fstsw ָ��ȡЭ��������״̬�֡����ϵ
# ͳ�д���Э�������Ļ�����ô��ִ����fninitָ�����״̬�ֵ��ֽڿ϶�Ϊ0��
54 check_x87:
55 fninit # ��Э������������ʼ�����
56 fstsw %ax # ȡЭ������״̬�ֵ�ax�Ĵ����С�
57 cmpb $0,%al # ��ʼ����״̬��Ӧ��Ϊ0������˵��Э�����������ڡ�
58 je 1f /* no coprocessor: have to set bits */
59 movl %cr0,%eax # �����������ǰ��ת�����1���������дcr0��
60 xorl $6,%eax /* reset MP, set EM */
61 movl %eax,%cr0
62 ret
# ������һ�������ָʾ�����京����ָ�洢�߽���������"2"��ʾ�����Ĵ�������ݵ�ƫ��λ��
# ��������ֵַ���2����λΪ���λ�ã�2^2��������4�ֽڷ�ʽ�����ڴ��ַ����������GNU as
# ֱ��ʱд�������ֵ����2�Ĵη�ֵ�ˡ�ʹ�ø�ָʾ����Ŀ����Ϊ�����32λCPU�����ڴ��д���
# �����ݵ��ٶȺ�Ч�ʡ��μ���������ϸ˵����
# ����������ֽ�ֵ��80287Э������ָ��fsetpm�Ļ����롣�������ǰ�80287����Ϊ����ģʽ��
# 80387�����ָ����ҽ���Ѹ�ָ����ǿղ�����
63 .align 2
64 1: .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ # 287Э�������롣
65 ret
66
67 /*
68 * setup_idt
69 *
70 * sets up a idt with 256 entries pointing to
71 * ignore_int, interrupt gates. It then loads
72 * idt. Everything that wants to install itself
73 * in the idt-table may do so themselves. Interrupts
74 * are enabled elsewhere, when we can be relatively
75 * sure everything is ok. This routine will be over-
76 * written by the page tables.
77 */
/*
* ��������������ж����������ӳ��� setup_idt
*
* ���ж���������idt���óɾ���256�������ָ��ignore_int�ж��š�Ȼ������ж�
* ���������Ĵ���(��lidtָ��)������ʵ�õ��ж����Ժ��ٰ�װ���������������ط���Ϊһ��
* ������ʱ�ٿ����жϡ����ӳ��ᱻҳ�����ǵ���
*/
# �ж����������е�����ȻҲ��8�ֽ���ɣ������ʽ��ȫ�ֱ��еIJ�ͬ������Ϊ��������
# (Gate Descriptor)������0-1,6-7�ֽ���ƫ������2-3�ֽ���ѡ�����4-5�ֽ���һЩ��־��
# ��δ���������edx��eax��������ó�8�ֽ�Ĭ�ϵ��ж�������ֵ��Ȼ����idt��ÿһ����
# �����ø�����������256�eax������������4�ֽڣ�edx���и�4�ֽڡ��ں������ij�ʼ
# �������л��滻��װ��Щ����ʵ�õ��ж��������
78 setup_idt:
79 lea ignore_int,%edx # ��ignore_int����Ч��ַ��ƫ��ֵ��ֵ��edx�Ĵ���
80 movl $0x00080000,%eax # ��ѡ���0x0008����eax�ĸ�16λ�С�
81 movw %dx,%ax /* selector = 0x0008 = cs */
# ƫ��ֵ�ĵ�16λ����eax�ĵ�16λ�С���ʱeax����
# ����������4�ֽڵ�ֵ��
82 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
83 # ��ʱedx��������������4�ֽڵ�ֵ��
84 lea _idt,%edi # _idt���ж����������ĵ�ַ��
85 mov $256,%ecx
86 rp_sidt:
87 movl %eax,(%edi) # ��������������������
88 movl %edx,4(%edi) # eax���ݷŵ� edi+4 ��ָ�ڴ�λ�ô���
89 addl $8,%edi # ediָ�������һ�
90 dec %ecx
91 jne rp_sidt
92 lidt idt_descr # �����ж����������Ĵ���ֵ��
93 ret
94
95 /*
96 * setup_gdt
97 *
98 * This routines sets up a new gdt and loads it.
99 * Only two entries are currently built, the same
100 * ones that were built in init.s. The routine
101 * is VERY complicated at two whole lines, so this
102 * rather long comment is certainly needed :-).
103 * This routine will beoverwritten by the page tables.
104 */
/*
* ����ȫ������������ setup_gdt
* ����ӳ�������һ���µ�ȫ����������gdt�������ء���ʱ�����������������ǰ
* ���һ�������ӳ���ֻ�����У����dz��ġ����ӣ����Ե�Ȼ��Ҫ��ô����ע����J��
* ���ӳ���ҳ�����ǵ���
*/
105 setup_gdt:
106 lgdt gdt_descr # ����ȫ�����������Ĵ���(���������úã���234-238��)��
107 ret
108
109 /*
110 * I put the kernel page tables right after the page directory,
111 * using 4 of them to span 16 Mb of physical memory. People with
112 * more than 16MB will have to expand this.
113 */
/* Linus���ں˵��ڴ�ҳ��ֱ�ӷ���ҳĿ¼֮��ʹ����4������Ѱַ16 MB�������ڴ档
* ������ж���16 Mb���ڴ棬����Ҫ��������������ġ�
*/
# ÿ��ҳ����Ϊ4 Kb�ֽڣ�1ҳ�ڴ�ҳ�棩����ÿ��ҳ������Ҫ4���ֽڣ����һ��ҳ�������Դ��
# 1024��������һ��ҳ����Ѱַ4 KB�ĵ�ַ�ռ䣬��һ��ҳ���Ϳ���Ѱַ4 MB�������ڴ档
# ҳ����ĸ�ʽΪ�����ǰ0-11λ���һЩ��־�������Ƿ����ڴ���(Pλ0)����д����(R/Wλ1)��
# ��ͨ�û����dz����û�ʹ��(U/Sλ2)���Ƿ��Ĺ�(�Ƿ�����)(Dλ6)�ȣ������λ12-31��
# ҳ���ַ������ָ��һҳ�ڴ��������ʼ��ַ��
114 .org 0x1000 # ��ƫ��0x1000����ʼ�ǵ�1��ҳ����ƫ��0��ʼ�������ҳ��Ŀ¼����
115 pg0:
116
117 .org 0x2000
118 pg1:
119
120 .org 0x3000
121 pg2:
122
123 .org 0x4000
124 pg3:
125
126 .org 0x5000 # ����������ڴ����ݿ��ƫ��0x5000����ʼ��
127 /*
128 * tmp_floppy_area is used by the floppy-driver when DMA cannot
129 * reach to a buffer-block. It needs to be aligned, so that it isn't
130 * on a 64kB border.
131 */
/* ��DMA��ֱ�Ӵ洢�����ʣ����ܷ��ʻ����ʱ�������tmp_floppy_area�ڴ��
* �Ϳɹ�������������ʹ�á����ַ��Ҫ��������������Ͳ����Խ64KB�߽硣
*/
132 _tmp_floppy_area:
133 .fill 1024,1,0 # ������1024�ÿ��1�ֽڣ������ֵ0��
134
# �����⼸����ջ��������Ϊ��ת��init/main.c�е�main()����������������139����
# ��ָ����ջ��ѹ���˷��ص�ַ������140����ѹ����main()��������ĵ�ַ����head.s
# ����ڵ�218��ִ��retָ��ʱ�ͻᵯ��main()�ĵ�ַ�����ѿ���Ȩת�Ƶ�init/main.c
# �����С��μ���3�����й�C�������û��Ƶ�˵����
# ǰ��3����ջ0ֵӦ�÷ֱ��ʾenvp��argvָ���argc��ֵ����main()û���õ���
# 139�е���ջ������ģ�����main.c����ʱ���Ƚ����ص�ַ��ջ�IJ������������
# main.c��������˳�ʱ���ͻ᷵�ص�����ı��L6������ִ����ȥ��Ҳ����ѭ����
# 140�н�main.c�ĵ�ַѹ���ջ�������������÷�ҳ������setup_paging��������
# ִ��'ret'����ָ��ʱ�ͻὫmain.c����ĵ�ַ������ջ����ȥִ��main.c�����ˡ�
# �й�C�������û�����μ�������˵����
135 after_page_tables:
136 pushl $0 # These are the parameters to main :-)
137 pushl $0 # ��Щ�ǵ���main����IJ�����ָinit/main.c����
138 pushl $0 # ���е�'$'���ű�ʾ����һ��������������
139 pushl $L6 # return address for main, if it decides to.
140 pushl $_main # '_main'�DZ�������main���ڲ���ʾ������
141 jmp setup_paging # ��ת����198�С�
142 L6:
143 jmp L6 # main should never return here, but
144 # just in case, we know what happens.
# main������Բ�Ӧ�÷��ص��������Ϊ���Է���һ��
# ���������˸���䡣�������Ǿ�֪������ʲô�����ˡ�
145
146 /* This is the default interrupt "handler" :-) */
/* ������Ĭ�ϵ��жϡ����������J */
147 int_msg:
148 .asciz "Unknown interrupt\n\r" # �����ַ�����δ֪�ж�(�س�����)����
149 .align 2 # ��4�ֽڷ�ʽ�����ڴ��ַ��
150 ignore_int:
151 pushl %eax
152 pushl %ecx
153 pushl %edx
154 push %ds # ������ע�⣡��ds,es,fs,gs����Ȼ��16λ�ļĴ���������ջ��
155 push %es # ��Ȼ����32λ����ʽ��ջ��Ҳ����Ҫռ��4���ֽڵĶ�ջ�ռ䡣
156 push %fs
157 movl $0x10,%eax # �ö�ѡ�����ʹds,es,fsָ��gdt���е����ݶΣ���
158 mov %ax,%ds
159 mov %ax,%es
160 mov %ax,%fs
161 pushl $int_msg # �ѵ���printk�����IJ���ָ�루��ַ����ջ��ע�⣡��int_msg
162 call _printk # ǰ����'$'�����ʾ��int_msg���Ŵ��ij��֣�'Unkn'����ջJ��
163 popl %eax # �ú�����/kernel/printk.c�С�'_printk'��printk�����ģ����
164 pop %fs # ���ڲ���ʾ����
165 pop %es
166 pop %ds
167 popl %edx
168 popl %ecx
169 popl %eax
170 iret # �жϷ��أ����жϵ���ʱѹ��ջ��CPU��־�Ĵ�����32λ��ֵҲ��������
171
172
173 /*
174 * Setup_paging
175 *
176 * This routine sets up paging by setting the page bit
177 * in cr0. The page tables are set up, identity-mapping
178 * the first 16MB. The pager assumes that no illegal
179 * addresses are produced (ie >4Mb on a 4Mb machine).
180 *
181 * NOTE! Although all physical memory should be identity
182 * mapped by this routine, only the kernel page functions
183 * use the >1Mb addresses directly. All "normal" functions
184 * use just the lower 1Mb, or the local data space, which
185 * will be mapped to some other place - mm keeps track of
186 * that.
187 *
188 * For those with more memory than 16 Mb - tough luck. I've
189 * not got it, why should you :-) The source is here. Change
190 * it. (Seriously - it shouldn't be too difficult. Mostly
191 * change some constants etc. I left it at 16Mb, as my machine
192 * even cannot be extended past that (ok, but it was cheap :-)
193 * I've tried to show which constants to change by having
194 * some kind of marker at them (search for "16Mb"), but I
195 * won't guarantee that's all :-( )
196 */
/*
* ����ӳ���ͨ�����ÿ��ƼĴ���cr0�ı�־��PG λ31�����������ڴ�ķ�ҳ�������ܣ�
* �����ø���ҳ��������ݣ��Ժ��ӳ��ǰ16 MB�������ڴ档��ҳ���ٶ���������Ƿ���
* ��ַӳ�䣨Ҳ����ֻ��4Mb�Ļ��������ó�����4Mb���ڴ��ַ����
*
* ע�⣡�������е�������ַ��Ӧ��������ӳ�����к��ӳ�䣬��ֻ���ں�ҳ�����������
* ֱ��ʹ��>1Mb�ĵ�ַ�����С���ͨ��������ʹ�õ���1Mb�ĵ�ַ�ռ䣬������ʹ�þֲ�����
* �ռ䣬�õ�ַ�ռ佫��ӳ�䵽����һЩ�ط�ȥ -- mm���ڴ�������������Щ�µġ�
*
* ������Щ�ж���16Mb�ڴ�ļһ� �C ����̫�����ˣ��һ�û�У�Ϊʲô�����J���������
* ������������İɡ���ʵ���ϣ��Ⲣ��̫���ѵġ�ͨ��ֻ����һЩ�����ȡ��Ұ�������
* Ϊ16Mb����Ϊ�ҵĻ�������ô�����������ܳ���������ޣ���Ȼ���ҵĻ����Ǻܱ��˵�J����
* ���Ѿ�ͨ������ij���־��������Ҫ�Ķ��ĵط���������16Mb���������Ҳ��ܱ�֤����Щ
* ��������L����
*/
# ����Ӣ��ע�͵�2�εĺ�����ָ�ڻ��������ڴ��д���1MB���ڴ�ռ���Ҫ���������ڴ�����
# ���ڴ����ռ���mmģ����������漰��ҳ��ӳ��������ں�����������������������ָ��һ��
#����ͨ����������Ҫʹ�����ڴ�����ҳ�棬����Ҫʹ��get_free_page()�Ⱥ�����ȡ����Ϊ����
# �������ڴ�ҳ���ǹ�����Դ�������г������ͳһ�����Ա�����Դ���ú;�����
#
# ���ڴ�������ַ0x0����ʼ���1ҳҳĿ¼����4ҳҳ����ҳĿ¼����ϵͳ���н��̹��õģ���
# �����4ҳҳ���������ں�ר�ã�����һһӳ�����Ե�ַ��ʼ16MB�ռ䷶Χ�������ڴ��ϡ�����
# �µĽ��̣�ϵͳ�������ڴ���Ϊ������ҳ����ҳ�������⣬1ҳ�ڴ泤����4096�ֽڡ�
197 .align 2 # ��4�ֽڷ�ʽ�����ڴ��ַ�߽硣
198 setup_paging: # ���ȶ�5ҳ�ڴ棨1ҳĿ¼ + 4ҳҳ�������㡣
199 movl $1024*5,%ecx /* 5 pages - pg_dir+4 page tables */
200 xorl %eax,%eax
201 xorl %edi,%edi /* pg_dir is at 0x000 */
# ҳĿ¼��0x000��ַ��ʼ��
202 cld;rep;stosl # eax���ݴ浽es:edi��ָ�ڴ�λ�ô�����edi��4��
# ����4������ҳĿ¼���е����Ϊ���ǣ��ںˣ�����4��ҳ������ֻ������4�
# ҳĿ¼��Ľṹ��ҳ������Ľṹһ����4���ֽ�Ϊ1��μ�����113���µ�˵����
# ����"$pg0+7"��ʾ��0x00001007����ҳĿ¼���еĵ�1�
# ���1��ҳ�����ڵĵ�ַ = 0x00001007 & 0xfffff000 = 0x1000��
# ��1��ҳ�������Ա�־ = 0x00001007 & 0x00000fff = 0x07����ʾ��ҳ���ڡ��û��ɶ�д��
203 movl $pg0+7,_pg_dir /* set present bit/user r/w */
204 movl $pg1+7,_pg_dir+4 /* --------- " " --------- */
205 movl $pg2+7,_pg_dir+8 /* --------- " " --------- */
206 movl $pg3+7,_pg_dir+12 /* --------- " " --------- */
# ����6����д4��ҳ��������������ݣ����У�4(ҳ��)*1024(��/ҳ��)=4096��(0 - 0xfff)��
# Ҳ����ӳ�������ڴ� 4096*4Kb = 16Mb��
# ÿ��������ǣ���ǰ����ӳ��������ڴ��ַ + ��ҳ�ı�־�������Ϊ7����
# ʹ�õķ����Ǵ����һ��ҳ�������һ�ʼ������˳����д��һ��ҳ�������һ����ҳ���е�
# λ����1023*4 = 4092��������һҳ�����һ���λ�þ���$pg3+4092��
207 movl $pg3+4092,%edi # edi�����һҳ�����һ�
208 movl $0xfff007,%eax /* 16Mb - 4096 + 7 (r/w user,p) */
# ���1���Ӧ�����ڴ�ҳ��ĵ�ַ��0xfff000��
# �������Ա�־7����Ϊ0xfff007��
209 std # ����λ��λ��ediֵ�ݼ�(4�ֽ�)��
210 1: stosl /* fill pages backwards - more efficient :-) */
211 subl $0x1000,%eax # ÿ��д��һ�������ֵַ��0x1000��
212 jge 1b # ���С��0��˵��ȫ��д���ˡ�
# ����ҳĿ¼����ַ�Ĵ���cr3��ֵ��ָ��ҳĿ¼����cr3�б������ҳĿ¼����������ַ��
213 xorl %eax,%eax /* pg_dir is at 0x0000 */ # ҳĿ¼����0x0000����
214 movl %eax,%cr3 /* cr3 - page directory start */
# ��������ʹ�÷�ҳ������cr0��PG��־��λ31��
215 movl %cr0,%eax
216 orl $0x80000000,%eax # ����PG��־��
217 movl %eax,%cr0 /* set paging (PG) bit */
218 ret /* this also flushes prefetch-queue */
# �ڸı��ҳ������־��Ҫ��ʹ��ת��ָ��ˢ��Ԥȡָ����У������õ��Ƿ���ָ��ret��
# �÷���ָ�����һ�������ǽ�140��ѹ���ջ�е�main����ĵ�ַ����������ת��/init/main.c
# ����ȥ���С������˾����������ˡ�
219
220 .align 2 # ��4�ֽڷ�ʽ�����ڴ��ַ�߽硣
221 .word 0 # �����ȿճ�2�ֽڣ�����224���ϵij�����4�ֽڶ���ġ�
! �����Ǽ����ж����������Ĵ���idtr��ָ��lidtҪ���6�ֽڲ�������ǰ2�ֽ���idt��������
! ��4�ֽ���idt�������Ե�ַ�ռ��е�32λ����ַ��
222 idt_descr:
223 .word 256*8-1 # idt contains 256 entries # ��256���=���� - 1��
224 .long _idt
225 .align 2
226 .word 0
! �������ȫ�����������Ĵ���gdtr��ָ��lgdtҪ���6�ֽڲ�������ǰ2�ֽ���gdt��������
! ��4�ֽ���gdt�������Ի���ַ������ȫ�ֱ���������Ϊ2KB�ֽڣ�0x7ff���ɣ�����Ϊÿ8�ֽ�
! ���һ������������Ա��й�����256�����_gdt��ȫ�ֱ��ڱ������е�ƫ��λ�ã���234�С�
227 gdt_descr:
228 .word 256*8-1 # so does gdt (not that that's any # ע��not �� note
229 .long _gdt # magic number, but it works for me :^)
230
231 .align 3 # ��8��2^3���ֽڷ�ʽ�����ڴ��ַ�߽硣
232 _idt: .fill 256,8,0 # idt is uninitialized # 256�ÿ��8�ֽڣ���0��
233
# ȫ�ֱ���ǰ4��ֱ��ǿ�����ã�������������������ݶ���������ϵͳ���ö�������������
# ϵͳ���ö���������û�����ô���Linus��ʱ���������ϵͳ���ô���ר�ŷ�����������Ķ��С�
# ���滹Ԥ����252��Ŀռ䣬���ڷ�������������ľֲ�������(LDT)�Ͷ�Ӧ������״̬��TSS
# ����������
# (0-nul, 1-cs, 2-ds, 3-syscall, 4-TSS0, 5-LDT0, 6-TSS1, 7-LDT1, 8-TSS2 etc...)
234 _gdt: .quad 0x0000000000000000 /* NULL descriptor */
235 .quad 0x00c09a0000000fff /* 16Mb */ # 0x08���ں˴�������16MB��
236 .quad 0x00c0920000000fff /* 16Mb */ # 0x10���ں����ݶ����16MB��
237 .quad 0x0000000000000000 /* TEMPORARY - don't use */
238 .fill 252,8,0 /* space for LDT's and TSS's etc */ # Ԥ���ռ䡣