|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2006 Michael Brown <[email protected]>. ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of the ! 7: * License, or any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: * ! 18: */ ! 19: ! 20: FILE_LICENCE ( GPL2_OR_LATER ) ! 21: ! 22: .arch i386 ! 23: ! 24: /* Image compression enabled */ ! 25: #define COMPRESS 1 ! 26: ! 27: /* Protected mode flag */ ! 28: #define CR0_PE 1 ! 29: ! 30: /* Allow for DBG()-style messages within libprefix */ ! 31: #ifdef NDEBUG ! 32: .macro progress message ! 33: .endm ! 34: #else ! 35: .macro progress message ! 36: pushfl ! 37: pushw %ds ! 38: pushw %si ! 39: pushw %di ! 40: pushw %cs ! 41: popw %ds ! 42: xorw %di, %di ! 43: movw $progress_\@, %si ! 44: call print_message ! 45: popw %di ! 46: popw %si ! 47: popw %ds ! 48: popfl ! 49: .section ".prefix.data", "aw", @progbits ! 50: progress_\@: ! 51: .asciz "\message" ! 52: .size progress_\@, . - progress\@ ! 53: .previous ! 54: .endm ! 55: #endif ! 56: ! 57: /***************************************************************************** ! 58: * Utility function: print character (with LF -> LF,CR translation) ! 59: * ! 60: * Parameters: ! 61: * %al : character to print ! 62: * %ds:di : output buffer (or %di=0 to print to console) ! 63: * Returns: ! 64: * %ds:di : next character in output buffer (if applicable) ! 65: ***************************************************************************** ! 66: */ ! 67: .section ".prefix.lib", "awx", @progbits ! 68: .code16 ! 69: .globl print_character ! 70: print_character: ! 71: /* Preserve registers */ ! 72: pushw %ax ! 73: pushw %bx ! 74: pushw %bp ! 75: /* If %di is non-zero, write character to buffer and exit */ ! 76: testw %di, %di ! 77: jz 1f ! 78: movb %al, %ds:(%di) ! 79: incw %di ! 80: jmp 3f ! 81: 1: /* Print character */ ! 82: movw $0x0007, %bx /* page 0, attribute 7 (normal) */ ! 83: movb $0x0e, %ah /* write char, tty mode */ ! 84: cmpb $0x0a, %al /* '\n'? */ ! 85: jne 2f ! 86: int $0x10 ! 87: movb $0x0d, %al ! 88: 2: int $0x10 ! 89: /* Restore registers and return */ ! 90: 3: popw %bp ! 91: popw %bx ! 92: popw %ax ! 93: ret ! 94: .size print_character, . - print_character ! 95: ! 96: /***************************************************************************** ! 97: * Utility function: print a NUL-terminated string ! 98: * ! 99: * Parameters: ! 100: * %ds:si : string to print ! 101: * %ds:di : output buffer (or %di=0 to print to console) ! 102: * Returns: ! 103: * %ds:si : character after terminating NUL ! 104: * %ds:di : next character in output buffer (if applicable) ! 105: ***************************************************************************** ! 106: */ ! 107: .section ".prefix.lib", "awx", @progbits ! 108: .code16 ! 109: .globl print_message ! 110: print_message: ! 111: /* Preserve registers */ ! 112: pushw %ax ! 113: /* Print string */ ! 114: 1: lodsb ! 115: testb %al, %al ! 116: je 2f ! 117: call print_character ! 118: jmp 1b ! 119: 2: /* Restore registers and return */ ! 120: popw %ax ! 121: ret ! 122: .size print_message, . - print_message ! 123: ! 124: /***************************************************************************** ! 125: * Utility functions: print hex digit/byte/word/dword ! 126: * ! 127: * Parameters: ! 128: * %al (low nibble) : digit to print ! 129: * %al : byte to print ! 130: * %ax : word to print ! 131: * %eax : dword to print ! 132: * %ds:di : output buffer (or %di=0 to print to console) ! 133: * Returns: ! 134: * %ds:di : next character in output buffer (if applicable) ! 135: ***************************************************************************** ! 136: */ ! 137: .section ".prefix.lib", "awx", @progbits ! 138: .code16 ! 139: .globl print_hex_dword ! 140: print_hex_dword: ! 141: rorl $16, %eax ! 142: call print_hex_word ! 143: rorl $16, %eax ! 144: /* Fall through */ ! 145: .size print_hex_dword, . - print_hex_dword ! 146: .globl print_hex_word ! 147: print_hex_word: ! 148: xchgb %al, %ah ! 149: call print_hex_byte ! 150: xchgb %al, %ah ! 151: /* Fall through */ ! 152: .size print_hex_word, . - print_hex_word ! 153: .globl print_hex_byte ! 154: print_hex_byte: ! 155: rorb $4, %al ! 156: call print_hex_nibble ! 157: rorb $4, %al ! 158: /* Fall through */ ! 159: .size print_hex_byte, . - print_hex_byte ! 160: .globl print_hex_nibble ! 161: print_hex_nibble: ! 162: /* Preserve registers */ ! 163: pushw %ax ! 164: /* Print digit (technique by Norbert Juffa <[email protected]> */ ! 165: andb $0x0f, %al ! 166: cmpb $10, %al ! 167: sbbb $0x69, %al ! 168: das ! 169: call print_character ! 170: /* Restore registers and return */ ! 171: popw %ax ! 172: ret ! 173: .size print_hex_nibble, . - print_hex_nibble ! 174: ! 175: /***************************************************************************** ! 176: * Utility function: print PCI bus:dev.fn ! 177: * ! 178: * Parameters: ! 179: * %ax : PCI bus:dev.fn to print ! 180: * %ds:di : output buffer (or %di=0 to print to console) ! 181: * Returns: ! 182: * %ds:di : next character in output buffer (if applicable) ! 183: ***************************************************************************** ! 184: */ ! 185: .section ".prefix.lib", "awx", @progbits ! 186: .code16 ! 187: .globl print_pci_busdevfn ! 188: print_pci_busdevfn: ! 189: /* Preserve registers */ ! 190: pushw %ax ! 191: /* Print bus */ ! 192: xchgb %al, %ah ! 193: call print_hex_byte ! 194: /* Print ":" */ ! 195: movb $( ':' ), %al ! 196: call print_character ! 197: /* Print device */ ! 198: movb %ah, %al ! 199: shrb $3, %al ! 200: call print_hex_byte ! 201: /* Print "." */ ! 202: movb $( '.' ), %al ! 203: call print_character ! 204: /* Print function */ ! 205: movb %ah, %al ! 206: andb $0x07, %al ! 207: call print_hex_nibble ! 208: /* Restore registers and return */ ! 209: popw %ax ! 210: ret ! 211: .size print_pci_busdevfn, . - print_pci_busdevfn ! 212: ! 213: /***************************************************************************** ! 214: * Utility function: clear current line ! 215: * ! 216: * Parameters: ! 217: * %ds:di : output buffer (or %di=0 to print to console) ! 218: * Returns: ! 219: * %ds:di : next character in output buffer (if applicable) ! 220: ***************************************************************************** ! 221: */ ! 222: .section ".prefix.lib", "awx", @progbits ! 223: .code16 ! 224: .globl print_kill_line ! 225: print_kill_line: ! 226: /* Preserve registers */ ! 227: pushw %ax ! 228: pushw %cx ! 229: /* Print CR */ ! 230: movb $( '\r' ), %al ! 231: call print_character ! 232: /* Print 79 spaces */ ! 233: movb $( ' ' ), %al ! 234: movw $79, %cx ! 235: 1: call print_character ! 236: loop 1b ! 237: /* Print CR */ ! 238: movb $( '\r' ), %al ! 239: call print_character ! 240: /* Restore registers and return */ ! 241: popw %cx ! 242: popw %ax ! 243: ret ! 244: .size print_kill_line, . - print_kill_line ! 245: ! 246: /**************************************************************************** ! 247: * copy_bytes ! 248: * ! 249: * Copy bytes ! 250: * ! 251: * Parameters: ! 252: * %ds:esi : source address ! 253: * %es:edi : destination address ! 254: * %ecx : length ! 255: * Returns: ! 256: * %ds:esi : next source address ! 257: * %es:edi : next destination address ! 258: * Corrupts: ! 259: * None ! 260: **************************************************************************** ! 261: */ ! 262: .section ".prefix.lib", "awx", @progbits ! 263: .code16 ! 264: copy_bytes: ! 265: pushl %ecx ! 266: rep addr32 movsb ! 267: popl %ecx ! 268: ret ! 269: .size copy_bytes, . - copy_bytes ! 270: ! 271: /**************************************************************************** ! 272: * zero_bytes ! 273: * ! 274: * Zero bytes ! 275: * ! 276: * Parameters: ! 277: * %ds:esi : source address ! 278: * %es:edi : destination address ! 279: * %ecx : length ! 280: * Returns: ! 281: * %ds:esi : next source address ! 282: * %es:edi : next destination address ! 283: * Corrupts: ! 284: * None ! 285: **************************************************************************** ! 286: */ ! 287: .section ".prefix.lib", "awx", @progbits ! 288: .code16 ! 289: zero_bytes: ! 290: pushl %ecx ! 291: pushw %ax ! 292: xorw %ax, %ax ! 293: rep addr32 stosb ! 294: popw %ax ! 295: popl %ecx ! 296: ret ! 297: .size zero_bytes, . - zero_bytes ! 298: ! 299: /**************************************************************************** ! 300: * process_bytes ! 301: * ! 302: * Call memcpy()-like function ! 303: * ! 304: * Parameters: ! 305: * %esi : source physical address ! 306: * %edi : destination physical address ! 307: * %ecx : length ! 308: * %bx : memcpy()-like function to call, passing parameters: ! 309: * %ds:esi : source address ! 310: * %es:edi : destination address ! 311: * %ecx : length ! 312: * and returning: ! 313: * %ds:esi : next source address ! 314: * %es:edi : next destination address ! 315: * Returns: ! 316: * %esi : next source physical address ! 317: * %edi : next destination physical address ! 318: * Corrupts: ! 319: * None ! 320: **************************************************************************** ! 321: */ ! 322: .section ".prefix.lib", "awx", @progbits ! 323: .code16 ! 324: process_bytes: ! 325: ! 326: #ifndef KEEP_IT_REAL ! 327: ! 328: /* Preserve registers */ ! 329: pushfw ! 330: pushl %eax ! 331: pushl %ebp ! 332: ! 333: /* Construct GDT on stack (since .prefix may not be writable) */ ! 334: .equ PM_DS, 0x18 /* Flat data segment */ ! 335: pushl $0x00cf9300 ! 336: pushl $0x0000ffff ! 337: .equ PM_SS, 0x10 /* Stack segment based at %ss:0000 */ ! 338: pushl $0x008f0930 ! 339: pushw %ss ! 340: pushw $0xffff ! 341: .equ PM_CS, 0x08 /* Code segment based at %cs:0000 */ ! 342: pushl $0x008f09b0 ! 343: pushw %cs ! 344: pushw $0xffff ! 345: pushl $0 /* Base and length */ ! 346: pushw %ss ! 347: pushw $0x1f ! 348: movzwl %sp, %ebp ! 349: shll $4, 0x02(%bp) ! 350: addl %ebp, 0x02(%bp) ! 351: shll $4, 0x0a(%bp) ! 352: shll $4, 0x12(%bp) ! 353: subw $8, %sp ! 354: sgdt -8(%bp) ! 355: ! 356: /* Switch to protected mode */ ! 357: pushw %gs ! 358: pushw %fs ! 359: pushw %es ! 360: pushw %ds ! 361: pushw %ss ! 362: pushw %cs ! 363: pushw $2f ! 364: cli ! 365: data32 lgdt (%bp) ! 366: movl %cr0, %eax ! 367: orb $CR0_PE, %al ! 368: movl %eax, %cr0 ! 369: ljmp $PM_CS, $1f ! 370: 1: movw $PM_SS, %ax ! 371: movw %ax, %ss ! 372: movw $PM_DS, %ax ! 373: movw %ax, %ds ! 374: movw %ax, %es ! 375: movw %ax, %fs ! 376: movw %ax, %gs ! 377: ! 378: /* Call memcpy()-like function */ ! 379: call *%bx ! 380: ! 381: /* Return to (flat) real mode */ ! 382: movl %cr0, %eax ! 383: andb $0!CR0_PE, %al ! 384: movl %eax, %cr0 ! 385: lret ! 386: 2: /* lret will ljmp to here */ ! 387: popw %ss ! 388: popw %ds ! 389: popw %es ! 390: popw %fs ! 391: popw %gs ! 392: ! 393: /* Restore GDT */ ! 394: data32 lgdt -8(%bp) ! 395: addw $( 8 /* saved GDT */ + ( PM_DS + 8 ) /* GDT on stack */ ), %sp ! 396: ! 397: /* Restore registers and return */ ! 398: popl %ebp ! 399: popl %eax ! 400: popfw ! 401: ret ! 402: ! 403: #else /* KEEP_IT_REAL */ ! 404: ! 405: /* Preserve registers */ ! 406: pushl %eax ! 407: pushw %ds ! 408: pushw %es ! 409: ! 410: /* Convert %esi and %edi to %ds:esi and %es:edi */ ! 411: shrl $4, %esi ! 412: movw %si, %ds ! 413: xorw %si, %si ! 414: shll $4, %esi ! 415: shrl $4, %edi ! 416: movw %di, %es ! 417: xorw %di, %di ! 418: shll $4, %edi ! 419: ! 420: /* Call memcpy()-like function */ ! 421: call *%bx ! 422: ! 423: /* Convert %ds:esi and %es:edi back to physical addresses */ ! 424: xorl %eax, %eax ! 425: movw %ds, %cx ! 426: shll $4, %eax ! 427: addl %eax, %esi ! 428: xorl %eax, %eax ! 429: movw %es, %cx ! 430: shll $4, %eax ! 431: addl %eax, %edi ! 432: ! 433: /* Restore registers and return */ ! 434: popw %es ! 435: popw %ds ! 436: popl %eax ! 437: ret ! 438: ! 439: #endif /* KEEP_IT_REAL */ ! 440: ! 441: .size process_bytes, . - process_bytes ! 442: ! 443: /**************************************************************************** ! 444: * install_block ! 445: * ! 446: * Install block to specified address ! 447: * ! 448: * Parameters: ! 449: * %esi : source physical address (must be a multiple of 16) ! 450: * %edi : destination physical address (must be a multiple of 16) ! 451: * %ecx : length of (decompressed) data ! 452: * %edx : total length of block (including any uninitialised data portion) ! 453: * Returns: ! 454: * %esi : next source physical address (will be a multiple of 16) ! 455: * %edi : next destination physical address (will be a multiple of 16) ! 456: * Corrupts: ! 457: * none ! 458: **************************************************************************** ! 459: */ ! 460: .section ".prefix.lib", "awx", @progbits ! 461: .code16 ! 462: install_block: ! 463: /* Preserve registers */ ! 464: pushl %ecx ! 465: pushw %bx ! 466: ! 467: /* Decompress (or copy) source to destination */ ! 468: #if COMPRESS ! 469: movw $decompress16, %bx ! 470: #else ! 471: movw $copy_bytes, %bx ! 472: #endif ! 473: call process_bytes ! 474: ! 475: /* Zero .bss portion */ ! 476: negl %ecx ! 477: addl %edx, %ecx ! 478: movw $zero_bytes, %bx ! 479: call process_bytes ! 480: ! 481: /* Round up %esi and %edi to start of next blocks */ ! 482: addl $0xf, %esi ! 483: andl $~0xf, %esi ! 484: addl $0xf, %edi ! 485: andl $~0xf, %edi ! 486: ! 487: /* Restore registers and return */ ! 488: popw %bx ! 489: popl %ecx ! 490: ret ! 491: .size install_block, . - install_block ! 492: ! 493: /**************************************************************************** ! 494: * alloc_basemem ! 495: * ! 496: * Allocate space for .text16 and .data16 from top of base memory. ! 497: * Memory is allocated using the BIOS free base memory counter at ! 498: * 0x40:13. ! 499: * ! 500: * Parameters: ! 501: * none ! 502: * Returns: ! 503: * %ax : .text16 segment address ! 504: * %bx : .data16 segment address ! 505: * Corrupts: ! 506: * none ! 507: **************************************************************************** ! 508: */ ! 509: .section ".prefix.lib", "awx", @progbits ! 510: .code16 ! 511: .globl alloc_basemem ! 512: alloc_basemem: ! 513: /* Preserve registers */ ! 514: pushw %fs ! 515: ! 516: /* FBMS => %ax as segment address */ ! 517: pushw $0x40 ! 518: popw %fs ! 519: movw %fs:0x13, %ax ! 520: shlw $6, %ax ! 521: ! 522: /* Calculate .data16 segment address */ ! 523: subw $_data16_memsz_pgh, %ax ! 524: pushw %ax ! 525: ! 526: /* Calculate .text16 segment address */ ! 527: subw $_text16_memsz_pgh, %ax ! 528: pushw %ax ! 529: ! 530: /* Update FBMS */ ! 531: shrw $6, %ax ! 532: movw %ax, %fs:0x13 ! 533: ! 534: /* Retrieve .text16 and .data16 segment addresses */ ! 535: popw %ax ! 536: popw %bx ! 537: ! 538: /* Restore registers and return */ ! 539: popw %fs ! 540: ret ! 541: .size alloc_basemem, . - alloc_basemem ! 542: ! 543: /**************************************************************************** ! 544: * free_basemem ! 545: * ! 546: * Free space allocated with alloc_basemem. ! 547: * ! 548: * Parameters: ! 549: * %ax : .text16 segment address ! 550: * %bx : .data16 segment address ! 551: * Returns: ! 552: * %ax : 0 if successfully freed ! 553: * Corrupts: ! 554: * none ! 555: **************************************************************************** ! 556: */ ! 557: .section ".text16", "ax", @progbits ! 558: .code16 ! 559: .globl free_basemem ! 560: free_basemem: ! 561: /* Preserve registers */ ! 562: pushw %fs ! 563: ! 564: /* Check FBMS counter */ ! 565: pushw %ax ! 566: shrw $6, %ax ! 567: pushw $0x40 ! 568: popw %fs ! 569: cmpw %ax, %fs:0x13 ! 570: popw %ax ! 571: jne 1f ! 572: ! 573: /* Check hooked interrupt count */ ! 574: cmpw $0, %cs:hooked_bios_interrupts ! 575: jne 1f ! 576: ! 577: /* OK to free memory */ ! 578: addw $_text16_memsz_pgh, %ax ! 579: addw $_data16_memsz_pgh, %ax ! 580: shrw $6, %ax ! 581: movw %ax, %fs:0x13 ! 582: xorw %ax, %ax ! 583: ! 584: 1: /* Restore registers and return */ ! 585: popw %fs ! 586: ret ! 587: .size free_basemem, . - free_basemem ! 588: ! 589: .section ".text16.data", "aw", @progbits ! 590: .globl hooked_bios_interrupts ! 591: hooked_bios_interrupts: ! 592: .word 0 ! 593: .size hooked_bios_interrupts, . - hooked_bios_interrupts ! 594: ! 595: /**************************************************************************** ! 596: * install ! 597: * ! 598: * Install all text and data segments. ! 599: * ! 600: * Parameters: ! 601: * none ! 602: * Returns: ! 603: * %ax : .text16 segment address ! 604: * %bx : .data16 segment address ! 605: * Corrupts: ! 606: * none ! 607: **************************************************************************** ! 608: */ ! 609: .section ".prefix.lib", "awx", @progbits ! 610: .code16 ! 611: .globl install ! 612: install: ! 613: progress "install:\n" ! 614: /* Preserve registers */ ! 615: pushl %esi ! 616: pushl %edi ! 617: /* Allocate space for .text16 and .data16 */ ! 618: call alloc_basemem ! 619: /* Image source = %cs:0000 */ ! 620: xorl %esi, %esi ! 621: /* Image destination = default */ ! 622: xorl %edi, %edi ! 623: /* Allow relocation */ ! 624: clc ! 625: /* Install text and data segments */ ! 626: call install_prealloc ! 627: /* Restore registers and return */ ! 628: popl %edi ! 629: popl %esi ! 630: ret ! 631: .size install, . - install ! 632: ! 633: /**************************************************************************** ! 634: * install_prealloc ! 635: * ! 636: * Install all text and data segments. ! 637: * ! 638: * Parameters: ! 639: * %ax : .text16 segment address ! 640: * %bx : .data16 segment address ! 641: * %esi : Image source physical address (or zero for %cs:0000) ! 642: * %edi : Decompression temporary area physical address (or zero for default) ! 643: * CF set : Avoid relocating to top of memory ! 644: * Corrupts: ! 645: * none ! 646: **************************************************************************** ! 647: */ ! 648: .section ".prefix.lib", "awx", @progbits ! 649: .code16 ! 650: .globl install_prealloc ! 651: install_prealloc: ! 652: progress "install_prealloc:\n" ! 653: /* Save registers */ ! 654: pushal ! 655: pushw %ds ! 656: pushw %es ! 657: cld /* Sanity: clear the direction flag asap */ ! 658: pushfw ! 659: ! 660: /* Set up %ds for (read-only) access to .prefix */ ! 661: pushw %cs ! 662: popw %ds ! 663: ! 664: /* Copy decompression temporary area physical address to %ebp */ ! 665: movl %edi, %ebp ! 666: ! 667: /* Install .text16.early */ ! 668: progress " .text16.early\n" ! 669: pushl %esi ! 670: xorl %esi, %esi ! 671: movw %cs, %si ! 672: shll $4, %esi ! 673: addl $_text16_early_lma, %esi ! 674: movzwl %ax, %edi ! 675: shll $4, %edi ! 676: movl $_text16_early_filesz, %ecx ! 677: movl $_text16_early_memsz, %edx ! 678: call install_block /* .text16.early */ ! 679: popl %esi ! 680: ! 681: #ifndef KEEP_IT_REAL ! 682: /* Access high memory by enabling the A20 gate. (We will ! 683: * already have 4GB segment limits as a result of calling ! 684: * install_block.) ! 685: */ ! 686: progress " access_highmem\n" ! 687: pushw %cs ! 688: pushw $1f ! 689: pushw %ax ! 690: pushw $access_highmem ! 691: lret ! 692: 1: /* Die if we could not access high memory */ ! 693: jnc 3f ! 694: movw $a20_death_message, %si ! 695: xorw %di, %di ! 696: call print_message ! 697: 2: jmp 2b ! 698: .section ".prefix.data", "aw", @progbits ! 699: a20_death_message: ! 700: .asciz "\nHigh memory inaccessible - cannot continue\n" ! 701: .size a20_death_message, . - a20_death_message ! 702: .previous ! 703: 3: ! 704: #endif ! 705: ! 706: /* Open payload (which may not yet be in memory) */ ! 707: progress " open_payload\n" ! 708: pushw %cs ! 709: pushw $1f ! 710: pushw %ax ! 711: pushw $open_payload ! 712: lret ! 713: 1: /* Die if we could not access the payload */ ! 714: jnc 3f ! 715: xorw %di, %di ! 716: movl %esi, %eax ! 717: call print_hex_dword ! 718: movw $payload_death_message, %si ! 719: call print_message ! 720: 2: jmp 2b ! 721: .section ".prefix.data", "aw", @progbits ! 722: payload_death_message: ! 723: .asciz "\nPayload inaccessible - cannot continue\n" ! 724: .size payload_death_message, . - payload_death_message ! 725: .previous ! 726: 3: ! 727: ! 728: /* Calculate physical address of payload (i.e. first source) */ ! 729: testl %esi, %esi ! 730: jnz 1f ! 731: movw %cs, %si ! 732: shll $4, %esi ! 733: 1: addl payload_lma, %esi ! 734: ! 735: /* Install .text16.late and .data16 */ ! 736: progress " .text16.late\n" ! 737: movl $_text16_late_filesz, %ecx ! 738: movl $_text16_late_memsz, %edx ! 739: call install_block /* .text16.late */ ! 740: progress " .data16\n" ! 741: movzwl %bx, %edi ! 742: shll $4, %edi ! 743: movl $_data16_filesz, %ecx ! 744: movl $_data16_memsz, %edx ! 745: call install_block /* .data16 */ ! 746: ! 747: /* Set up %ds for access to .data16 */ ! 748: movw %bx, %ds ! 749: ! 750: #ifdef KEEP_IT_REAL ! 751: /* Initialise libkir */ ! 752: movw %ax, (init_libkir_vector+2) ! 753: lcall *init_libkir_vector ! 754: #else ! 755: /* Find a suitable decompression temporary area, if none specified */ ! 756: pushl %eax ! 757: testl %ebp, %ebp ! 758: jnz 1f ! 759: /* Use INT 15,88 to find the highest available address via INT ! 760: * 15,88. This limits us to around 64MB, which should avoid ! 761: * all of the POST-time memory map failure modes. ! 762: */ ! 763: movb $0x88, %ah ! 764: int $0x15 ! 765: movw %ax, %bp ! 766: addl $0x400, %ebp ! 767: subl $_textdata_memsz_kb, %ebp ! 768: shll $10, %ebp ! 769: /* Sanity check: if we have ended up below 1MB, use 1MB */ ! 770: cmpl $0x100000, %ebp ! 771: jae 1f ! 772: movl $0x100000, %ebp ! 773: 1: popl %eax ! 774: ! 775: /* Install .text and .data to temporary area in high memory, ! 776: * prior to reading the E820 memory map and relocating ! 777: * properly. ! 778: */ ! 779: progress " .textdata\n" ! 780: movl %ebp, %edi ! 781: movl $_textdata_filesz, %ecx ! 782: movl $_textdata_memsz, %edx ! 783: call install_block ! 784: ! 785: /* Initialise librm at current location */ ! 786: progress " init_librm\n" ! 787: movw %ax, (init_librm_vector+2) ! 788: movl %ebp, %edi ! 789: lcall *init_librm_vector ! 790: ! 791: /* Skip relocation if CF was set on entry */ ! 792: popfw ! 793: pushfw ! 794: jc skip_relocate ! 795: ! 796: /* Call relocate() to determine target address for relocation. ! 797: * relocate() will return with %esi, %edi and %ecx set up ! 798: * ready for the copy to the new location. ! 799: */ ! 800: progress " relocate\n" ! 801: movw %ax, (prot_call_vector+2) ! 802: pushl $relocate ! 803: lcall *prot_call_vector ! 804: popl %edx /* discard */ ! 805: ! 806: /* Copy code to new location */ ! 807: progress " copy\n" ! 808: pushl %edi ! 809: pushw %bx ! 810: movw $copy_bytes, %bx ! 811: call process_bytes ! 812: popw %bx ! 813: popl %edi ! 814: ! 815: /* Initialise librm at new location */ ! 816: progress " init_librm\n" ! 817: lcall *init_librm_vector ! 818: skip_relocate: ! 819: #endif ! 820: ! 821: /* Close access to payload */ ! 822: progress " close_payload\n" ! 823: movw %ax, (close_payload_vector+2) ! 824: lcall *close_payload_vector ! 825: ! 826: /* Restore registers */ ! 827: popfw ! 828: popw %es ! 829: popw %ds ! 830: popal ! 831: ret ! 832: .size install_prealloc, . - install_prealloc ! 833: ! 834: /* Vectors for far calls to .text16 functions. Must be in ! 835: * .data16, since .prefix may not be writable. ! 836: */ ! 837: .section ".data16", "aw", @progbits ! 838: #ifdef KEEP_IT_REAL ! 839: init_libkir_vector: ! 840: .word init_libkir ! 841: .word 0 ! 842: .size init_libkir_vector, . - init_libkir_vector ! 843: #else ! 844: init_librm_vector: ! 845: .word init_librm ! 846: .word 0 ! 847: .size init_librm_vector, . - init_librm_vector ! 848: prot_call_vector: ! 849: .word prot_call ! 850: .word 0 ! 851: .size prot_call_vector, . - prot_call_vector ! 852: #endif ! 853: close_payload_vector: ! 854: .word close_payload ! 855: .word 0 ! 856: .size close_payload_vector, . - close_payload_vector ! 857: ! 858: /* Payload address */ ! 859: .section ".prefix.lib", "awx", @progbits ! 860: payload_lma: ! 861: .long 0 ! 862: .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ ! 863: .ascii "ADHL" ! 864: .long payload_lma ! 865: .long 1 ! 866: .long 0 ! 867: .previous ! 868: ! 869: /* Dummy routines to open and close payload */ ! 870: .section ".text16.early.data", "aw", @progbits ! 871: .weak open_payload ! 872: .weak close_payload ! 873: open_payload: ! 874: close_payload: ! 875: clc ! 876: lret ! 877: .size open_payload, . - open_payload ! 878: .size close_payload, . - close_payload ! 879: ! 880: /**************************************************************************** ! 881: * uninstall ! 882: * ! 883: * Uninstall all text and data segments. ! 884: * ! 885: * Parameters: ! 886: * %ax : .text16 segment address ! 887: * %bx : .data16 segment address ! 888: * Returns: ! 889: * none ! 890: * Corrupts: ! 891: * none ! 892: **************************************************************************** ! 893: */ ! 894: .section ".text16", "ax", @progbits ! 895: .code16 ! 896: .globl uninstall ! 897: uninstall: ! 898: call free_basemem ! 899: ret ! 900: .size uninstall, . - uninstall ! 901: ! 902: ! 903: ! 904: /* File split information for the compressor */ ! 905: #if COMPRESS ! 906: #define PACK_OR_COPY "PACK" ! 907: #else ! 908: #define PACK_OR_COPY "COPY" ! 909: #endif ! 910: .section ".zinfo", "a", @progbits ! 911: .ascii "COPY" ! 912: .long _prefix_lma ! 913: .long _prefix_filesz ! 914: .long _max_align ! 915: .ascii PACK_OR_COPY ! 916: .long _text16_early_lma ! 917: .long _text16_early_filesz ! 918: .long _max_align ! 919: .ascii "PAYL" ! 920: .long 0 ! 921: .long 0 ! 922: .long _max_align ! 923: .ascii PACK_OR_COPY ! 924: .long _text16_late_lma ! 925: .long _text16_late_filesz ! 926: .long _max_align ! 927: .ascii PACK_OR_COPY ! 928: .long _data16_lma ! 929: .long _data16_filesz ! 930: .long _max_align ! 931: .ascii PACK_OR_COPY ! 932: .long _textdata_lma ! 933: .long _textdata_filesz ! 934: .long _max_align
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.