����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 */  # Ԥ���ռ䡣