locore.s revision 757
14Srgrimes/*- 24Srgrimes * Copyright (c) 1990 The Regents of the University of California. 34Srgrimes * All rights reserved. 44Srgrimes * 54Srgrimes * This code is derived from software contributed to Berkeley by 64Srgrimes * William Jolitz. 74Srgrimes * 84Srgrimes * Redistribution and use in source and binary forms, with or without 94Srgrimes * modification, are permitted provided that the following conditions 104Srgrimes * are met: 114Srgrimes * 1. Redistributions of source code must retain the above copyright 124Srgrimes * notice, this list of conditions and the following disclaimer. 134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 144Srgrimes * notice, this list of conditions and the following disclaimer in the 154Srgrimes * documentation and/or other materials provided with the distribution. 164Srgrimes * 3. All advertising materials mentioning features or use of this software 174Srgrimes * must display the following acknowledgement: 184Srgrimes * This product includes software developed by the University of 194Srgrimes * California, Berkeley and its contributors. 204Srgrimes * 4. Neither the name of the University nor the names of its contributors 214Srgrimes * may be used to endorse or promote products derived from this software 224Srgrimes * without specific prior written permission. 234Srgrimes * 244Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 254Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 264Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 274Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 284Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 294Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 304Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 314Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 324Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 334Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 344Srgrimes * SUCH DAMAGE. 354Srgrimes * 36556Srgrimes * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 37757Sdg * $Id$ 384Srgrimes */ 394Srgrimes 404Srgrimes/* 41757Sdg * locore.s: FreeBSD machine support for the Intel 386 42757Sdg * originally from: locore.s, by William F. Jolitz 43757Sdg * 44757Sdg * Substantially rewritten by David Greenman, Rod Grimes, 45757Sdg * Bruce Evans, Wolfgang Solfrank, and many others. 464Srgrimes */ 474Srgrimes 48757Sdg#include "npx.h" /* for NNPX */ 49556Srgrimes 50757Sdg#include "assym.s" /* system definitions */ 51757Sdg#include "machine/psl.h" /* processor status longword defs */ 52757Sdg#include "machine/pte.h" /* page table entry definitions */ 534Srgrimes 54757Sdg#include "errno.h" /* error return codes */ 554Srgrimes 56757Sdg#include "machine/specialreg.h" /* x86 special registers */ 57757Sdg#include "i386/isa/debug.h" /* BDE debugging macros */ 58757Sdg#include "machine/cputypes.h" /* x86 cpu type definitions */ 594Srgrimes 60757Sdg#include "syscall.h" /* system call numbers */ 614Srgrimes 62757Sdg#include "machine/asmacros.h" /* miscellaneous asm macros */ 634Srgrimes 644Srgrimes/* 65757Sdg * XXX 66757Sdg * 674Srgrimes * Note: This version greatly munged to avoid various assembler errors 684Srgrimes * that may be fixed in newer versions of gas. Perhaps newer versions 694Srgrimes * will have more pleasant appearance. 704Srgrimes */ 714Srgrimes 72200Sdg/* 734Srgrimes * PTmap is recursive pagemap at top of virtual address space. 744Srgrimes * Within PTmap, the page directory can be found (third indirection). 754Srgrimes */ 76592Srgrimes .globl _PTmap,_PTD,_PTDpde,_Sysmap 77592Srgrimes .set _PTmap,PTDPTDI << PDRSHIFT 78592Srgrimes .set _PTD,_PTmap + (PTDPTDI * NBPG) 79757Sdg .set _PTDpde,_PTD + (PTDPTDI * PDESIZE) 80592Srgrimes 81757Sdg/* Sysmap is the base address of the kernel page tables */ 82608Srgrimes .set _Sysmap,_PTmap + (KPTDI * NBPG) 834Srgrimes 844Srgrimes/* 854Srgrimes * APTmap, APTD is the alternate recursive pagemap. 864Srgrimes * It's used when modifying another process's page tables. 874Srgrimes */ 88592Srgrimes .globl _APTmap,_APTD,_APTDpde 89592Srgrimes .set _APTmap,APTDPTDI << PDRSHIFT 90592Srgrimes .set _APTD,_APTmap + (APTDPTDI * NBPG) 91757Sdg .set _APTDpde,_PTD + (APTDPTDI * PDESIZE) 924Srgrimes 934Srgrimes/* 944Srgrimes * Access to each processes kernel stack is via a region of 954Srgrimes * per-process address space (at the beginning), immediatly above 964Srgrimes * the user process stack. 974Srgrimes */ 98570Srgrimes .set _kstack,USRSTACK 99134Sdg .globl _kstack 1004Srgrimes 101556Srgrimes/* 102556Srgrimes * Globals 103556Srgrimes */ 104556Srgrimes .data 105556Srgrimes .globl _esym 106757Sdg_esym: .long 0 /* ptr to end of syms */ 107134Sdg 108592Srgrimes .globl _boothowto,_bootdev,_curpcb 109134Sdg 110592Srgrimes .globl _cpu,_cold,_atdevbase 111757Sdg_cpu: .long 0 /* are we 386, 386sx, or 486 */ 112757Sdg_cold: .long 1 /* cold till we are not */ 113757Sdg_atdevbase: .long 0 /* location of start of iomem in virtual */ 114757Sdg_atdevphys: .long 0 /* location of device mapping ptes (phys) */ 1154Srgrimes 116757Sdg .globl _KERNend 117757Sdg_KERNend: .long 0 /* phys addr end of kernel (just after bss) */ 118757Sdg 119592Srgrimes .globl _IdlePTD,_KPTphys 120757Sdg_IdlePTD: .long 0 /* phys addr of kernel PTD */ 121757Sdg_KPTphys: .long 0 /* phys addr of kernel page tables */ 1224Srgrimes 123757Sdg .globl _cyloffset 124757Sdg_cyloffset: .long 0 /* cylinder offset from boot blocks */ 125718Swollman 126757Sdg .globl _proc0paddr 127757Sdg_proc0paddr: .long 0 /* address of proc 0 address space */ 128134Sdg 129757Sdg#ifdef BDE_DEBUGGER 130757Sdg .globl _bdb_exists /* flag to indicate BDE debugger is available */ 131757Sdg .long 0 132757Sdg#endif 133718Swollman 134757Sdg .globl tmpstk 1354Srgrimes .space 512 1364Srgrimestmpstk: 137134Sdg 138134Sdg 139556Srgrimes/* 140556Srgrimes * System Initialization 141556Srgrimes */ 1424Srgrimes .text 143134Sdg 144134Sdg/* 145200Sdg * btext: beginning of text section. 146200Sdg * Also the entry point (jumped to directly from the boot blocks). 147134Sdg */ 148200SdgENTRY(btext) 149757Sdg movw $0x1234,0x472 /* warm boot */ 1504Srgrimes jmp 1f 151757Sdg .space 0x500 /* skip over warm boot shit */ 1524Srgrimes 1534Srgrimes /* 154556Srgrimes * pass parameters on stack (howto, bootdev, unit, cyloffset, esym) 1554Srgrimes * note: (%esp) is return address of boot 1564Srgrimes * ( if we want to hold onto /boot, it's physical %esp up to _end) 1574Srgrimes */ 1584Srgrimes 1594Srgrimes 1: movl 4(%esp),%eax 160570Srgrimes movl %eax,_boothowto-KERNBASE 1614Srgrimes movl 8(%esp),%eax 162570Srgrimes movl %eax,_bootdev-KERNBASE 1634Srgrimes movl 12(%esp),%eax 164570Srgrimes movl %eax,_cyloffset-KERNBASE 165556Srgrimes movl 16(%esp),%eax 166570Srgrimes addl $KERNBASE,%eax 167570Srgrimes movl %eax,_esym-KERNBASE 1684Srgrimes 169556Srgrimes /* find out our CPU type. */ 170556Srgrimes pushfl 171556Srgrimes popl %eax 172556Srgrimes movl %eax,%ecx 173556Srgrimes xorl $0x40000,%eax 174556Srgrimes pushl %eax 175556Srgrimes popfl 176556Srgrimes pushfl 177556Srgrimes popl %eax 178556Srgrimes xorl %ecx,%eax 179556Srgrimes shrl $18,%eax 180556Srgrimes andl $1,%eax 181556Srgrimes push %ecx 182556Srgrimes popfl 183556Srgrimes 184556Srgrimes cmpl $0,%eax 185556Srgrimes jne 1f 186570Srgrimes movl $CPU_386,_cpu-KERNBASE 187556Srgrimes jmp 2f 188570Srgrimes1: movl $CPU_486,_cpu-KERNBASE 189556Srgrimes2: 190556Srgrimes 1914Srgrimes /* 1924Srgrimes * Finished with old stack; load new %esp now instead of later so 1934Srgrimes * we can trace this code without having to worry about the trace 1944Srgrimes * trap clobbering the memory test or the zeroing of the bss+bootstrap 1954Srgrimes * page tables. 1964Srgrimes * 1974Srgrimes * XXX - wdboot clears the bss after testing that this is safe. 1984Srgrimes * This is too wasteful - memory below 640K is scarce. The boot 1994Srgrimes * program should check: 2004Srgrimes * text+data <= &stack_variable - more_space_for_stack 2014Srgrimes * text+data+bss+pad+space_for_page_tables <= end_of_memory 2024Srgrimes * Oops, the gdt is in the carcass of the boot program so clearing 2034Srgrimes * the rest of memory is still not possible. 2044Srgrimes */ 205757Sdg movl $tmpstk-KERNBASE,%esp /* bootstrap stack end location */ 2064Srgrimes 207570Srgrimes/* 208570Srgrimes * Virtual address space of kernel: 209570Srgrimes * 210570Srgrimes * text | data | bss | [syms] | page dir | proc0 kernel stack | usr stk map | Sysmap 211757Sdg * pages: 1 UPAGES (2) 1 NKPDE (7) 212570Srgrimes */ 213570Srgrimes 2144Srgrimes/* find end of kernel image */ 215570Srgrimes movl $_end-KERNBASE,%ecx 216757Sdg addl $NBPG-1,%ecx /* page align up */ 2174Srgrimes andl $~(NBPG-1),%ecx 218757Sdg movl %ecx,%esi /* esi=start of tables */ 219757Sdg movl %ecx,_KERNend-KERNBASE /* save end of kernel */ 2204Srgrimes 221757Sdg/* clear bss */ 222570Srgrimes movl $_edata-KERNBASE,%edi 223757Sdg subl %edi,%ecx /* get mount to clear */ 224757Sdg xorl %eax,%eax /* specify zero fill */ 2254Srgrimes cld 2264Srgrimes rep 2274Srgrimes stosb 2284Srgrimes 229608Srgrimes/* 230757Sdg * If we are loaded at 0x0 check to see if we have space for the 231757Sdg * page dir/tables and stack area after the kernel and before the 640K 232757Sdg * ISA memory hole. If we do not have space relocate the page directory, 233757Sdg * UPAGES, proc 0 stack, and page table pages to start at 1MB. The value 234757Sdg * that ends up in esi, which points to the kernel page directory, is 235757Sdg * used by the rest of locore to build the tables. 236757Sdg * esi + 1(page dir) + 2(UPAGES) + 1(p0stack) + NKPDE(number of kernel 237757Sdg * page table pages) is then passed on the stack to init386(first) as 238757Sdg * the value first. esi should ALWAYS be page aligned!! 239608Srgrimes */ 240757Sdg movl %esi,%ecx /* Get current first availiable address */ 241757Sdg cmpl $0x100000,%ecx /* Lets see if we are already above 1MB */ 242757Sdg jge 1f /* yep, don't need to check for room */ 243757Sdg addl $((1+UPAGES+1+NKPDE)*NBPG),%ecx /* XXX the 4 is for kstack */ 244757Sdg /* space for kstack, PTD and PTE's */ 245757Sdg cmpl $(640*1024),%ecx /* see if it fits in low memory */ 246757Sdg jle 1f /* yep, don't need to relocate it */ 247757Sdg movl $0x100000,%esi /* won't fit, so start it at 1MB */ 248608Srgrimes1: 249608Srgrimes 250757Sdg/* clear pagetables, page directory, stack, etc... */ 251757Sdg movl %esi,%edi /* base (page directory) */ 252757Sdg movl $((1+UPAGES+1+NKPDE)*NBPG),%ecx /* amount to clear */ 253757Sdg xorl %eax,%eax /* specify zero fill */ 254757Sdg cld 255757Sdg rep 256757Sdg stosb 257757Sdg 258757Sdg/* physical address of Idle proc/kernel page directory */ 259570Srgrimes movl %esi,_IdlePTD-KERNBASE 2604Srgrimes 261592Srgrimes/* 262592Srgrimes * fillkpt 263592Srgrimes * eax = (page frame address | control | status) == pte 264592Srgrimes * ebx = address of page table 265592Srgrimes * ecx = how many pages to map 266592Srgrimes */ 2674Srgrimes#define fillkpt \ 2684Srgrimes1: movl %eax,(%ebx) ; \ 269570Srgrimes addl $NBPG,%eax ; /* increment physical address */ \ 2704Srgrimes addl $4,%ebx ; /* next pte */ \ 2714Srgrimes loop 1b ; 2724Srgrimes 2734Srgrimes/* 2744Srgrimes * Map Kernel 2754Srgrimes * 2764Srgrimes * First step - build page tables 2774Srgrimes */ 278757Sdg#if defined (KGDB) || defined (BDE_DEBUGGER) 279757Sdg movl _KERNend-KERNBASE,%ecx /* this much memory, */ 280757Sdg shrl $PGSHIFT,%ecx /* for this many PTEs */ 281757Sdg#ifdef BDE_DEBUGGER 282757Sdg cmpl $0xa0,%ecx /* XXX - cover debugger pages */ 283200Sdg jae 1f 284200Sdg movl $0xa0,%ecx 285200Sdg1: 286757Sdg#endif /* BDE_DEBUGGER */ 287757Sdg movl $PG_V|PG_KW,%eax /* having these bits set, */ 288757Sdg lea ((1+UPAGES+1)*NBPG)(%esi),%ebx /* phys addr of kernel PT base */ 289757Sdg movl %ebx,_KPTphys-KERNBASE /* save in global */ 2904Srgrimes fillkpt 2914Srgrimes 292757Sdg#else /* !KGDB && !BDE_DEBUGGER */ 293757Sdg /* write protect kernel text (doesn't do a thing for 386's - only 486's) */ 294757Sdg movl $_etext-KERNBASE,%ecx /* get size of text */ 295757Sdg shrl $PGSHIFT,%ecx /* for this many PTEs */ 296757Sdg movl $PG_V|PG_KR,%eax /* specify read only */ 297757Sdg lea ((1+UPAGES+1)*NBPG)(%esi),%ebx /* phys addr of kernel PT base */ 298757Sdg movl %ebx,_KPTphys-KERNBASE /* save in global */ 299757Sdg fillkpt 300757Sdg 301757Sdg /* data and bss are r/w */ 302757Sdg andl $PG_FRAME,%eax /* strip to just addr of bss */ 303757Sdg movl _KERNend-KERNBASE,%ecx /* calculate size */ 304757Sdg subl %eax,%ecx 305757Sdg shrl $PGSHIFT,%ecx 306757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 307757Sdg fillkpt 308757Sdg#endif 309757Sdg 310757Sdg/* now initialize the page dir, upages, p0stack PT, and page tables */ 311757Sdg 312757Sdg movl $(1+UPAGES+1+NKPDE),%ecx /* number of PTEs */ 313757Sdg movl %esi,%eax /* phys address of PTD */ 314757Sdg andl $PG_FRAME,%eax /* convert to PFN, should be a NOP */ 315757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 316757Sdg movl %esi,%ebx /* calculate pte offset to ptd */ 317757Sdg shrl $PGSHIFT-2,%ebx 318757Sdg addl %esi,%ebx /* address of page directory */ 319757Sdg addl $((1+UPAGES+1)*NBPG),%ebx /* offset to kernel page tables */ 320757Sdg fillkpt 321757Sdg 3224Srgrimes/* map I/O memory map */ 3234Srgrimes 324757Sdg movl _KPTphys-KERNBASE,%ebx /* base of kernel page tables */ 325757Sdg lea (0xa0 * PTESIZE)(%ebx),%ebx /* hardwire ISA hole at KERNBASE + 0xa0000 */ 326757Sdg movl $0x100-0xa0,%ecx /* for this many pte s, */ 327757Sdg movl $(0xa0000|PG_V|PG_KW),%eax /* valid, kernel read/write */ 328757Sdg movl %ebx,_atdevphys-KERNBASE /* save phys addr of ptes */ 3294Srgrimes fillkpt 3304Srgrimes 3314Srgrimes /* map proc 0's kernel stack into user page table page */ 3324Srgrimes 333757Sdg movl $UPAGES,%ecx /* for this many pte s, */ 334757Sdg lea (1*NBPG)(%esi),%eax /* physical address in proc 0 */ 335757Sdg lea (KERNBASE)(%eax),%edx /* change into virtual addr */ 336757Sdg movl %edx,_proc0paddr-KERNBASE /* save VA for proc 0 init */ 337757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 338757Sdg lea ((1+UPAGES)*NBPG)(%esi),%ebx /* addr of stack page table in proc 0 */ 339757Sdg addl $(KSTKPTEOFF * PTESIZE),%ebx /* offset to kernel stack PTE */ 3404Srgrimes fillkpt 3414Srgrimes 3424Srgrimes/* 343757Sdg * Initialize kernel page table directory 3444Srgrimes */ 3454Srgrimes /* install a pde for temporary double map of bottom of VA */ 346757Sdg movl _KPTphys-KERNBASE,%eax 347757Sdg orl $PG_V|PG_KW,%eax /* valid, kernel read/write */ 348757Sdg movl %eax,(%esi) /* which is where temp maps! */ 3494Srgrimes 350757Sdg /* initialize kernel pde's */ 351757Sdg movl $(NKPDE),%ecx /* for this many PDEs */ 352757Sdg lea (KPTDI*PDESIZE)(%esi),%ebx /* offset of pde for kernel */ 3534Srgrimes fillkpt 3544Srgrimes 3554Srgrimes /* install a pde recursively mapping page directory as a page table! */ 356757Sdg movl %esi,%eax /* phys address of ptd in proc 0 */ 357757Sdg orl $PG_V|PG_KW,%eax /* pde entry is valid */ 358757Sdg movl %eax,PTDPTDI*PDESIZE(%esi) /* which is where PTmap maps! */ 3594Srgrimes 3604Srgrimes /* install a pde to map kernel stack for proc 0 */ 361757Sdg lea ((1+UPAGES)*NBPG)(%esi),%eax /* physical address of pt in proc 0 */ 362757Sdg orl $PG_V|PG_KW,%eax /* pde entry is valid */ 363757Sdg movl %eax,KSTKPTDI*PDESIZE(%esi) /* which is where kernel stack maps! */ 3644Srgrimes 365757Sdg#ifdef BDE_DEBUGGER 3664Srgrimes /* copy and convert stuff from old gdt and idt for debugger */ 3674Srgrimes 368757Sdg cmpl $0x0375c339,0x96104 /* XXX - debugger signature */ 3694Srgrimes jne 1f 370570Srgrimes movb $1,_bdb_exists-KERNBASE 3714Srgrimes1: 3724Srgrimes pushal 3734Srgrimes subl $2*6,%esp 3744Srgrimes 3754Srgrimes sgdt (%esp) 376757Sdg movl 2(%esp),%esi /* base address of current gdt */ 377570Srgrimes movl $_gdt-KERNBASE,%edi 3784Srgrimes movl %edi,2(%esp) 3794Srgrimes movl $8*18/4,%ecx 380757Sdg rep /* copy gdt */ 3814Srgrimes movsl 382570Srgrimes movl $_gdt-KERNBASE,-8+2(%edi) /* adjust gdt self-ptr */ 3834Srgrimes movb $0x92,-8+5(%edi) 3844Srgrimes 3854Srgrimes sidt 6(%esp) 386757Sdg movl 6+2(%esp),%esi /* base address of current idt */ 387757Sdg movl 8+4(%esi),%eax /* convert dbg descriptor to ... */ 3884Srgrimes movw 8(%esi),%ax 389570Srgrimes movl %eax,bdb_dbg_ljmp+1-KERNBASE /* ... immediate offset ... */ 3904Srgrimes movl 8+2(%esi),%eax 391570Srgrimes movw %ax,bdb_dbg_ljmp+5-KERNBASE /* ... and selector for ljmp */ 392757Sdg movl 24+4(%esi),%eax /* same for bpt descriptor */ 3934Srgrimes movw 24(%esi),%ax 394570Srgrimes movl %eax,bdb_bpt_ljmp+1-KERNBASE 3954Srgrimes movl 24+2(%esi),%eax 396570Srgrimes movw %ax,bdb_bpt_ljmp+5-KERNBASE 3974Srgrimes 398570Srgrimes movl $_idt-KERNBASE,%edi 3994Srgrimes movl %edi,6+2(%esp) 4004Srgrimes movl $8*4/4,%ecx 401757Sdg rep /* copy idt */ 4024Srgrimes movsl 4034Srgrimes 4044Srgrimes lgdt (%esp) 4054Srgrimes lidt 6(%esp) 4064Srgrimes 4074Srgrimes addl $2*6,%esp 4084Srgrimes popal 409757Sdg#endif 4104Srgrimes 411592Srgrimes /* load base of page directory and enable mapping */ 412757Sdg movl %esi,%eax /* phys address of ptd in proc 0 */ 413570Srgrimes orl $I386_CR3PAT,%eax 414757Sdg movl %eax,%cr3 /* load ptd addr into mmu */ 415757Sdg movl %cr0,%eax /* get control word */ 416200Sdg/* 417200Sdg * XXX it is now safe to always (attempt to) set CR0_WP and to set up 418200Sdg * the page tables assuming it works, so USE_486_WRITE_PROTECT will go 419200Sdg * away. The special 386 PTE checking needs to be conditional on 420200Sdg * whatever distingiushes 486-only kernels from 386-486 kernels. 421200Sdg */ 4224Srgrimes#ifdef USE_486_WRITE_PROTECT 423570Srgrimes orl $CR0_PE|CR0_PG|CR0_WP,%eax /* enable paging */ 4244Srgrimes#else 425757Sdg orl $CR0_PE|CR0_PG,%eax /* enable paging */ 4264Srgrimes#endif 427757Sdg movl %eax,%cr0 /* and let's page NOW! */ 4284Srgrimes 429757Sdg pushl $begin /* jump to high mem */ 4304Srgrimes ret 4314Srgrimes 432570Srgrimesbegin: /* now running relocated at KERNBASE where the system is linked to run */ 4334Srgrimes 434757Sdg .globl _Crtat /* XXX - locore should not know about */ 435757Sdg movl _Crtat,%eax /* variables of device drivers (pccons)! */ 436592Srgrimes subl $(KERNBASE+0xA0000),%eax 437757Sdg movl _atdevphys,%edx /* get pte PA */ 438757Sdg subl _KPTphys,%edx /* remove base of ptes, now have phys offset */ 439757Sdg shll $PGSHIFT-2,%edx /* corresponding to virt offset */ 440757Sdg addl $KERNBASE,%edx /* add virtual base */ 441570Srgrimes movl %edx,_atdevbase 4424Srgrimes addl %eax,%edx 4434Srgrimes movl %edx,_Crtat 4444Srgrimes 445757Sdg /* set up bootstrap stack - 48 bytes */ 446570Srgrimes movl $_kstack+UPAGES*NBPG-4*12,%esp /* bootstrap stack end location */ 447757Sdg xorl %eax,%eax /* mark end of frames */ 4484Srgrimes movl %eax,%ebp 449570Srgrimes movl _proc0paddr,%eax 450570Srgrimes movl %esi,PCB_CR3(%eax) 4514Srgrimes 452757Sdg#ifdef BDE_DEBUGGER 4534Srgrimes /* relocate debugger gdt entries */ 4544Srgrimes 455757Sdg movl $_gdt+8*9,%eax /* adjust slots 9-17 */ 4564Srgrimes movl $9,%ecx 4574Srgrimesreloc_gdt: 458757Sdg movb $0xfe,7(%eax) /* top byte of base addresses, was 0, */ 459757Sdg addl $8,%eax /* now KERNBASE>>24 */ 4604Srgrimes loop reloc_gdt 4614Srgrimes 4624Srgrimes cmpl $0,_bdb_exists 4634Srgrimes je 1f 4644Srgrimes int $3 4654Srgrimes1: 466757Sdg#endif 4674Srgrimes 468608Srgrimes /* 469608Srgrimes * Skip over the page tables and the kernel stack 470608Srgrimes */ 471757Sdg lea ((1+UPAGES+1+NKPDE)*NBPG)(%esi),%esi 472608Srgrimes 473757Sdg pushl %esi /* value of first for init386(first) */ 474757Sdg call _init386 /* wire 386 chip for unix operation */ 475200Sdg 4764Srgrimes movl $0,_PTD 477757Sdg call _main /* autoconfiguration, mountroot etc */ 4784Srgrimes popl %esi 4794Srgrimes 480134Sdg /* 481570Srgrimes * now we've run main() and determined what cpu-type we are, we can 482570Srgrimes * enable WP mode on i486 cpus and above. 483134Sdg * on return from main(), we are process 1 484134Sdg * set up address space and stack so that we can 'return' to user mode 485134Sdg */ 486134Sdg 487570Srgrimes .globl __ucodesel,__udatasel 4884Srgrimes movl __ucodesel,%eax 4894Srgrimes movl __udatasel,%ecx 490570Srgrimes /* build outer stack frame */ 491757Sdg pushl %ecx /* user ss */ 492757Sdg pushl $USRSTACK /* user esp */ 493757Sdg pushl %eax /* user cs */ 494757Sdg pushl $0 /* user ip */ 4954Srgrimes movl %cx,%ds 4964Srgrimes movl %cx,%es 497757Sdg movl %ax,%fs /* double map cs to fs */ 498757Sdg movl %cx,%gs /* and ds to gs */ 499757Sdg lret /* goto user! */ 5004Srgrimes 501757Sdg pushl $lretmsg1 /* "should never get here!" */ 5024Srgrimes call _panic 5034Srgrimeslretmsg1: 5044Srgrimes .asciz "lret: toinit\n" 5054Srgrimes 5064Srgrimes 5074Srgrimes#define LCALL(x,y) .byte 0x9a ; .long y; .word x 5084Srgrimes/* 509134Sdg * Icode is copied out to process 1 and executed in user mode: 510134Sdg * execve("/sbin/init", argv, envp); exit(0); 511200Sdg * If the execve fails, process 1 exits and the system panics. 5124Srgrimes */ 513200SdgNON_GPROF_ENTRY(icode) 514757Sdg pushl $0 /* envp for execve() */ 515200Sdg 516757Sdg# pushl $argv-_icode /* can't do this 'cos gas 1.38 is broken */ 5174Srgrimes movl $argv,%eax 5184Srgrimes subl $_icode,%eax 519757Sdg pushl %eax /* argp for execve() */ 5204Srgrimes 521570Srgrimes# pushl $init-_icode 5224Srgrimes movl $init,%eax 5234Srgrimes subl $_icode,%eax 524757Sdg pushl %eax /* fname for execve() */ 5254Srgrimes 526757Sdg pushl %eax /* dummy return address */ 527200Sdg 528757Sdg movl $SYS_execve,%eax 5294Srgrimes LCALL(0x7,0x0) 530200Sdg 531570Srgrimes /* exit if something botches up in the above execve() */ 532757Sdg pushl %eax /* execve failed, the errno will do for an */ 533757Sdg /* exit code because errnos are < 128 */ 534757Sdg pushl %eax /* dummy return address */ 535757Sdg movl $SYS_exit,%eax 5364Srgrimes LCALL(0x7,0x0) 5374Srgrimes 5384Srgrimesinit: 5394Srgrimes .asciz "/sbin/init" 5404Srgrimes ALIGN_DATA 5414Srgrimesargv: 542757Sdg .long init+6-_icode /* argv[0] = "init" ("/sbin/init" + 6) */ 543757Sdg .long eicode-_icode /* argv[1] follows icode after copyout */ 5444Srgrimes .long 0 5454Srgrimeseicode: 5464Srgrimes 5474Srgrimes .globl _szicode 5484Srgrimes_szicode: 5494Srgrimes .long _szicode-_icode 5504Srgrimes 551200SdgNON_GPROF_ENTRY(sigcode) 552592Srgrimes call SIGF_HANDLER(%esp) 553757Sdg lea SIGF_SC(%esp),%eax /* scp (the call may have clobbered the */ 554757Sdg /* copy at 8(%esp)) */ 5554Srgrimes pushl %eax 556757Sdg pushl %eax /* junk to fake return address */ 557757Sdg movl $103,%eax /* XXX sigreturn() */ 558757Sdg LCALL(0x7,0) /* enter kernel with args on stack */ 559757Sdg hlt /* never gets here */ 5604Srgrimes 5614Srgrimes .globl _szsigcode 5624Srgrimes_szsigcode: 5634Srgrimes .long _szsigcode-_sigcode 564