⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 head_32.s

📁 linux 内核源代码
💻 S
📖 第 1 页 / 共 2 页
字号:
/* *  linux/arch/i386/kernel/head.S -- the 32-bit startup code. * *  Copyright (C) 1991, 1992  Linus Torvalds * *  Enhanced CPU detection and feature setting code by Mike Jagdis *  and Martin Mares, November 1997. */.text#include <linux/threads.h>#include <linux/linkage.h>#include <asm/segment.h>#include <asm/page.h>#include <asm/pgtable.h>#include <asm/desc.h>#include <asm/cache.h>#include <asm/thread_info.h>#include <asm/asm-offsets.h>#include <asm/setup.h>/* * References to members of the new_cpu_data structure. */#define X86		new_cpu_data+CPUINFO_x86#define X86_VENDOR	new_cpu_data+CPUINFO_x86_vendor#define X86_MODEL	new_cpu_data+CPUINFO_x86_model#define X86_MASK	new_cpu_data+CPUINFO_x86_mask#define X86_HARD_MATH	new_cpu_data+CPUINFO_hard_math#define X86_CPUID	new_cpu_data+CPUINFO_cpuid_level#define X86_CAPABILITY	new_cpu_data+CPUINFO_x86_capability#define X86_VENDOR_ID	new_cpu_data+CPUINFO_x86_vendor_id/* * This is how much memory *in addition to the memory covered up to * and including _end* we need mapped initially. * We need: *  - one bit for each possible page, but only in low memory, which means *     2^32/4096/8 = 128K worst case (4G/4G split.) *  - enough space to map all low memory, which means *     (2^32/4096) / 1024 pages (worst case, non PAE) *     (2^32/4096) / 512 + 4 pages (worst case for PAE) *  - a few pages for allocator use before the kernel pagetable has *     been set up * * Modulo rounding, each megabyte assigned here requires a kilobyte of * memory, which is currently unreclaimed. * * This should be a multiple of a page. */LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)/* * To preserve the DMA pool in PAGEALLOC kernels, we'll allocate * pagetables from above the 16MB DMA limit, so we'll have to set * up pagetables 16MB more (worst-case): */#ifdef CONFIG_DEBUG_PAGEALLOCLOW_PAGES = LOW_PAGES + 0x1000000#endif#if PTRS_PER_PMD > 1PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD#elsePAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)#endifBOOTBITMAP_SIZE = LOW_PAGES / 8ALLOCATOR_SLOP = 4INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm/* * 32-bit kernel entrypoint; only used by the boot CPU.  On entry, * %esi points to the real-mode code as a 32-bit pointer. * CS and DS must be 4 GB flat segments, but we don't depend on * any particular GDT layout, because we load our own as soon as we * can. */.section .text.head,"ax",@progbitsENTRY(startup_32)	/* check to see if KEEP_SEGMENTS flag is meaningful */	cmpw $0x207, BP_version(%esi)	jb 1f	/* test KEEP_SEGMENTS flag to see if the bootloader is asking		us to not reload segments */	testb $(1<<6), BP_loadflags(%esi)	jnz 2f/* * Set segments to known values. */1:	lgdt boot_gdt_descr - __PAGE_OFFSET	movl $(__BOOT_DS),%eax	movl %eax,%ds	movl %eax,%es	movl %eax,%fs	movl %eax,%gs2:/* * Clear BSS first so that there are no surprises... */	cld	xorl %eax,%eax	movl $__bss_start - __PAGE_OFFSET,%edi	movl $__bss_stop - __PAGE_OFFSET,%ecx	subl %edi,%ecx	shrl $2,%ecx	rep ; stosl/* * Copy bootup parameters out of the way. * Note: %esi still has the pointer to the real-mode data. * With the kexec as boot loader, parameter segment might be loaded beyond * kernel image and might not even be addressable by early boot page tables. * (kexec on panic case). Hence copy out the parameters before initializing * page tables. */	movl $(boot_params - __PAGE_OFFSET),%edi	movl $(PARAM_SIZE/4),%ecx	cld	rep	movsl	movl boot_params - __PAGE_OFFSET + NEW_CL_POINTER,%esi	andl %esi,%esi	jz 1f			# No comand line	movl $(boot_command_line - __PAGE_OFFSET),%edi	movl $(COMMAND_LINE_SIZE/4),%ecx	rep	movsl1:#ifdef CONFIG_PARAVIRT	cmpw $0x207, (boot_params + BP_version - __PAGE_OFFSET)	jb default_entry	/* Paravirt-compatible boot parameters.  Look to see what architecture		we're booting under. */	movl (boot_params + BP_hardware_subarch - __PAGE_OFFSET), %eax	cmpl $num_subarch_entries, %eax	jae bad_subarch	movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax	subl $__PAGE_OFFSET, %eax	jmp *%eaxbad_subarch:WEAK(lguest_entry)WEAK(xen_entry)	/* Unknown implementation; there's really	   nothing we can do at this point. */	ud2a.datasubarch_entries:	.long default_entry		/* normal x86/PC */	.long lguest_entry		/* lguest hypervisor */	.long xen_entry			/* Xen hypervisor */num_subarch_entries = (. - subarch_entries) / 4.previous#endif /* CONFIG_PARAVIRT *//* * Initialize page tables.  This creates a PDE and a set of page * tables, which are located immediately beyond _end.  The variable * init_pg_tables_end is set up to point to the first "safe" location. * Mappings are created both at virtual address 0 (identity mapping) * and PAGE_OFFSET for up to _end+sizeof(page tables)+INIT_MAP_BEYOND_END. * * Warning: don't use %esi or the stack in this code.  However, %esp * can be used as a GPR if you really need it... */page_pde_offset = (__PAGE_OFFSET >> 20);default_entry:	movl $(pg0 - __PAGE_OFFSET), %edi	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx	movl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */10:	leal 0x007(%edi),%ecx			/* Create PDE entry */	movl %ecx,(%edx)			/* Store identity PDE entry */	movl %ecx,page_pde_offset(%edx)		/* Store kernel PDE entry */	addl $4,%edx	movl $1024, %ecx11:	stosl	addl $0x1000,%eax	loop 11b	/* End condition: we must map up to and including INIT_MAP_BEYOND_END */	/* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */	leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp	cmpl %ebp,%eax	jb 10b	movl %edi,(init_pg_tables_end - __PAGE_OFFSET)	/* Do an early initialization of the fixmap area */	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx	movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax	addl $0x67, %eax			/* 0x67 == _PAGE_TABLE */	movl %eax, 4092(%edx)	xorl %ebx,%ebx				/* This is the boot CPU (BSP) */	jmp 3f/* * Non-boot CPU entry point; entered from trampoline.S * We can't lgdt here, because lgdt itself uses a data segment, but * we know the trampoline has already loaded the boot_gdt for us. * * If cpu hotplug is not supported then this code can go in init section * which will be freed later */#ifndef CONFIG_HOTPLUG_CPU.section .init.text,"ax",@progbits#endif#ifdef CONFIG_SMPENTRY(startup_32_smp)	cld	movl $(__BOOT_DS),%eax	movl %eax,%ds	movl %eax,%es	movl %eax,%fs	movl %eax,%gs/* *	New page tables may be in 4Mbyte page mode and may *	be using the global pages.  * *	NOTE! If we are on a 486 we may have no cr4 at all! *	So we do not try to touch it unless we really have *	some bits in it to set.  This won't work if the BSP *	implements cr4 but this AP does not -- very unlikely *	but be warned!  The same applies to the pse feature *	if not equally supported. --macro * *	NOTE! We have to correct for the fact that we're *	not yet offset PAGE_OFFSET.. */#define cr4_bits mmu_cr4_features-__PAGE_OFFSET	movl cr4_bits,%edx	andl %edx,%edx	jz 6f	movl %cr4,%eax		# Turn on paging options (PSE,PAE,..)	orl %edx,%eax	movl %eax,%cr4	btl $5, %eax		# check if PAE is enabled	jnc 6f	/* Check if extended functions are implemented */	movl $0x80000000, %eax	cpuid	cmpl $0x80000000, %eax	jbe 6f	mov $0x80000001, %eax	cpuid	/* Execute Disable bit supported? */	btl $20, %edx	jnc 6f	/* Setup EFER (Extended Feature Enable Register) */	movl $0xc0000080, %ecx	rdmsr	btsl $11, %eax	/* Make changes effective */	wrmsr6:	/* This is a secondary processor (AP) */	xorl %ebx,%ebx	incl %ebx#endif /* CONFIG_SMP */3:/* * Enable paging */	movl $swapper_pg_dir-__PAGE_OFFSET,%eax	movl %eax,%cr3		/* set the page table pointer.. */	movl %cr0,%eax	orl $0x80000000,%eax	movl %eax,%cr0		/* ..and set paging (PG) bit */	ljmp $__BOOT_CS,$1f	/* Clear prefetch and normalize %eip */1:	/* Set up the stack pointer */	lss stack_start,%esp/* * Initialize eflags.  Some BIOS's leave bits like NT set.  This would * confuse the debugger if this code is traced. * XXX - best to initialize before switching to protected mode. */	pushl $0	popfl#ifdef CONFIG_SMP	andl %ebx,%ebx	jz  1f				/* Initial CPU cleans BSS */	jmp checkCPUtype1:#endif /* CONFIG_SMP *//* * start system 32-bit setup. We need to re-do some of the things done * in 16-bit mode for the "real" operations. */	call setup_idtcheckCPUtype:	movl $-1,X86_CPUID		#  -1 for no CPUID initially

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -