|
|
1.1 ! root 1: / Startup.s -- initilization code for any tertiary boot program. ! 2: / ! 3: / La Monte H. Yarroll <[email protected]>, September 1991 ! 4: / ! 5: / RBOOTS is set exactly 128K below the top of 640K. ! 6: / One day, RBOOTS should be dynamicly determined based on the size of ! 7: / available memory. ! 8: RBOOTS = 0x8000 / New segement for boot program. ! 9: JMPF = 0xEA / jump far, direct ! 10: SEGSIZ = 0xffff / Size of a whole segment. ! 11: NSTK = 0x2000 / # of bytes of stack. ! 12: BLOCK = 0x200 / # of bytes in a disk block ! 13: DIRSIZE = 14 / Size of a file name. ! 14: SIZEOFSDAT = 23 / sizeof(seconddat) ! 15: SECONDDAT = 0x01E7 / Offset of useful data in secondary boot. ! 16: CR = 0x0d / Carriage return ! 17: LF = 0x0a / Line Feed ! 18: NUL = 0x00 / NUL (for terminating strings) ! 19: / Interrupts. ! 20: MON = 0x00 / Invoke BIOS monitor. ! 21: KEYBD = 0x16 / Keyboard software interrupt. ! 22: REBOOT = 0x19 / Reboot through BIOS. ! 23: ! 24: ! 25: NTRK = 40 / Number of tracks on a floppy. ! 26: NSPT = 9 / Number of sectors per track on a floppy. ! 27: NHD = 1 / Number of heads per drive on a floppy. ! 28: .bssd ! 29: stack: .blkb NSTK / Local Stack ! 30: .shri ! 31: .blkb 0x100 / Symbol "begin" must be at offset 0x100 from ! 32: begin: / the beginning of the code segment--secondary ! 33: / boot jumps here. ! 34: / Upon entry ds points at the secondary boot data segment, ! 35: / si points at the data we want, ! 36: / and es points at our data segment. ! 37: mov di, $seconddat ! 38: mov cx, $SIZEOFSDAT ! 39: cld ! 40: rep ! 41: movsb / Copy disk configuration information to our own segment. ! 42: / Create a nice, safe stack. ! 43: mov bp, $stack+NSTK ! 44: mov ax, es ! 45: mov ss, ax ! 46: mov sp, bp ! 47: ! 48: push es / Save location of data segment from secondary boot. ! 49: / Move the tertiary boot to high memory. ! 50: call moveme ! 51: ! 52: add sp, $2 / Throw away old data segment. ! 53: / Set up the new stack. ! 54: mov bp, $stack+NSTK ! 55: mov ax, es ! 56: mov ss, ax ! 57: mov sp, bp ! 58: .byte JMPF / Jump to the relocated code. ! 59: .word entry ! 60: .word RBOOTS ! 61: entry: call main_ ! 62: / Aargh! main() returned! Wait for a keystroke and then reboot. ! 63: push $keymsg ! 64: call puts_ ! 65: 0: movb ah, $1 / while (!iskey()) {}; ! 66: int KEYBD / /* Read the key. */ ! 67: movb ah, $1 / } while (iskey()) ! 68: int KEYBD / /* Scan the keyboard for another key. */ ! 69: jne 1b / ! 70: int REBOOT / Reboot through the BIOS. ! 71: .shrd ! 72: keymsg: ! 73: .byte CR ! 74: .byte LF ! 75: .ascii "Press any key to reboot." ! 76: .byte CR ! 77: .byte LF ! 78: .byte NUL ! 79: //////// ! 80: / ! 81: / Move tertiary boot to high memory. ! 82: / Take one parameter--a word on the stack pointing to the current ! 83: / data segment. ! 84: / ! 85: / As a side effect, this sets ds to the new data segment in high memory. ! 86: / ! 87: //////// ! 88: .shri ! 89: moveme: ! 90: mov bp, sp / For parameter lookups. ! 91: / Move the code segment. ! 92: push cs ! 93: pop ds ! 94: xor si, si / Point ds:si at loaded code segment. ! 95: mov ax, $RBOOTS ! 96: mov es, ax ! 97: xor di, di / Point es:di at where we want to be. ! 98: mov cx, $SEGSIZ / Move a maximal segment. ! 99: cld ! 100: rep ! 101: movsb ! 102: / Calculate location of new data segment. ! 103: mov ax, 2(bp) ! 104: push cs / Fetch the code segment. ! 105: pop bx ! 106: sub ax, bx / Calculate offset to data segment. ! 107: add ax, $RBOOTS / Calculate the new data segment. ! 108: ! 109: / Move the data segment. ! 110: mov ds, 2(bp) ! 111: xor si, si / Point ds:si at loaded data segment ! 112: mov es, ax ! 113: xor di, di / Point es:di at where we want to be. ! 114: mov cx, $SEGSIZ / Move a maximal segment. ! 115: cld ! 116: rep ! 117: movsb ! 118: / Set the new data segment appropriately. ! 119: push es ! 120: pop ds ! 121: mov myds_, ds ! 122: ret / routine moveme ! 123: / Shared data segment (initialized) ! 124: .shrd ! 125: .globl myds_ ! 126: myds_: .word 0 / Place to communicate ds to C programs. ! 127: / Variables nbuf, traks, sects, and heads MUST appear in this order. ! 128: .globl seconddat ! 129: seconddat: / Data extracted from secondary boot data segment. ! 130: .globl nbuf_ ! 131: nbuf_: ! 132: nbuf: .blkb DIRSIZE ! 133: / Defaults for all the following parameters match a floppy disk. ! 134: .globl traks ! 135: .globl traks_ ! 136: traks_: ! 137: traks: .word NTRK / Number of cylinders on drive we're booting off of. ! 138: .globl sects ! 139: .globl sects_ ! 140: sects_: ! 141: sects: .byte NSPT / Number of sectors per track for our drive. ! 142: .globl heads ! 143: .globl heads_ ! 144: heads_: ! 145: heads: .byte NHD / Number of heads on drive we're booting off of. ! 146: .globl drive ! 147: .globl drive_ ! 148: drive_: ! 149: drive: .byte 0 / Drive our partition resides upon. ! 150: .globl first ! 151: .globl first_ ! 152: first_: ! 153: first: .word 0 / First block of our partition (?) ! 154: .word 0 ! 155: /* ! 156: * Determine whether or not a given argument exists on the command line ! 157: * passed into the kernel. ! 158: * ! 159: * Takes a pointer to a NUL terminated string that is the name of ! 160: * the desired argument. ! 161: */ ! 162: extern typed_space boot_gift; ! 163: int ! 164: arg_exist(arg) ! 165: { ! 166: } /* arg_exist() */ ! 167: /* ! 168: * Looks for the string "astring" in the fifo "afifo". ! 169: * Returns TRUE if it find the string. ! 170: */ ! 171: int ! 172: fifo_find_str(afifo, astring) ! 173: typed_space *afifo; ! 174: char *astring; ! 175: { ! 176: } /* fifo_find_str() */ ! 177: /* ! 178: * bio.c -- buffer handling code. ! 179: * ! 180: * This code REALLY assumes single-threaded execution. All locks are ! 181: * advisory only and may be revoked without notice. ! 182: * ! 183: * See also bread() in diskio.c. ! 184: */ ! 185: static BUF bufl[NBUF]; /* Buffer structures. */ ! 186: static char blockp[NBUF * BLOCK]; /* The blocks themselves. */ ! 187: static int buf_inited = (1==2); /* Has bufinit been called? */ ! 188: /* ! 189: * Initialise buffer headers. ! 190: */ ! 191: void ! 192: bufinit() ! 193: { ! 194: } /* bufinit() */ ! 195: /* ! 196: * Claim a buffer for a block. ! 197: * Finds the buffer if it has already been accessed, otherwise, ! 198: * picks another buffer. ! 199: */ ! 200: BUF * ! 201: bclaim(block) ! 202: daddr_t block; ! 203: { ! 204: } /* bclaim() */ ! 205: /* ! 206: * Pick the next buffer for allocation. ! 207: * Uses a round-robin scheme of buffer allocation, skipping over ! 208: * locked buffers. If all buffers are locked, they are forcibly ! 209: * unlocked and the first one is picked. ! 210: */ ! 211: BUF * ! 212: bpick() ! 213: { ! 214: } /* bpick() */ ! 215: /* ! 216: * Release a buffer for a block. ! 217: */ ! 218: void ! 219: brelease(bp) ! 220: BUF *bp; ! 221: { ! 222: } /* brelease() */ ! 223: /* ! 224: * Attempt to lock the gate 'g'. ! 225: * Return TRUE on success, FALSE if it was already locked. ! 226: */ ! 227: int ! 228: gate_lock(g) ! 229: GATE g; ! 230: { ! 231: } /* gate_lock() */ ! 232: /* ! 233: * Check to see if the gate 'g' is locked. ! 234: */ ! 235: int ! 236: gate_locked(g) ! 237: GATE g; ! 238: { ! 239: } /* gate_locked() */ ! 240: /* ! 241: * Unlock the gate 'g'. ! 242: */ ! 243: void ! 244: gate_unlock(g) ! 245: GATE g; ! 246: { ! 247: } /* gate_unlock() */ ! 248: /* ! 249: * Sanity checker. ! 250: * Prints contents of "message" if something is amiss and dumps you ! 251: * into the monitor. ! 252: * ! 253: * Add tests and messages as needed. ! 254: */ ! 255: void ! 256: sanity_check(message) ! 257: char *message; ! 258: { ! 259: } /* sanity_check() */ ! 260: //////// ! 261: / ! 262: / I/O library for use with boot programs. Uses the BIOS. ! 263: / ! 264: / La Monte H. Yarroll <[email protected]>, September 1991 ! 265: / ! 266: //////// ! 267: //////// ! 268: / ! 269: / Magic constants. ! 270: / ! 271: //////// ! 272: RETF = 0xCB / Far return ! 273: VIDEO = 0x10 / video swi ! 274: DISK = 0x13 / disk io swi ! 275: KEYBD = 0x16 / keyboard swi ! 276: MON = 0x00 / Monitor swi ! 277: READ1 = 0x0201 / read 1 sector ! 278: ! 279: BUFSIZE = 0x200 / Size of a physical disk block. ! 280: ! 281: NTRK = 40 / Number of tracks on a floppy. ! 282: NSPT = 9 / Number of sectors per track on a floppy. ! 283: NHD = 1 / Number of heads per drive on a floppy. ! 284: FIRST = 8 / Relative start of partition. ! 285: .shri / Shared code segment, initialized. ! 286: //////// ! 287: / ! 288: / Read a block from disk, relative to the start of the boot partition, ! 289: / using the code in the IBM firmware. ! 290: / ! 291: / It takes two parameters: ! 292: / daddr_t blockno; /* 32 bit block number. */ ! 293: / char *buff; /* Must point to a 512 byte buffer. */ ! 294: / ! 295: / The buffer must not cross a 4K boundry. Disk input should generally ! 296: / be done through the C routine bread(), which calls _bread() with an ! 297: / aligned buffer. ! 298: / ! 299: //////// ! 300: .globl _bread_ ! 301: _bread_: ! 302: push es / Save registers ! 303: push si ! 304: push di ! 305: push bp ! 306: push dx ! 307: push ds ! 308: pop es / Set es:bp to address of the buffer. ! 309: mov bp, sp ! 310: mov ax, 12(bp) / Get low word of block number. ! 311: mov dx, 14(bp) / Get high word of block number. ! 312: mov bx, 16(bp) / Get a buffer to put it in. ! 313: mov bp, bx ! 314: mov di, bp / Blast the buffer contents. ! 315: mov cx, $BUFSIZE / For block 0, this fills the buffer ! 316: rep / with zeros. ! 317: stosb ! 318: / Block #0 is the sparse block--it means a block of all zeros. ! 319: test ax, ax / if block 0, return zeroed buffer ! 320: jnz 3f ! 321: test dx, dx ! 322: jnz 3f ! 323: movb al, $1 / Say that we read 1 block. ! 324: jmp 2f ! 325: / Translate block number into cylinder, head, and sector. ! 326: 3: add ax, first / add first block ! 327: adc dx, first+2 / add rest ! 328: mov bx, ax / save block number ! 329: movb al, heads / get number of heads ! 330: movb cl, sects / get number of sectors ! 331: mulb cl / calculate sectors per cylinder ! 332: xchg bx,ax / swap block/sectors ! 333: div bx / calculate track ! 334: xchg dx, ax / put track in DX ! 335: divb cl / calculate head/sector ! 336: movb cl, ah / set sector ! 337: inc cx / sectors start at 1 [incb cl] ! 338: ! 339: cmp dx, traks / check for second side ! 340: jb 0f ! 341: sub dx, traks / fold track ! 342: inc ax / next head [incb al] ! 343: 0: rorb dh, $1 / rotate track(low) into ! 344: rorb dh, $1 / msbits of DX ! 345: orb cl, dh / set track(high) ! 346: movb ch, dl / set track(low) ! 347: movb dh, al / set head ! 348: movb dl, drive / set drive ! 349: mov bx, bp / set offset [bbuf] ! 350: mov ax, $READ1 / Read, 1 sector. ! 351: int DISK / Disk I/O. ! 352: jnc 2f / Jump if no error. ! 353: mov ax, $READ1 / try again ! 354: int DISK ! 355: jc berror ! 356: 2: ! 357: / al contains the number of blocks read (should be 1). ! 358: pop dx / restore registers. ! 359: pop bp ! 360: pop di ! 361: pop si ! 362: pop es ! 363: ret / return. ! 364: berror: / error handling for _bread. ! 365: xorb al, al / ah contains an error code. ! 366: jmp 2b ! 367: //////// ! 368: / ! 369: / Write the character in "al" out to ! 370: / the display, using routines in the ROM. ! 371: / Like most calls to the ROM, this routine spends ! 372: / most of its time saving and restoring the ! 373: / registers. ! 374: / ! 375: //////// ! 376: .globl putchar_ ! 377: putchar_: push si / Save registers. ! 378: push di ! 379: push bp ! 380: mov bp, sp ! 381: mov ax, 8(bp) / Fetch the single argument. ! 382: mov bx, $0x0007 / Page 0, white on black ! 383: movb ah, $0x0E / Write TTY. ! 384: int VIDEO / Call video I/O in ROM. ! 385: pop bp / Restore registers. ! 386: pop di ! 387: pop si ! 388: ret ! 389: //////// ! 390: / ! 391: / Fetch character from keyboard, using ! 392: / routines in the ROM. ! 393: / ! 394: //////// ! 395: .globl getchar_ ! 396: getchar_: ! 397: push si / Save registers. ! 398: push di ! 399: push bp ! 400: movb ah, $0x00 / Read keystroke. ! 401: int KEYBD ! 402: movb ah, $0x00 ! 403: pop bp / Restore registers. ! 404: pop di ! 405: pop si ! 406: ret ! 407: //////// ! 408: / ! 409: / Check for a pending keystroke using ! 410: / routines in the ROM. ! 411: / ! 412: //////// ! 413: .globl iskey_ ! 414: iskey_: ! 415: push si / Save registers. ! 416: push di ! 417: push bp ! 418: movb ah, $0x01 / Check for keystroke. ! 419: int KEYBD ! 420: jne 0f ! 421: xor ax, ax / Set false. ! 422: jmp 1f ! 423: 0: xor ax, ax ! 424: inc ax / Set true. ! 425: 1: pop bp / Restore registers. ! 426: pop di ! 427: pop si ! 428: ret ! 429: //////// ! 430: / ! 431: / Goto a far address ! 432: / Takes two integer arguments: an offset, and a segment, in that order. ! 433: / ! 434: //////// ! 435: .globl gotofar_ ! 436: gotofar_: ! 437: add sp, $2 ! 438: .byte RETF ! 439: //////// ! 440: / ! 441: / Goto a kernel. ! 442: / Takes three integer arguments: an offset, a segment, and a new data segment ! 443: / in that order. ! 444: / ! 445: //////// ! 446: .globl gotoker_ ! 447: gotoker_: ! 448: mov bp, sp ! 449: mov es, 6(bp) / Point es at the new data segment. ! 450: mov si, $seconddat / Point ds:si at useful data. ! 451: add sp, $2 ! 452: .byte RETF ! 453: //////// ! 454: / ! 455: / Initilize hard disk parameters ! 456: / ! 457: //////// ! 458: .globl hdinit_ ! 459: hdinit_: ! 460: push si / Save registers. ! 461: push di ! 462: push bp ! 463: mov si, bp / set si to partition table ! 464: movb dl, (si) / get drive number ! 465: movb ah, $8 / get drive parameters ! 466: int DISK ! 467: jc 1f / abort on error (just return) ! 468: movb al, ch / fetch cyl(lo) ! 469: movb ah, cl / move cyl(hi), sects ! 470: rolb ah, $1 / shift cylinder high to ! 471: rolb ah, $1 / the least sig bits ! 472: andb ah, $3 / mask out cylinder bits ! 473: mov di, $traks / point to drive ! 474: stosw / set number of tracks ! 475: movb al, $0x3F / sector mask ! 476: andb al, cl / mask sector ! 477: stosb / set sector ! 478: movb al, dh / get max head ! 479: inc ax / change to # of heads (incb al) ! 480: stosb / set number of heads ! 481: movsb / set drive ! 482: add si, $FIRST-1 / point to first block ! 483: movsw / fetch first block ! 484: movsw ! 485: 1: pop bp / Restore registers. ! 486: pop di ! 487: pop si ! 488: ret ! 489: //////// ! 490: / ! 491: / Invoke the native monitor. ! 492: / Useful for debugging. ! 493: / ! 494: //////// ! 495: .globl intmon_ ! 496: intmon_: ! 497: int MON ! 498: ret ! 499: //////// ! 500: / ! 501: / void _ffcopy(from_fp, to_fp, count) ! 502: / faddr_t from_fp, to_fp; ! 503: / int count; ! 504: / ! 505: / Copy count bytes from from_fp to to_fp. ! 506: / ! 507: / Here is the stack after initial "push bp": ! 508: / ! 509: / 12(bp) count ! 510: / 10(bp) FP_SEL(to_fp) ! 511: / 8(bp) FP_OFF(to_fp) ! 512: / 6(bp) FP_SEL(from_fp) ! 513: / 4(bp) FP_OFF(from_fp) ! 514: / 2(bp) return IP ! 515: / 0(bp) old bp ! 516: / ! 517: //////// ! 518: .globl _ffcopy_ ! 519: _ffcopy_: ! 520: push bp ! 521: mov bp, sp ! 522: push es ! 523: push di ! 524: push ds ! 525: push si ! 526: lds si, 4(bp) / from_fp to DS:SI ! 527: les di, 8(bp) / to_fp to ES:DI ! 528: mov cx, 12(bp) / rep count to CX ! 529: rep ! 530: movsb ! 531: pop si ! 532: pop ds ! 533: pop di ! 534: pop es ! 535: pop bp ! 536: ret / return from _ffcopy() ! 537: //////// ! 538: / ! 539: / Read a block from disk, relative to start of disk, ! 540: / using the code in the IBM firmware. ! 541: / ! 542: / It takes two parameters: ! 543: / daddr_t blockno; /* 32 bit block number. */ ! 544: / char *buff; /* Must point to a 512 byte buffer. */ ! 545: / ! 546: / The buffer must not cross a 4K boundry. Disk input should generally ! 547: / be done through the C routine xbread(), which calls _xbread() with an ! 548: / aligned buffer. ! 549: / ! 550: //////// ! 551: .globl _xbread_ ! 552: _xbread_: ! 553: push es / Save registers ! 554: push si ! 555: push di ! 556: push bp ! 557: push dx ! 558: push ds ! 559: pop es / Set es:bp to address of the buffer. ! 560: mov bp, sp ! 561: mov ax, 12(bp) / Get low word of block number. ! 562: mov dx, 14(bp) / Get high word of block number. ! 563: mov bx, 16(bp) / Get a buffer to put it in. ! 564: mov bp, bx ! 565: / Translate block number into cylinder, head, and sector. ! 566: 3: ! 567: mov bx, ax / save block number ! 568: movb al, heads / get number of heads ! 569: movb cl, sects / get number of sectors ! 570: mulb cl / calculate sectors per cylinder ! 571: xchg bx,ax / swap block/sectors ! 572: div bx / calculate track ! 573: xchg dx, ax / put track in DX ! 574: divb cl / calculate head/sector ! 575: movb cl, ah / set sector ! 576: inc cx / sectors start at 1 [incb cl] ! 577: ! 578: cmp dx, traks / check for second side ! 579: jb 0f ! 580: sub dx, traks / fold track ! 581: inc ax / next head [incb al] ! 582: 0: rorb dh, $1 / rotate track(low) into ! 583: rorb dh, $1 / msbits of DX ! 584: orb cl, dh / set track(high) ! 585: movb ch, dl / set track(low) ! 586: movb dh, al / set head ! 587: movb dl, drive / set drive ! 588: mov bx, bp / set offset [bbuf] ! 589: mov ax, $READ1 / Read, 1 sector. ! 590: int DISK / Disk I/O. ! 591: jnc 2f / Jump if no error. ! 592: mov ax, $READ1 / try again ! 593: int DISK ! 594: jc berror ! 595: 2: ! 596: / al contains the number of blocks read (should be 1). ! 597: pop dx / restore registers. ! 598: pop bp ! 599: pop di ! 600: pop si ! 601: pop es ! 602: ret / return. ! 603: /* builtin.c -- builtin routines for tboot. ! 604: * ! 605: * Add new ones by adding a check for them in interpret(). ! 606: * ! 607: * La Monte H. Yarroll <[email protected]>, September 1991 ! 608: */ ! 609: extern int slow_flag; /* Slow down pacifier. */ ! 610: extern int feet_flag; /* Enable pacifier footprints. */ ! 611: /* If possible, execute "command". ! 612: * Return "true" if the command exists, "false" otherwise. ! 613: */ ! 614: int ! 615: interpret(command) ! 616: char *command; ! 617: { ! 618: } /* interpret() */ ! 619: /* Display the BIOS parameters loaded up by the startup code. */ ! 620: void ! 621: dpb() ! 622: { ! 623: } /* dpb() */ ! 624: /* Ask the BIOS how many drives are attached. */ ! 625: int get_num_of_drives() ! 626: { ! 627: } /* get_num_of_drives() */ ! 628: /* Create a listing of file names in /. */ ! 629: void ! 630: dir() ! 631: { ! 632: } /* dir() */ ! 633: /* cbootlib.c -- C routines for use by boot programs. ! 634: * ! 635: * La Monte H. Yarroll <[email protected]>, September 1991 ! 636: */ ! 637: /* puts() -- put a NUL terminated string. ! 638: * Takes one argument--a pointer to a NUL terminated character string. ! 639: * Does no error checking. Calls the assembly language routine putc(). ! 640: */ ! 641: void ! 642: puts(s) ! 643: register char *s; ! 644: { ! 645: } /* puts() */ ! 646: /* gets() -- Read string from keyboard. ! 647: * Takes one argument--a pointer to a buffer big enough for the ! 648: * expected response. ! 649: * It stops reading as soon as it detects a carriage return. The CR ! 650: * is replaced with a NUL. ! 651: */ ! 652: char * ! 653: gets(s) ! 654: char *s; ! 655: { ! 656: } /* gets() */ ! 657: /* Reverse string s in place. ! 658: * Straight from K&R. ! 659: */ ! 660: void ! 661: reverse(s) ! 662: char s[]; ! 663: { ! 664: } /* reverse() */ ! 665: /* Convert n to decimal characters in s. ! 666: * Straight from K&R (with minor sylistic changes.) ! 667: */ ! 668: void ! 669: itoa(n, s) ! 670: char s[]; ! 671: int n; ! 672: { ! 673: } /* itoa() */ ! 674: /* Convert n to digits in s, base base. ! 675: * Works for any base from 2 to 36. ! 676: * Modified itoa() from K&R. ! 677: */ ! 678: void ! 679: itobase(n, s, base) ! 680: uint16 n; ! 681: char s[]; ! 682: int base; ! 683: { ! 684: } /* itobase() */ ! 685: /* basetoi(char *s, int base) ! 686: * Convert a string base "base" to an integer. ! 687: * Good through base 36. ! 688: * Loosely based on K&R's atoi(). ! 689: */ ! 690: uint16 ! 691: basetoi(s, base) ! 692: char *s; ! 693: int base; ! 694: { ! 695: } /* basetoi() */ ! 696: /* seginc(uint16 *offset, ! 697: * uint16 *segment, ! 698: * uint16 increment) ! 699: * Add an offset to a segment. We may adjust the segment base ! 700: * to make everything fit. ! 701: */ ! 702: * segments are PP aligned. ! 703: */ ! 704: ! 705: void ! 706: seginc(offset, segment, increment) ! 707: uint16 *offset; ! 708: uint16 *segment; ! 709: uint16 increment; ! 710: { ! 711: } /* seginc() */ ! 712: /* Pad a string s on the left with character c, to length n. ! 713: * The old contents of s are replaced by the padded version. ! 714: */ ! 715: char * ! 716: lpad(s, c, n) ! 717: char *s; ! 718: char c; ! 719: int n; ! 720: { ! 721: } /* lpad() */ ! 722: /* ! 723: * Print a 32 bit integer in hexadecimal. ! 724: */ ! 725: void ! 726: print32(my_int) ! 727: uint32 my_int; ! 728: { ! 729: } ! 730: /* ! 731: * Print a 16 bit integer in hexadecimal. ! 732: */ ! 733: void ! 734: print16(my_int) ! 735: uint16 my_int; ! 736: { ! 737: } ! 738: /* ! 739: * Print an 8 bit integer in hexadecimal. ! 740: */ ! 741: void ! 742: print8(my_int) ! 743: uint8 my_int; ! 744: { ! 745: } ! 746: /* ! 747: * Wrapper for far-far copy. Changes the segment so that the requested ! 748: * length does not wrap past the end of the segment. ! 749: * ! 750: * For Intel 8086 Real Mode. ! 751: */ ! 752: void ! 753: ffcopy(to_offset, to_seg, from_offset, from_seg, length) ! 754: uint16 to_offset; ! 755: uint16 to_seg; ! 756: uint16 from_offset; ! 757: uint16 from_seg; ! 758: uint16 length; ! 759: { ! 760: } /* ffcopy() */ ! 761: /* ! 762: * Align a far address so that its offset is within a paragraph of ! 763: * the start of the segment. ! 764: * ! 765: * Note that we ignore overflow in the segment, since this is exactly ! 766: * what happens when you offset past the end of the highest segment. ! 767: * ! 768: * WARNING: This routine is destructive to its arguments. ! 769: * ! 770: * For Intel 8086 Real Mode. ! 771: */ ! 772: void ! 773: seg_align(offset, segment) ! 774: uint16 *offset; ! 775: uint16 *segment; ! 776: { ! 777: } /* seg_align() */ ! 778: /* ! 779: * wait_for_keystroke() -- wait for a specific keystroke. ! 780: */ ! 781: /* Location of BIOS-run timer. */ ! 782: /* ! 783: * Waits delay ticks for the requested keystroke. Returns TRUE if ! 784: * keystroke came, FALSE if delay runs out. ! 785: * If key == -1, accept ANY keystroke. ! 786: */ ! 787: int ! 788: wait_for_keystroke(delay, key) ! 789: int delay; ! 790: int key; ! 791: { ! 792: } /* wait_for_keystrok() */ ! 793: /* coff.c -- rutines for manipulating coff executable files. */ ! 794: /* Convert COFF to load table. ! 795: * Used to generate loading instructions for use by tboot main(). ! 796: * Returns true on successful translation. ! 797: */ ! 798: int ! 799: coff2load(ip, table, data_seg) ! 800: struct inode *ip; /* input: File to read. */ ! 801: struct load_segment table[]; /* output: How to read it. */ ! 802: uint16 *data_seg; /* output: Where to point es. */ ! 803: { ! 804: } ! 805: /* ! 806: * Symbol name. ! 807: */ ! 808: static char * ! 809: symName(sym, str_tab, work) ! 810: SYMENT *sym; ! 811: char *str_tab, *work; ! 812: { ! 813: } ! 814: /* ! 815: * Look up the value of a single data symbol in a coff file, ! 816: * relative to the start of the data segment. ! 817: * ! 818: * We use the symbol "sdata" to find the start of the data segment-- ! 819: * this works for 386 COHERENT kernels but will not work in general. ! 820: * It should really fetch the address of the start of the data segment ! 821: * from the data section header. ! 822: */ ! 823: uint32 ! 824: wrap_coffnlist(fn, symbol) ! 825: char *fn; /* file name */ ! 826: char *symbol; /* symbol to look up */ ! 827: { ! 828: } /* wrap_coffnlist() */ ! 829: int ! 830: coffnlist(fn, nlp, names, count) ! 831: char *fn; /* file name */ ! 832: SYMENT *nlp; /* names to look up */ ! 833: char *names; /* long names */ ! 834: int count; /* size of passed table */ ! 835: { ! 836: } ! 837: main() ! 838: { ! 839: } ! 840: /* diskio.c -- C routines for disk i/o in tertiary boot programs. ! 841: * ! 842: * La Monte H. Yarroll <[email protected]>, September 1991 ! 843: */ ! 844: /* Aligning bread. ! 845: * Reads 1 block into an arbitrary buffer. The assembly language ! 846: * routine bread() needs a buffer aligned on a 4K boundary. ! 847: */ ! 848: char bufspace[FOURK+BLOCK]; ! 849: char *lbuf = NULL; /* Buffer for bread. */ ! 850: BUF * ! 851: bread(blockno) ! 852: daddr_t blockno; /* Block number. */ ! 853: { ! 854: } /* bread() */ ! 855: /* ! 856: * Inode OPEN: Load the inode for a file into memory. ! 857: * iopen(struct inode *ip, ! 858: * ino_t inode_number) ! 859: * ! 860: */ ! 861: int ! 862: iopen(meminode, inode_number) ! 863: struct inode *meminode; ! 864: ino_t inode_number; ! 865: { ! 866: } /* iopen() */ ! 867: /* Convert a filename to an inode number. Returns inode number 0 on ! 868: * failure. ! 869: */ ! 870: ino_t ! 871: namei(filename) ! 872: char *filename; ! 873: { ! 874: } /* namei() */ ! 875: /* ! 876: * Inode READ: Load a local buffer from a file. ! 877: * iread(struct inode *ip, ! 878: * char *buffer, ! 879: * fsize_t offset, ! 880: * uint16 lenarg); ! 881: */ ! 882: void ! 883: iread(ip, buffer, offset, lenarg) ! 884: struct inode *ip; /* Read from this file, */ ! 885: char *buffer; /* into this buffer, */ ! 886: fsize_t offset; /* from here in the file, */ ! 887: uint16 lenarg; /* for this many bytes. */ ! 888: { ! 889: } /* iread() */ ! 890: /* ! 891: * Inode to Far READ: Load an arbitrary length from a file into a far address. ! 892: * ifread(struct inode *ip, ! 893: * uint16 toseg, ! 894: * uint16 tooffset, ! 895: * fsize_t offset, ! 896: * fsize_t length); ! 897: */ ! 898: void ! 899: ifread(ip, toseg, tooffset, offset, lenarg) ! 900: struct inode *ip; /* Read from this file, */ ! 901: uint16 toseg; /* into this far buffer, */ ! 902: uint16 tooffset; ! 903: fsize_t offset; /* from here in the file, */ ! 904: fsize_t lenarg; /* for this many bytes. */ ! 905: { ! 906: } /* ifread() */ ! 907: /* Aligning xbread. ! 908: * Disk addresses are relative to the start of the disk, rather than ! 909: * the start of the partition. ! 910: * Reads 1 block into an arbitrary buffer. The assembly language ! 911: * routine xbread() needs a buffer aligned on a 4K boundary. ! 912: */ ! 913: BUF * ! 914: xbread(blockno) ! 915: daddr_t blockno; /* Block number. */ ! 916: { ! 917: } /* xbread() */ ! 918: /* ! 919: * ! 920: * fdisk( fp ) -- Fixed Disk Configuration ! 921: * dev_t dev; ! 922: * struct fdisk_s *fp; ! 923: * ! 924: * Input: fp = pointer to memory-resident partition info (to update) ! 925: * ! 926: * Action: Read first block from the device. ! 927: * If valid signature present on block, ! 928: * copy partition information to memory ! 929: * ! 930: * Return: 1 = partition information successfully updated ! 931: * 0 = failure (could not read block, or bad signature) ! 932: */ ! 933: int ! 934: fdisk( fp ) ! 935: register FDISK_S *fp; ! 936: { ! 937: } ! 938: /* ! 939: * fifo_b.c -- Extra routines for handling typed fifos. ! 940: * Both fifo_b.c (boot fifo) and fifo_k.c (kernel fifo) are needed by the ! 941: * boot code. ! 942: */ ! 943: /* How long is an open fifo? */ ! 944: long ! 945: fifo_len(ffp) ! 946: FIFO *ffp; ! 947: { ! 948: } /* fifo_len() */ ! 949: /* Write a typed space into a FIFO. */ ! 950: typed_space * ! 951: fifo_write(ffp, space) ! 952: FIFO *ffp; ! 953: typed_space *space; ! 954: { ! 955: } /* fifo_write() */ ! 956: /* Write a chunk of data into an open fifo as a typed space. ! 957: * Takes a FIFO to be written to, ffp; a pointer to the data, datum; a ! 958: * size for the datum, size; and a type for the new space, type. ! 959: * ! 960: * Returns a pointer to the newly written space. Returns NULL if the ! 961: * new space could not be written. ! 962: * ! 963: * Note that while sizes throughout this package refer to TOTAL sizes ! 964: * including headers, the size argument here is ONLY for the datum. ! 965: * ! 966: * Only FIFOs of type T_FIFO_SIC are implimented. ! 967: */ ! 968: typed_space * ! 969: fifo_write_untyped(ffp, datum, size, type) ! 970: FIFO *ffp; ! 971: char *datum; ! 972: long size; ! 973: space_type type; ! 974: { ! 975: } /* fifo_write_untyped() */ ! 976: /* ! 977: * fifo_k.c -- Routines for reading interally typed fifos. ! 978: * These are all that need to be included in the kernel. ! 979: */ ! 980: /* The input channel from tboot to the kernel. */ ! 981: TYPED_SPACE(boot_gift, 512, T_FIFO_SIC); ! 982: /* Read a typed space from a fifo. ! 983: * Return a pointer to the next typed space in the fifo ffp. Returns ! 984: * NULL on end of fifo. ! 985: * ! 986: * This read assumes that ffp->f_space has type T_FIFO_SIC. ! 987: */ ! 988: typed_space * ! 989: fifo_read(ffp) ! 990: register FIFO *ffp; ! 991: { ! 992: } /* fifo_read() */ ! 993: /* Go back to the start of the fifo. ! 994: * Takes a FIFO. For reading, go back to the first space; for writing ! 995: * truncate the FIFO to empty. ! 996: * Returns 1 on success, 0 otherwise. ! 997: */ ! 998: int ! 999: fifo_rewind(ffp) ! 1000: FIFO *ffp; ! 1001: { ! 1002: } /* fifo_rewind() */ ! 1003: /* Finish with using a typed space as a fifo. ! 1004: * Free up FIFO structure associated with a typed space. ! 1005: * Returns 0 if ffp was not open, 1 otherwise. ! 1006: */ ! 1007: int ! 1008: fifo_close(ffp) ! 1009: FIFO *ffp; ! 1010: { ! 1011: } /* fifo_close() */ ! 1012: /* Open a typed space as a fifo. ! 1013: * ! 1014: * Takes a typed_space that is already allocated, and a mode. The type of ! 1015: * the typed space must be a FIFO. Only T_FIFO_SIC has been implimented ! 1016: * (static, in-core fifo). ! 1017: * ! 1018: * The mode indicates whether to open for reading or writing. ! 1019: * mode == 0 means read only. ! 1020: * mode == 1 means write only. ! 1021: * Other values are illegal. ! 1022: * ! 1023: * Returns a pointer to an initialized FIFO structure. FIFO structures are ! 1024: * allocated from a pre-allocated array. Returns F_NULL if it can't open ! 1025: * the fifo. ! 1026: */ ! 1027: FIFO * ! 1028: fifo_open(fifo_space, mode) ! 1029: typed_space *fifo_space; ! 1030: int mode; ! 1031: { ! 1032: } /* fifo_open() */ ! 1033: /* This is the typed space we will use for our FIFO operations. */ ! 1034: TYPED_SPACE(global_space, 128, T_FIFO_SIC); /* Static In-Core Fifo. */ ! 1035: int ! 1036: main() ! 1037: { ! 1038: } /* main() */ ! 1039: /* gift.c -- Prepare a gift of information for the program currently loaded. ! 1040: * ! 1041: * To pass a new data structure into the kernel: ! 1042: * ! 1043: * 1. Define your new data structure in typed.h. You will probably want ! 1044: * to define some supporting routines for your data structure. These ! 1045: * should go in a file by themselves. Be sure to add the file to the ! 1046: * tboot Makefile. ! 1047: * ! 1048: * 2. Write a routine that takes at least an ffp, which will generate your ! 1049: * data structure and write it into the ffp. The routine should return 0 ! 1050: * if it ran out of space in the FIFO. Other return values are permissible, ! 1051: * but ignored. Add arguments to prepare_gift() as needed. It is called ! 1052: * only from the end of main() in tboot.c ! 1053: * ! 1054: * 3. Add a call to your routine to prepare_gift() in the section marked ! 1055: * FILL THE BOX. This is an if statement with || seperated calls. The ! 1056: * most important data structures should be called first, because later ! 1057: * calls will be skipped if the FIFO fills. ! 1058: * ! 1059: * 4. In the kernel (probably in a driver) you will want to add a loop to ! 1060: * look through the gift for your data structure: ! 1061: * ! 1062: * FIFO *ffp; ! 1063: * typed_space *tp; ! 1064: * ! 1065: * ffp = fifo_open(&boot_gift, 0); -- Open gift for reading. ! 1066: * ! 1067: * if (F_NULL == ffp) { ! 1068: * indicate_error("Could not open boot_gift."); ! 1069: * } else { ! 1070: * while (T_NULL != (tp = fifo_read(ffp))) { -- While not EOFIFO. ! 1071: * if (T_MYTYPE == tp->ts_type) { -- Is this my type? ! 1072: * my_handler(tp->ts_data); -- Process the data. ! 1073: * } ! 1074: * } ! 1075: * } ! 1076: * ! 1077: * Be sure to include fifo.c and typed.h into your kernel. ! 1078: * ! 1079: */ ! 1080: /* We have to build the gift in the local segment and then copy it in ! 1081: * place. In a better world, the gift could be built in place. ! 1082: */ ! 1083: TYPED_SPACE(local_gift, GIFTBOX, T_FIFO_SIC); /* Static In-Core Fifo. */ ! 1084: /* Prepare a gift of information for the program currently loaded. ! 1085: * ! 1086: * The gift is a Static In-Core FIFO whose objects are typed spaces. ! 1087: * ! 1088: * cmd_line is the command line needby by gift_argf(). ! 1089: * ! 1090: * It should be placed in memory at data_seg:offset. ! 1091: */ ! 1092: void ! 1093: prepare_gift(data_seg, offset, cmd_line) ! 1094: uint16 data_seg; ! 1095: uint16 offset; ! 1096: char *cmd_line; ! 1097: { ! 1098: } /* prepare_gift() */ ! 1099: /* Load the BIOS parameters loaded up by the startup code. */ ! 1100: int ! 1101: gift_drive_params(ffp) ! 1102: FIFO *ffp; ! 1103: { ! 1104: } /* gift_drive_params() */ ! 1105: /* We'd really rather have a dynamic in-core fifo, but they are not ! 1106: * yet implimented. We'll have to settle for a fixed length argument list. ! 1107: */ ! 1108: TYPED_SPACE(argf, BLOCK, T_FIFO_SIC); ! 1109: /* ! 1110: * To read this item from bootgift, use the procedure outlined above in ! 1111: * point 4 to find the entry marked T_STR_ARGF. You must then explicitly ! 1112: * recast it with RETYPE(tp->ts_data, T_FIFO_SIC). Then you can open it ! 1113: * as a FIFO, with code modeled on point 4 above. This scheme seemed ! 1114: * the simplest for uniquely identifying the argument FIFO. ! 1115: * Each element of the FIFO is a T_STR_STR, so ts_data for these is ! 1116: * just a NUL terminated string. You can a ! 1117: */ ! 1118: /* Write an argument fifo into ffp from the command line cmd_line. ! 1119: * Returns 0 if it runs out of space, 1 on success, and 2 if something else ! 1120: * goes wrong. ! 1121: */ ! 1122: int ! 1123: gift_argf(ffp, cmd_line) ! 1124: FIFO *ffp; ! 1125: char *cmd_line; ! 1126: { ! 1127: } /* gift_argf() */ ! 1128: /* Write a structure describing the boot partition into a fifo. ! 1129: * Returns 1 on success, 0 if it runs out of space, or 2 if it ! 1130: * can't read the boot block. ! 1131: */ ! 1132: int ! 1133: gift_rootdev(ffp) ! 1134: FIFO *ffp; ! 1135: { ! 1136: } /* gift_rootdev() */ ! 1137: /* Dump the contents of boot_gift. */ ! 1138: void ! 1139: dump_gift() ! 1140: { ! 1141: } ! 1142: /* Dump the contents of a fifo. */ ! 1143: void ! 1144: dump_fifo(fifo) ! 1145: typed_space *fifo; ! 1146: { ! 1147: } /* dump_gift() */ ! 1148: /* Dump a T_BIOS_DISK typed_space. */ ! 1149: void ! 1150: dump_bios_disk(a_disk) ! 1151: BIOS_DISK *a_disk; ! 1152: { ! 1153: } /* dump_bios_disk() */ ! 1154: /* Dump a T_BIOS_ROOTDEV typed_space. */ ! 1155: void ! 1156: dump_rootdev(a_rootdev) ! 1157: BIOS_ROOTDEV *a_rootdev; ! 1158: { ! 1159: } /* dump_rootdev() */ ! 1160: /* ! 1161: * Handle the indirections in Unix-style file system. ! 1162: * ! 1163: * Uses a recursive scheme to follow up indirections. ! 1164: * ! 1165: * Needs optimization. A good place to start would be caching of ! 1166: * lookup tables. ! 1167: * ! 1168: * La Monte H. Yarroll <[email protected]>, September 1991 ! 1169: */ ! 1170: extern BUF *bread(); ! 1171: daddr_t vmap(); ! 1172: daddr_t indirect(); ! 1173: daddr_t ind_lookup(); ! 1174: uint16 ind_index(); ! 1175: /* Convert the given virtual block to a physical block for the given inode. ! 1176: * ip points to the in-core inode for a file. ! 1177: * vblockno is a block number relative to the start of that file. ! 1178: */ ! 1179: daddr_t ! 1180: vmap(ip, vblockno) ! 1181: struct inode *ip; ! 1182: daddr_t vblockno; ! 1183: { ! 1184: } /* vmap() */ ! 1185: /* indirect(uint16 ind_level, daddr_t ind_table_ptr, daddr_t vblockno) ! 1186: * Recursively follow an indirection for a given virtual block number ! 1187: * vblockno. ! 1188: * ind_level must be the level of indirection still un-resolved. ! 1189: * ind_table is the physical block number of the next indirection. ! 1190: */ ! 1191: daddr_t ! 1192: indirect(ind_level, ind_table_ptr, vblockno) ! 1193: uint16 ind_level; ! 1194: daddr_t ind_table_ptr; ! 1195: daddr_t vblockno; ! 1196: { ! 1197: } /* indirect() */ ! 1198: /* ind_lookup(uint16 ind_level, daddr_t *ind_table, daddr_t vblockno) ! 1199: * Look up the next level of block in table ind_table, for virtual ! 1200: * block number vblockno. ! 1201: * Note that this table is in DISK CANNONICAL format. If the local ! 1202: * notion of daddr_t is a different size from DISK CANONICAL daddr_t ! 1203: */ ! 1204: daddr_t ! 1205: ind_lookup(ind_level, ind_table, vblockno) ! 1206: uint16 ind_level; ! 1207: daddr_t *ind_table; ! 1208: daddr_t vblockno; ! 1209: { ! 1210: } ! 1211: /* uint16 ind_index(uint16 ind_level, daddr_t vblockno); ! 1212: * Calculate the index needed for virtual block vblockno into ! 1213: * a table of the given indirection level. ! 1214: */ ! 1215: * NBN = 128 entries = 7 bit address. ! 1216: */ ! 1217: uint16 ! 1218: ind_index(ind_level, vblockno) ! 1219: uint16 ind_level; ! 1220: daddr_t vblockno; ! 1221: {} ! 1222: ////////// ! 1223: / From MSDOS MWC86 system call interface. ! 1224: / Interrupt simulation. ! 1225: / Modified for use with tertiary boot code for COHERENT. ! 1226: / ! 1227: / Modified September 1991 by La Monte H. Yarroll <[email protected]> ! 1228: / ! 1229: / DANGER!! THIS IS SELF MODIFYING CODE. IT WILL ONLY WORK IN A STRICTLY ! 1230: / SINGLE THREADED ENVIRONMENT. ! 1231: ////////// ! 1232: ////////// ! 1233: / void ! 1234: / intcall(src, dest, intnum) ! 1235: / struct reg *src; /* All regs are loaded except flags */ ! 1236: / struct reg *dest; /* All regs are stored here */ ! 1237: / int intnum; /* Int number */ ! 1238: ////////// ! 1239: src = 6+RASIZE ! 1240: dest = src+PTRSIZE ! 1241: intnum = dest+PTRSIZE ! 1242: .globl intcall_ ! 1243: intcall_: ! 1244: push si / Save register variables. ! 1245: push di ! 1246: push bp ! 1247: mov bp, sp ! 1248: movb al, intnum(bp) / Get intnum in AL ! 1249: movb cs:myint+1, al / Modify the code ! 1250: Lds si, src(bp) / Load DS:SI with src pointer. ! 1251: mov ax, (si) / Set AX ! 1252: mov bx, 2(si) / and BX ! 1253: mov cx, 4(si) / and CX ! 1254: mov dx, 6(si) / and DX ! 1255: mov di, 10(si) / and DI, ! 1256: push 12(si) / save src DS, ! 1257: mov es, 14(si) / set ES ! 1258: mov si, 8(si) / and SI ! 1259: pop ds / and DS. ! 1260: / Actually do the interrupt. ! 1261: myint: int 0 / This instruction gets modified. ! 1262: / The interrupt handler preserves SS:SP. ! 1263: / The iret to the handler pops the handler address and flags pushed above, ! 1264: / the iret from the handler pops the retint address and flags. ! 1265: retint: ! 1266: mov bp, sp / Restore BP. ! 1267: pushf / Save result flags ! 1268: push es / and ES ! 1269: push ds / and DS ! 1270: push si / and SI. ! 1271: mov si, ss ! 1272: mov ds, si / Restore DS ! 1273: mov es, si / and ES. ! 1274: Lds si, dest(bp) / Get dest in DS:SI. ! 1275: mov (si), ax / Load dest with returned AX ! 1276: mov 2(si), bx / and BX ! 1277: mov 4(si), cx / and CX ! 1278: mov 6(si), dx / and DX ! 1279: pop 8(si) / and SI ! 1280: mov 10(si), di / and DI ! 1281: pop 12(si) / and DS ! 1282: pop 14(si) / and ES ! 1283: pop 16(si) / and flags. ! 1284: pop bp ! 1285: pop di ! 1286: pop si ! 1287: Gret ! 1288: / end of intcall.m ! 1289: /* l.out.c -- routines for manipulating l.out executable files. */ ! 1290: /* Convert l.out to load table. ! 1291: * Used to generate loading instructions for use by tboot main(). ! 1292: * Returns true on successful translation. ! 1293: */ ! 1294: int ! 1295: lout2load(ip, table, data_seg) ! 1296: struct inode *ip; /* input: File to read. */ ! 1297: struct load_segment table[]; /* output: How to read it. */ ! 1298: uint16 *data_seg; /* output: Where to point es. */ ! 1299: { ! 1300: } ! 1301: /* ! 1302: * Get entries from l.out name list. ! 1303: */ ! 1304: void ! 1305: l_out_nlist(fn, nlp) ! 1306: char *fn; ! 1307: struct nlist *nlp; ! 1308: { ! 1309: } ! 1310: /* Mini-monitor for testing boot code. ! 1311: * ! 1312: * La Monte H. Yarroll <[email protected]>, September 1991 ! 1313: */ ! 1314: void ! 1315: monitor() ! 1316: { ! 1317: } ! 1318: /* objects.c -- routines for handling different object formats. ! 1319: * Currently, only COFF and COHERENT l.out are supported. ! 1320: */ ! 1321: /* Extract information from an object file that describes how to ! 1322: * load an executable. ! 1323: * The magic number of the file is in "magic". ! 1324: * The object file's inode is in "ip". ! 1325: * ! 1326: * The information needed is extracted into "table". ! 1327: * The value for the data segment is put in "data_seg". ! 1328: * ! 1329: * Returns TRUE if the needed information could be extracted, FALSE ow. ! 1330: */ ! 1331: int ! 1332: object2load(magic, ip, table, data_seg) ! 1333: uint16 magic; ! 1334: struct inode *ip; ! 1335: struct load_segment table[]; ! 1336: uint16 *data_seg; ! 1337: { ! 1338: } /* object2load() */ ! 1339: /* Look up symbol(s) in an object file. ! 1340: * searches the name list (symbol table) of the load module ! 1341: * "filename" for each symbol in the array pointed to by "nlp". ! 1342: * ! 1343: * nlp points to an array of nlist structures, terminated by a ! 1344: * structure with a null string as its n_name member. ! 1345: * ! 1346: * If "filename" is not a load module or has had its symbol table ! 1347: * stripped, all returned n_type and n_value entries will be zero. ! 1348: * ! 1349: */ ! 1350: uint16 ! 1351: object_nlist(magic, filename, symbol) ! 1352: uint16 magic; ! 1353: char *filename; ! 1354: char *symbol; ! 1355: { ! 1356: } /* object_nlist() */ ! 1357: /* Determine the value for sys_base based on the type of the load file. */ ! 1358: uint16 ! 1359: object_sys_base(magic) ! 1360: int magic; ! 1361: { ! 1362: } /* object_sys_base() */ ! 1363: main() ! 1364: { ! 1365: } /* main () */ ! 1366: /* ! 1367: * pacifier.c - state machine for putting something interesting on the screen. ! 1368: */ ! 1369: int slow_flag = FALSE; /* Slow down pacifier. */ ! 1370: int feet_flag = FALSE; /* Print footprints? */ ! 1371: void pac_init(); /* Initialise the state machine. */ ! 1372: void pac_cleanup(); /* Clean up after the state machine. */ ! 1373: void pacifier(); /* Run the next step of the state machine. */ ! 1374: void subliminal(); /* Print a subliminal message. */ ! 1375: static int pac_inited = FALSE; /* Has pac_init() been called? */ ! 1376: static int pac_dirty = FALSE; /* Has pacifier() been called? */ ! 1377: static int state; ! 1378: static int substate; ! 1379: static int count; ! 1380: void ! 1381: pacifier() ! 1382: { ! 1383: } /* pacifier() */ ! 1384: /* ! 1385: * Print a subliminal message on the console. ! 1386: * It does this by printing the message, backspacing over it, ! 1387: * spacing over it, and the backspacing again. ! 1388: */ ! 1389: void ! 1390: subliminal(msg) ! 1391: char *msg; ! 1392: { ! 1393: } /* subliminal() */ ! 1394: /* ! 1395: * Initialize the pacifier state machine. ! 1396: */ ! 1397: void ! 1398: pac_init() ! 1399: { ! 1400: } /* pac_init() */ ! 1401: /* ! 1402: * Clean up the screen after the pacifier. ! 1403: */ ! 1404: void ! 1405: pac_cleanup() ! 1406: { ! 1407: } /* pac_cleanup() */ ! 1408: /* sys.c -- Simulate kernel calls for file i/o. ! 1409: */ ! 1410: int errno; ! 1411: /* Table of file descriptors. */ ! 1412: static FD u_filep[NUFILE]; ! 1413: static struct inode ip_table[NUFILE]; ! 1414: static inited = (1==2); ! 1415: /* Open a file. ! 1416: * Takes a file name, file; and a way of opening it, type as follows: ! 1417: * 0 Read only ! 1418: * 1 Write ! 1419: * 2 Read and write ! 1420: * Only read is implimented. ! 1421: * ! 1422: * Returns a file descriptor, or -1 if the open failed. ! 1423: */ ! 1424: int ! 1425: open(file, type) ! 1426: char *file; ! 1427: int type; ! 1428: { ! 1429: } /* open() */ ! 1430: /* Read from a file. ! 1431: * Takes a file descriptor, a buffer, and a length to read. ! 1432: * ! 1433: * Returns the number of characters read, or -1 if an error occurs. ! 1434: */ ! 1435: int ! 1436: read(fd, buffer, n) ! 1437: int fd; ! 1438: char *buffer; ! 1439: int n; ! 1440: { ! 1441: } /* read() */ ! 1442: /* Close a file. ! 1443: * Takes a file descriptor. ! 1444: */ ! 1445: int ! 1446: close(fd) ! 1447: int fd; ! 1448: { ! 1449: } /* close() */ ! 1450: /* Set a read/write position. ! 1451: * Changes the seek position for file descriptor fd. ! 1452: * where and how describe the new seek position. where gives the ! 1453: * number of bytes that you wish to move the seek position; it is ! 1454: * measured from the beginning of the file if how is zero, from the ! 1455: * current seek position if how is one, or from the end of the file ! 1456: * if how is two. A successful call to lseek returns the new seek ! 1457: * position; a failure returns (int32) -1. ! 1458: */ ! 1459: long ! 1460: lseek(fd, where, how) ! 1461: int fd; ! 1462: long where; ! 1463: int how; ! 1464: { ! 1465: } /* lseek() */ ! 1466: /* tboot.c -- tertiary boot ! 1467: * This is invoked by the secondary boot to do all the things we can't ! 1468: * do in just 512 bytes. ! 1469: * ! 1470: * Includes an interpreter for builtin commands. Just type "info" or "dir" ! 1471: * to get disk information, or a directory listing of "/". ! 1472: * ! 1473: * Can load an image up to 1 gigabyte in length. Segments can be as ! 1474: * big as the whole file. ! 1475: * ! 1476: * La Monte H. Yarroll <[email protected]>, September 1991 ! 1477: */ ! 1478: /* Potentially communicated information from an earlier tboot. */ ! 1479: TYPED_SPACE(boot_gift, 8192, T_FIFO_SIC); /* Static In-Core FIFO. */ ! 1480: main() ! 1481: { ! 1482: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.