|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1995-1994 The University of Utah and ! 3: * the Computer Systems Laboratory at the University of Utah (CSL). ! 4: * All rights reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software is hereby ! 7: * granted provided that (1) source code retains these copyright, permission, ! 8: * and disclaimer notices, and (2) redistributions including binaries ! 9: * reproduce the notices in supporting documentation, and (3) all advertising ! 10: * materials mentioning features or use of this software display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * Computer Systems Laboratory at the University of Utah.'' ! 13: * ! 14: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS ! 15: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF ! 16: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 17: * ! 18: * CSL requests users of this software to return to [email protected] any ! 19: * improvements that they make and grant CSL redistribution rights. ! 20: * ! 21: * Author: Bryan Ford, University of Utah CSL ! 22: */ ! 23: ! 24: #include <mach/machine/asm.h> ! 25: ! 26: #include "config.h" ! 27: #include "i16_crt0.h" ! 28: ! 29: .code16 ! 30: .text ! 31: ! 32: ENTRY(i16_entry) ! 33: /* DOS starts us up with our stack pointer pointing ! 34: to the very top of our BSS segment. ! 35: ds and es point to the PSP. */ ! 36: ! 37: #define DELAY jmp 1f; 1: jmp 1f; 1: jmp 1f; 1: ! 38: ! 39: /* Check to make sure we're running on a 386 or higher - ! 40: _without_ using any 32-bit instructions of course. ! 41: Tricky, since gas doesn't support 16-bit addressing modes. :-) ! 42: We can't produce any 16-bit relocations either, ! 43: because ELF doesn't support them. ! 44: This code is basically straight out of the Pentium manual, ! 45: except gassed of coursed. */ ! 46: pushfw ! 47: DELAY ! 48: popw %bx ! 49: movw $0xfff,%ax ! 50: andw %bx,%ax ! 51: pushw %ax ! 52: DELAY ! 53: popfw ! 54: DELAY ! 55: pushfw ! 56: DELAY ! 57: popw %ax ! 58: and $0xf000,%ax ! 59: cmpw $0xf000,%ax ! 60: ! 61: je 1f ! 62: orw $0xf000,%bx ! 63: pushw %bx ! 64: DELAY ! 65: popfw ! 66: DELAY ! 67: pushfw ! 68: DELAY ! 69: popw %ax ! 70: andw $0xf000,%ax ! 71: jnz 4f ! 72: 1: ! 73: /* Gak! We're running on an 8086/8088/80286! */ ! 74: callw 5f ! 75: .ascii "This program requires a 386 or better.\r\n\0" ! 76: 5: popw %si ! 77: movw %cs,%ax ! 78: movw %ax,%ds ! 79: cld ! 80: 2: lodsb ! 81: orb %al,%al ! 82: jz 3f ! 83: movb $0x02,%ah ! 84: movb %al,%dl ! 85: int $0x21 ! 86: jmp 2b ! 87: 3: movw $0x4c02,%ax ! 88: int $0x21 ! 89: 4: ! 90: /* Now we can use 32-bit instructions all we want. */ ! 91: ! 92: /* Save the PSP segment address (dx). */ ! 93: movw %ds,%dx ! 94: ! 95: /* Find our real-mode code segment (ax). */ ! 96: movw %cs,%ax ! 97: ! 98: #ifdef ENABLE_PAGE_ALIGNED_KERNEL ! 99: /* Move our code and data so that everything is on a page boundary. ! 100: Theoretically we _could_ go past the end of available memory, ! 101: since we're not checking, but it's enormously unlikely. */ ! 102: std ! 103: movw %ax,%ds ! 104: addw $0xff,%ax ! 105: andw $0xff00,%ax ! 106: movw %ax,%es ! 107: movl $EXT(edata),%ecx ! 108: subl $EXT(i16_entry_2),%ecx ! 109: movl $EXT(edata)-1,%esi ! 110: movw %si,%di ! 111: rep ! 112: movsb ! 113: ! 114: /* Start running at the new address. */ ! 115: pushl $EXT(i16_entry_2) ! 116: movw %ax,2(%esp) ! 117: lretw ! 118: ! 119: ENTRY(i16_entry_2) ! 120: /* We're now page aligned. */ ! 121: #endif ENABLE_PAGE_ALIGNED_KERNEL ! 122: ! 123: /* Load the data segment registers appropriately. */ ! 124: movw %ax,%es ! 125: movw %ax,%ss ! 126: ! 127: /* Start using a real stack. */ ! 128: movl $EXT(crt0_stack)+CRT0_STACK_SIZE,%esp ! 129: ! 130: /* Clear our BSS segment. */ ! 131: movl $EXT(edata),%edi ! 132: movl $EXT(end),%ecx ! 133: subw %di,%cx ! 134: xorb %al,%al ! 135: cld ! 136: rep ! 137: stosb ! 138: ! 139: /* Find the size of the environment array (si) ! 140: and the number of environment variables plus one (bx). ! 141: The PSP segment is still in dx. */ ! 142: movw %dx,%ds ! 143: movw 0x2c,%ds ! 144: xorw %si,%si ! 145: 1: lodsb ! 146: orb %al,%al ! 147: jnz 1b ! 148: lodsb ! 149: orb %al,%al ! 150: jnz 1b ! 151: ! 152: /* Allocate space for the environment array on the stack. ! 153: Also make sure the top 16 bits of ESP are cleared, ! 154: and that the stack pointer is longword aligned. */ ! 155: subw %si,%sp ! 156: andl $0x0000fffc,%esp ! 157: ! 158: /* Copy the environment array to the local stack. ! 159: We present it backwards, but big deal - shouldn't matter. */ ! 160: xorl %edi,%edi ! 161: movw %sp,%di ! 162: xorl %esi,%esi ! 163: pushl %esi ! 164: jmp 3f ! 165: 2: pushl %edi ! 166: stosb ! 167: 1: lodsb ! 168: stosb ! 169: orb %al,%al ! 170: jnz 1b ! 171: 3: lodsb ! 172: orb %al,%al ! 173: jnz 2b ! 174: movl %esp,%cs:EXT(environ) ! 175: ! 176: /* Copy the program name to the local stack; ! 177: it will be used as argv[0]. */ ! 178: lodsw ! 179: movw %si,%bx ! 180: 1: pushw $0 ! 181: lodsb ! 182: orb %al,%al ! 183: jz 2f ! 184: lodsb ! 185: orb %al,%al ! 186: jnz 1b ! 187: 2: movw %bx,%si ! 188: movw %sp,%di ! 189: 3: lodsb ! 190: stosb ! 191: orb %al,%al ! 192: jnz 3b ! 193: movl %esp,%ebp ! 194: ! 195: /* Build argv[1..n] from the command tail in the PSP. ! 196: Count the arguments in ebx. */ ! 197: movw %dx,%ds ! 198: xorl %ecx,%ecx ! 199: xorl %ebx,%ebx ! 200: movb 0x80,%cl /* get size of command tail */ ! 201: incw %cx /* plus the return character */ ! 202: movw $0x80,%si ! 203: addw %cx,%si /* si = ptr to return character */ ! 204: movw %sp,%di ! 205: decw %di ! 206: subw %cx,%sp /* allocate space on the stack */ ! 207: andw $0xfffc,%sp ! 208: pushl %ebx ! 209: std ! 210: 1: xorb %al,%al /* store a null terminator for this arg */ ! 211: stosb ! 212: incl %ebx ! 213: 2: cmpw $0x80,%si ! 214: je 5f ! 215: lodsb /* scan backwards for the end of an arg */ ! 216: cmpb $0x20,%al ! 217: jbe 2b ! 218: 3: stosb /* copy the arg */ ! 219: cmpw $0x80,%si ! 220: je 4f ! 221: lodsb ! 222: cmpb $0x20,%al ! 223: ja 3b ! 224: 4: movw %di,%cx /* push an arg pointer */ ! 225: incw %cx ! 226: pushl %ecx ! 227: jmp 1b ! 228: 5: ! 229: ! 230: /* Push the argv[0] pointer. */ ! 231: pushl %ebp ! 232: ! 233: /* Push the argument and envirnonment parameters on the stack. */ ! 234: movl %esp,%eax ! 235: pushl %cs:EXT(environ) ! 236: pushl %eax ! 237: pushl %ebx ! 238: ! 239: /* Release all conventional memory above the top of our BSS. ! 240: The PSP segment is still in dx. */ ! 241: movl $EXT(end)+15,%ebx ! 242: shrw $4,%bx ! 243: movw %cs,%ax ! 244: addw %ax,%bx ! 245: subw %dx,%bx ! 246: movw %dx,%es ! 247: movb $0x4a,%ah ! 248: int $0x21 ! 249: ! 250: /* Load the normal data segment registers. */ ! 251: movw %cs,%ax ! 252: movw %ax,%ds ! 253: movw %ax,%es ! 254: ! 255: /* GCC wants the direction flag cleared at all times. */ ! 256: cld ! 257: ! 258: /* Initialize the bss and run the program. */ ! 259: call EXT(i16_main) ! 260: ! 261: .globl EXT(crt0_stack) ! 262: .comm EXT(crt0_stack),CRT0_STACK_SIZE ! 263: ! 264: .globl EXT(environ) ! 265: .comm EXT(environ),4 ! 266: ! 267: ! 268: .data ! 269: ! 270: .section .anno,"aw",@progbits ! 271: P2ALIGN(4) ! 272: .globl __ANNO_START__ ! 273: __ANNO_START__: ! 274:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.