diff options
Diffstat (limited to 'arch/i386/kernel/head.S')
-rw-r--r-- | arch/i386/kernel/head.S | 118 |
1 files changed, 30 insertions, 88 deletions
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 3fa7f9389afe..9b10af65faaa 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -34,17 +34,32 @@ | |||
34 | 34 | ||
35 | /* | 35 | /* |
36 | * This is how much memory *in addition to the memory covered up to | 36 | * This is how much memory *in addition to the memory covered up to |
37 | * and including _end* we need mapped initially. We need one bit for | 37 | * and including _end* we need mapped initially. |
38 | * each possible page, but only in low memory, which means | 38 | * We need: |
39 | * 2^32/4096/8 = 128K worst case (4G/4G split.) | 39 | * - one bit for each possible page, but only in low memory, which means |
40 | * 2^32/4096/8 = 128K worst case (4G/4G split.) | ||
41 | * - enough space to map all low memory, which means | ||
42 | * (2^32/4096) / 1024 pages (worst case, non PAE) | ||
43 | * (2^32/4096) / 512 + 4 pages (worst case for PAE) | ||
44 | * - a few pages for allocator use before the kernel pagetable has | ||
45 | * been set up | ||
40 | * | 46 | * |
41 | * Modulo rounding, each megabyte assigned here requires a kilobyte of | 47 | * Modulo rounding, each megabyte assigned here requires a kilobyte of |
42 | * memory, which is currently unreclaimed. | 48 | * memory, which is currently unreclaimed. |
43 | * | 49 | * |
44 | * This should be a multiple of a page. | 50 | * This should be a multiple of a page. |
45 | */ | 51 | */ |
46 | #define INIT_MAP_BEYOND_END (128*1024) | 52 | LOW_PAGES = 1<<(32-PAGE_SHIFT_asm) |
47 | 53 | ||
54 | #if PTRS_PER_PMD > 1 | ||
55 | PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD | ||
56 | #else | ||
57 | PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD) | ||
58 | #endif | ||
59 | BOOTBITMAP_SIZE = LOW_PAGES / 8 | ||
60 | ALLOCATOR_SLOP = 4 | ||
61 | |||
62 | INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm | ||
48 | 63 | ||
49 | /* | 64 | /* |
50 | * 32-bit kernel entrypoint; only used by the boot CPU. On entry, | 65 | * 32-bit kernel entrypoint; only used by the boot CPU. On entry, |
@@ -147,8 +162,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20); | |||
147 | /* | 162 | /* |
148 | * Non-boot CPU entry point; entered from trampoline.S | 163 | * Non-boot CPU entry point; entered from trampoline.S |
149 | * We can't lgdt here, because lgdt itself uses a data segment, but | 164 | * We can't lgdt here, because lgdt itself uses a data segment, but |
150 | * we know the trampoline has already loaded the boot_gdt_table GDT | 165 | * we know the trampoline has already loaded the boot_gdt for us. |
151 | * for us. | ||
152 | * | 166 | * |
153 | * If cpu hotplug is not supported then this code can go in init section | 167 | * If cpu hotplug is not supported then this code can go in init section |
154 | * which will be freed later | 168 | * which will be freed later |
@@ -318,12 +332,12 @@ is386: movl $2,%ecx # set MP | |||
318 | movl %eax,%cr0 | 332 | movl %eax,%cr0 |
319 | 333 | ||
320 | call check_x87 | 334 | call check_x87 |
321 | call setup_pda | ||
322 | lgdt early_gdt_descr | 335 | lgdt early_gdt_descr |
323 | lidt idt_descr | 336 | lidt idt_descr |
324 | ljmp $(__KERNEL_CS),$1f | 337 | ljmp $(__KERNEL_CS),$1f |
325 | 1: movl $(__KERNEL_DS),%eax # reload all the segment registers | 338 | 1: movl $(__KERNEL_DS),%eax # reload all the segment registers |
326 | movl %eax,%ss # after changing gdt. | 339 | movl %eax,%ss # after changing gdt. |
340 | movl %eax,%fs # gets reset once there's real percpu | ||
327 | 341 | ||
328 | movl $(__USER_DS),%eax # DS/ES contains default USER segment | 342 | movl $(__USER_DS),%eax # DS/ES contains default USER segment |
329 | movl %eax,%ds | 343 | movl %eax,%ds |
@@ -333,16 +347,17 @@ is386: movl $2,%ecx # set MP | |||
333 | movl %eax,%gs | 347 | movl %eax,%gs |
334 | lldt %ax | 348 | lldt %ax |
335 | 349 | ||
336 | movl $(__KERNEL_PDA),%eax | ||
337 | mov %eax,%fs | ||
338 | |||
339 | cld # gcc2 wants the direction flag cleared at all times | 350 | cld # gcc2 wants the direction flag cleared at all times |
340 | pushl $0 # fake return address for unwinder | 351 | pushl $0 # fake return address for unwinder |
341 | #ifdef CONFIG_SMP | 352 | #ifdef CONFIG_SMP |
342 | movb ready, %cl | 353 | movb ready, %cl |
343 | movb $1, ready | 354 | movb $1, ready |
344 | cmpb $0,%cl # the first CPU calls start_kernel | 355 | cmpb $0,%cl # the first CPU calls start_kernel |
345 | jne initialize_secondary # all other CPUs call initialize_secondary | 356 | je 1f |
357 | movl $(__KERNEL_PERCPU), %eax | ||
358 | movl %eax,%fs # set this cpu's percpu | ||
359 | jmp initialize_secondary # all other CPUs call initialize_secondary | ||
360 | 1: | ||
346 | #endif /* CONFIG_SMP */ | 361 | #endif /* CONFIG_SMP */ |
347 | jmp start_kernel | 362 | jmp start_kernel |
348 | 363 | ||
@@ -366,23 +381,6 @@ check_x87: | |||
366 | ret | 381 | ret |
367 | 382 | ||
368 | /* | 383 | /* |
369 | * Point the GDT at this CPU's PDA. On boot this will be | ||
370 | * cpu_gdt_table and boot_pda; for secondary CPUs, these will be | ||
371 | * that CPU's GDT and PDA. | ||
372 | */ | ||
373 | ENTRY(setup_pda) | ||
374 | /* get the PDA pointer */ | ||
375 | movl start_pda, %eax | ||
376 | |||
377 | /* slot the PDA address into the GDT */ | ||
378 | mov early_gdt_descr+2, %ecx | ||
379 | mov %ax, (__KERNEL_PDA+0+2)(%ecx) /* base & 0x0000ffff */ | ||
380 | shr $16, %eax | ||
381 | mov %al, (__KERNEL_PDA+4+0)(%ecx) /* base & 0x00ff0000 */ | ||
382 | mov %ah, (__KERNEL_PDA+4+3)(%ecx) /* base & 0xff000000 */ | ||
383 | ret | ||
384 | |||
385 | /* | ||
386 | * setup_idt | 384 | * setup_idt |
387 | * | 385 | * |
388 | * sets up a idt with 256 entries pointing to | 386 | * sets up a idt with 256 entries pointing to |
@@ -554,9 +552,6 @@ ENTRY(empty_zero_page) | |||
554 | * This starts the data section. | 552 | * This starts the data section. |
555 | */ | 553 | */ |
556 | .data | 554 | .data |
557 | ENTRY(start_pda) | ||
558 | .long boot_pda | ||
559 | |||
560 | ENTRY(stack_start) | 555 | ENTRY(stack_start) |
561 | .long init_thread_union+THREAD_SIZE | 556 | .long init_thread_union+THREAD_SIZE |
562 | .long __BOOT_DS | 557 | .long __BOOT_DS |
@@ -588,7 +583,7 @@ fault_msg: | |||
588 | .word 0 # 32 bit align gdt_desc.address | 583 | .word 0 # 32 bit align gdt_desc.address |
589 | boot_gdt_descr: | 584 | boot_gdt_descr: |
590 | .word __BOOT_DS+7 | 585 | .word __BOOT_DS+7 |
591 | .long boot_gdt_table - __PAGE_OFFSET | 586 | .long boot_gdt - __PAGE_OFFSET |
592 | 587 | ||
593 | .word 0 # 32-bit align idt_desc.address | 588 | .word 0 # 32-bit align idt_desc.address |
594 | idt_descr: | 589 | idt_descr: |
@@ -599,67 +594,14 @@ idt_descr: | |||
599 | .word 0 # 32 bit align gdt_desc.address | 594 | .word 0 # 32 bit align gdt_desc.address |
600 | ENTRY(early_gdt_descr) | 595 | ENTRY(early_gdt_descr) |
601 | .word GDT_ENTRIES*8-1 | 596 | .word GDT_ENTRIES*8-1 |
602 | .long cpu_gdt_table | 597 | .long per_cpu__gdt_page /* Overwritten for secondary CPUs */ |
603 | 598 | ||
604 | /* | 599 | /* |
605 | * The boot_gdt_table must mirror the equivalent in setup.S and is | 600 | * The boot_gdt must mirror the equivalent in setup.S and is |
606 | * used only for booting. | 601 | * used only for booting. |
607 | */ | 602 | */ |
608 | .align L1_CACHE_BYTES | 603 | .align L1_CACHE_BYTES |
609 | ENTRY(boot_gdt_table) | 604 | ENTRY(boot_gdt) |
610 | .fill GDT_ENTRY_BOOT_CS,8,0 | 605 | .fill GDT_ENTRY_BOOT_CS,8,0 |
611 | .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ | 606 | .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ |
612 | .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ | 607 | .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ |
613 | |||
614 | /* | ||
615 | * The Global Descriptor Table contains 28 quadwords, per-CPU. | ||
616 | */ | ||
617 | .align L1_CACHE_BYTES | ||
618 | ENTRY(cpu_gdt_table) | ||
619 | .quad 0x0000000000000000 /* NULL descriptor */ | ||
620 | .quad 0x0000000000000000 /* 0x0b reserved */ | ||
621 | .quad 0x0000000000000000 /* 0x13 reserved */ | ||
622 | .quad 0x0000000000000000 /* 0x1b reserved */ | ||
623 | .quad 0x0000000000000000 /* 0x20 unused */ | ||
624 | .quad 0x0000000000000000 /* 0x28 unused */ | ||
625 | .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ | ||
626 | .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ | ||
627 | .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ | ||
628 | .quad 0x0000000000000000 /* 0x4b reserved */ | ||
629 | .quad 0x0000000000000000 /* 0x53 reserved */ | ||
630 | .quad 0x0000000000000000 /* 0x5b reserved */ | ||
631 | |||
632 | .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ | ||
633 | .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ | ||
634 | .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */ | ||
635 | .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */ | ||
636 | |||
637 | .quad 0x0000000000000000 /* 0x80 TSS descriptor */ | ||
638 | .quad 0x0000000000000000 /* 0x88 LDT descriptor */ | ||
639 | |||
640 | /* | ||
641 | * Segments used for calling PnP BIOS have byte granularity. | ||
642 | * They code segments and data segments have fixed 64k limits, | ||
643 | * the transfer segment sizes are set at run time. | ||
644 | */ | ||
645 | .quad 0x00409a000000ffff /* 0x90 32-bit code */ | ||
646 | .quad 0x00009a000000ffff /* 0x98 16-bit code */ | ||
647 | .quad 0x000092000000ffff /* 0xa0 16-bit data */ | ||
648 | .quad 0x0000920000000000 /* 0xa8 16-bit data */ | ||
649 | .quad 0x0000920000000000 /* 0xb0 16-bit data */ | ||
650 | |||
651 | /* | ||
652 | * The APM segments have byte granularity and their bases | ||
653 | * are set at run time. All have 64k limits. | ||
654 | */ | ||
655 | .quad 0x00409a000000ffff /* 0xb8 APM CS code */ | ||
656 | .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */ | ||
657 | .quad 0x004092000000ffff /* 0xc8 APM DS data */ | ||
658 | |||
659 | .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */ | ||
660 | .quad 0x00cf92000000ffff /* 0xd8 - PDA */ | ||
661 | .quad 0x0000000000000000 /* 0xe0 - unused */ | ||
662 | .quad 0x0000000000000000 /* 0xe8 - unused */ | ||
663 | .quad 0x0000000000000000 /* 0xf0 - unused */ | ||
664 | .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ | ||
665 | |||