|
|
1.1 ! root 1: #undef ptable1_v ! 2: #undef ptable0_v ! 3: ! 4: /* Put the page directory at the click before the start of kernel text. */ ! 5: #define ptable0_v ((long *)(&stext[ctob(-1)])) ! 6: ! 7: /* ! 8: * mchinit() ! 9: * Initializes buddy system for (physical?) memory allocation. ! 10: * (See Knuth's Art of Computer Programming, Vol I.) ! 11: * Initializes tables for the memory management unit (mmu). ! 12: * (See Intel i386 CPU documentation.) ! 13: * ! 14: */ ! 15: ! 16: ! 17: ! 18: mchinit() ! 19: { ! 20: /* Symbols generated by linker. */ ! 21: extern char end[], /* End of kernel bss (uninitialized data). */ ! 22: edata[], /* End of kernel initialized data. */ ! 23: etext[]; /* End of kernel text segment. */ ! 24: ! 25: /* Symbols from as.s. */ ! 26: extern char stext[], /* Start of kernel text segment. */ ! 27: sdata[]; /* Start of kernel initialized data segment. */ ! 28: ! 29: register char *pe; /* Working pointer meant for abuse. */ ! 30: register zero = 0; /* */ ! 31: register i; /* Miscellaneous counter. */ ! 32: register long *lp; /* Unused */ ! 33: ! 34: register long *ptable1_v; /* Abused slave page table pointer. */ ! 35: ! 36: register n, /* Unused? */ ! 37: syse, /* Unused. */ ! 38: /* Click addr */ base; /* Counter for freeing memory (low and extended). */ ! 39: ! 40: int uaddr; /* Unused. */ ! 41: ! 42: /* These point at the slave page tables for various segments. ! 43: * They are in clicks. ! 44: */ ! 45: int sysseg, /* System segment--the entire kernel. */ ! 46: codeseg, /* User code segment. */ ! 47: dataseg, /* User data segment. */ ! 48: stackseg, /* User stack segment. */ ! 49: ptable1; /* Paging segment--most slave page tables ! 50: * get mapped to this segment. ! 51: */ ! 52: ! 53: /* Low memory is 0-640K, extended is 1M and up. */ ! 54: int lo, /* Number of bytes above kernel in low memory. */ ! 55: hi, /* Number of bytes in extended memory. */ ! 56: nalloc, /* Number of allocatable clicks in all of memory. */ ! 57: diff; /* Buddy system overhead in clicks. */ ! 58: ! 59: extern char digtab[]; /* Mystery kernel hangman. :-) */ ! 60: ! 61: static SEG uinit; /* User area for /etc/init? */ ! 62: ! 63: /* ! 64: * 1. ! 65: * a. Relocate the data on a page boundary (4K bytes) the ! 66: * bootstrap relocates it on a paragraph boundary (16 bytes) ! 67: * ! 68: * b. Verify that the data has been relocated correctly ! 69: */ ! 70: pe = edata; /* 1.a */ ! 71: /* (((unsigned)etext+15) & ~15) is where the boot code put ! 72: * the data segment. ! 73: * (unsigned)sdata is where the linker wants it to be. ! 74: * Thus "i" is the distance from where the data segment is, to ! 75: * where the data segment should be. ! 76: * ! 77: * Note that i will be negative with this kernel. ! 78: */ ! 79: i = (((unsigned)etext+15) & ~15) - (unsigned)sdata; ! 80: ! 81: /* Move a region to a (possibly overlapping) region above it. ! 82: * SIC! ! 83: */ ! 84: do { ! 85: pe--; ! 86: pe[0] = pe[i]; ! 87: } while (pe != sdata); /* 1.a */ ! 88: ! 89: /* The kernel will hang if digtab[] is not initialized such that ! 90: * digtab[0] is the character '0'. This is done by the ! 91: * compiler. ! 92: */ ! 93: while (digtab[0]!='0'); /* 1.b */ ! 94: ! 95: /* ! 96: * 2. Zero the bss ! 97: * Zero the level 0 page directory (Master page table) ! 98: */ ! 99: pe = edata; ! 100: do ! 101: *pe++ = zero; ! 102: while (pe != end); ! 103: ! 104: /* Note that ptable0_v is the click before the kernel text segment. */ ! 105: pe = (char *) ptable0_v; ! 106: do ! 107: *pe++ = zero; ! 108: while (pe != stext); ! 109: ! 110: /* ! 111: * 3. Calculate total system memory in taking ! 112: * into account the space used by the system and the page ! 113: * descriptors, the interrupt stack, and the refresh work area ! 114: * ! 115: * a. initialize allocation area and adjust system size ! 116: * to take allocation area and free page area into account ! 117: */ ! 118: /* SBASE is the click of the start of the kernel in virtual memory. ! 119: * PBASE is the click of the start of the kernel in physical memory. ! 120: * ! 121: * SBASE is 0xFFC00, PBASE is 0x02 ! 122: * ! 123: * Calculate the first click after the kernel in physical memory. ! 124: * This is in low memory (below 640k). ! 125: */ ! 126: sysmem.lo = (btoc((unsigned)end) - SBASE) + PBASE; ! 127: ! 128: /* ! 129: * These calls to c_size() should be replaced by calls to a ! 130: * routine that gets the memory size from the CMOS. ! 131: */ ! 132: lo = c_size(sysmem.lo, btoc(640*1024)); ! 133: hi = c_size(btoc(1024*1024), btoc(4096*1024)); ! 134: ! 135: /* This calculation is suspect. It may be high by 1 click. ! 136: * The problem is that a click split between extended and low ! 137: * memory cannot be allocated as a single click. ! 138: */ ! 139: nalloc = (lo+hi) / (sizeof(short) + SPLASH*sizeof(long) + ctob(1)); ! 140: areainit(SPLASH*nalloc*sizeof(long)); ! 141: sysmem.tfree = sysmem.pfree = ! 142: (unsigned short *)(end + SPLASH*nalloc*sizeof(long)); ! 143: ! 144: sysmem.hi = btoc(hi+1024*1024); ! 145: base = sysmem.lo + (lo>>BPCSHIFT); ! 146: diff = ((lo + hi) >> BPCSHIFT) - nalloc; ! 147: sysmem.lo += diff; ! 148: sysmem.vaddre = ctob(sysmem.lo+SBASE-PBASE); ! 149: /* include in system area pages for arena, free area */ ! 150: /* ! 151: * 4. ! 152: * Free the memory from [end, 640) kilobytes ! 153: * Free the memory from [1024, 16*1024) kilobytes ! 154: */ ! 155: while (base > sysmem.lo) ! 156: *sysmem.pfree++ = --base; /* push(--base) onto sysmem.pfree */ ! 157: ! 158: base = btoc(1024*1024); ! 159: while (base < sysmem.hi) ! 160: *sysmem.pfree++ = base++; /* push(base++) onto sysmem.pfree */ ! 161: ! 162: sysmem.efree = sysmem.pfree; ! 163: ! 164: /* ! 165: * 5. allocate page entries and initialize level 0 ^'s ! 166: * a. [ 00000000 .. 000400000 ) user code segment ! 167: * b. [ 00400000 .. 000800000 ) user data & bss ! 168: * c. [ 7FC00000 .. 800000000 ) user stack ! 169: * d. [ FF800000 .. FFC000000 ) pointers to level 1 page table ! 170: * e. [ FFC00000 ..1000000000 ) system process addresses ! 171: */ ! 172: codeseg = clickseg(*--sysmem.pfree); /* 5.a */ ! 173: ptable0_v[0x000] = codeseg | DIR_RW; ! 174: ! 175: dataseg = clickseg(*--sysmem.pfree); /* 5.b */ ! 176: ptable0_v[0x001] = dataseg | DIR_RW; ! 177: ! 178: stackseg = clickseg(*--sysmem.pfree); /* 5.c */ ! 179: ptable0_v[0x1FF] = stackseg | DIR_RW; ! 180: ! 181: ptable1 = clickseg(*--sysmem.pfree); /* 5.d */ ! 182: ptable0_v[0x3FE] = ptable1 | DIR_RW; ! 183: ! 184: sysseg = clickseg(*--sysmem.pfree); /* 5.e */ ! 185: ptable0_v[0x3FF] = sysseg | DIR_RW; ! 186: ! 187: /* ! 188: * 6. initialize level 2 ^'s to [5.d] ! 189: */ ! 190: ! 191: ptable1_v = (long *)(ptable1 + ctob(SBASE-PBASE)); ! 192: ptable1_v[0x000] = codeseg | SEG_SRW; ! 193: ptable1_v[0x001] = dataseg | SEG_SRW; ! 194: ptable1_v[0x1FF] = stackseg| SEG_SRW; ! 195: ptable1_v[0x3FF] = sysseg | SEG_SRW; ! 196: /* ! 197: * 7. ! 198: * b. map kernel code and data ! 199: * map ^ to: ! 200: * c. level 0 page table ! 201: * d. level 1 page table ! 202: * e. I/O segments (video RAM, ...) ! 203: */ ! 204: ! 205: ptable1_v = (long *)(sysseg + ctob(SBASE-PBASE)); /* 7.b */ ! 206: for (i = PBASE; i <sysmem.lo; i++) ! 207: ptable1_v[i-PBASE] = clickseg(i) | SEG_SRW; ! 208: ! 209: ptable1_v[0x3FE] = clickseg(PTABLE0_P) | SEG_SRW; /* 7.c */ ! 210: ptable1_v[0x3FD] = ptable1 | SEG_SRW; /* 7.d */ ! 211: ! 212: init_phy_seg(ptable1_v, ROM-SBASE, 0x0000F0000); /* 7.e. */ ! 213: init_phy_seg(ptable1_v, VIDEOa-SBASE,0x0000B0000); ! 214: init_phy_seg(ptable1_v, VIDEOb-SBASE,0x0000B8000); ! 215: /* ! 216: * 8. allocate and map U area ! 217: */ ! 218: ! 219: uinit.s_flags = SFSYST|SFCORE; /* System segment, Memory resident */ ! 220: uinit.s_size = UPASIZE; /* Size of user area in bytes. */ ! 221: uinit.s_vmem = c_alloc(btoc(UPASIZE)); /* Breaks if UPASIZE > 4k? */ ! 222: ptable1_v[0x3FF] = *uinit.s_vmem | SEG_SRW; /* Map to the top of ! 223: * the kernel area. ! 224: */ ! 225: procq.p_segp[SIUSERP] = &uinit; /* Map the u area for /etc/init, ! 226: * the first process. ! 227: */ ! 228: ! 229: /* ! 230: * 9. make FFC00000 and 00002000 map to the same address ! 231: * to prevent the prefetch after the instruction turning on ! 232: * paging from causing a page fault ! 233: */ ! 234: ! 235: ptable1_v = (long *)(codeseg + ctob(SBASE-PBASE)); ! 236: ptable1_v[PBASE] = clickseg(PBASE) | SEG_SRW; ! 237: /* ! 238: * 10. load page table base address into MMU ! 239: * fix up the interrupt vectors ! 240: */ ! 241: ! 242: mmuupd(); ! 243: idtinit(); ! 244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.