You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

libprefix.S 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /*
  2. * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
  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. .arch i386
  20. /**
  21. * High memory temporary load address
  22. *
  23. * Temporary buffer into which to copy (or decompress) our runtime
  24. * image, prior to calling get_memmap() and relocate(). We don't
  25. * actually leave anything here once install() has returned.
  26. *
  27. * We use the start of an even megabyte so that we don't have to worry
  28. * about the current state of the A20 line.
  29. *
  30. * We use 4MB rather than 2MB because some PXE stack / PMM BIOS
  31. * combinations are known to place data required by other UNDI ROMs
  32. * loader around the 2MB mark.
  33. */
  34. .globl HIGHMEM_LOADPOINT
  35. .equ HIGHMEM_LOADPOINT, ( 4 << 20 )
  36. /* Image compression enabled */
  37. #define COMPRESS 1
  38. #define CR0_PE 1
  39. /*****************************************************************************
  40. * Utility function: print character (with LF -> LF,CR translation)
  41. *
  42. * Parameters:
  43. * %al : character to print
  44. * %ds:di : output buffer (or %di=0 to print to console)
  45. * Returns:
  46. * %ds:di : next character in output buffer (if applicable)
  47. *****************************************************************************
  48. */
  49. .section ".prefix.lib", "awx", @progbits
  50. .code16
  51. .globl print_character
  52. print_character:
  53. /* Preserve registers */
  54. pushw %ax
  55. pushw %bx
  56. pushw %bp
  57. /* If %di is non-zero, write character to buffer and exit */
  58. testw %di, %di
  59. jz 1f
  60. movb %al, %ds:(%di)
  61. incw %di
  62. jmp 3f
  63. 1: /* Print character */
  64. movw $0x0007, %bx /* page 0, attribute 7 (normal) */
  65. movb $0x0e, %ah /* write char, tty mode */
  66. cmpb $0x0a, %al /* '\n'? */
  67. jne 2f
  68. int $0x10
  69. movb $0x0d, %al
  70. 2: int $0x10
  71. /* Restore registers and return */
  72. 3: popw %bp
  73. popw %bx
  74. popw %ax
  75. ret
  76. .size print_character, . - print_character
  77. /*****************************************************************************
  78. * Utility function: print a NUL-terminated string
  79. *
  80. * Parameters:
  81. * %ds:si : string to print
  82. * %ds:di : output buffer (or %di=0 to print to console)
  83. * Returns:
  84. * %ds:si : character after terminating NUL
  85. * %ds:di : next character in output buffer (if applicable)
  86. *****************************************************************************
  87. */
  88. .section ".prefix.lib", "awx", @progbits
  89. .code16
  90. .globl print_message
  91. print_message:
  92. /* Preserve registers */
  93. pushw %ax
  94. /* Print string */
  95. 1: lodsb
  96. testb %al, %al
  97. je 2f
  98. call print_character
  99. jmp 1b
  100. 2: /* Restore registers and return */
  101. popw %ax
  102. ret
  103. .size print_message, . - print_message
  104. /*****************************************************************************
  105. * Utility functions: print hex digit/byte/word/dword
  106. *
  107. * Parameters:
  108. * %al (low nibble) : digit to print
  109. * %al : byte to print
  110. * %ax : word to print
  111. * %eax : dword to print
  112. * %ds:di : output buffer (or %di=0 to print to console)
  113. * Returns:
  114. * %ds:di : next character in output buffer (if applicable)
  115. *****************************************************************************
  116. */
  117. .section ".prefix.lib", "awx", @progbits
  118. .code16
  119. .globl print_hex_dword
  120. print_hex_dword:
  121. rorl $16, %eax
  122. call print_hex_word
  123. rorl $16, %eax
  124. /* Fall through */
  125. .size print_hex_dword, . - print_hex_dword
  126. .globl print_hex_word
  127. print_hex_word:
  128. xchgb %al, %ah
  129. call print_hex_byte
  130. xchgb %al, %ah
  131. /* Fall through */
  132. .size print_hex_word, . - print_hex_word
  133. .globl print_hex_byte
  134. print_hex_byte:
  135. rorb $4, %al
  136. call print_hex_nibble
  137. rorb $4, %al
  138. /* Fall through */
  139. .size print_hex_byte, . - print_hex_byte
  140. .globl print_hex_nibble
  141. print_hex_nibble:
  142. /* Preserve registers */
  143. pushw %ax
  144. /* Print digit (technique by Norbert Juffa <norbert.juffa@amd.com> */
  145. andb $0x0f, %al
  146. cmpb $10, %al
  147. sbbb $0x69, %al
  148. das
  149. call print_character
  150. /* Restore registers and return */
  151. popw %ax
  152. ret
  153. .size print_hex_nibble, . - print_hex_nibble
  154. /*****************************************************************************
  155. * Utility function: print PCI bus:dev.fn
  156. *
  157. * Parameters:
  158. * %ax : PCI bus:dev.fn to print
  159. * %ds:di : output buffer (or %di=0 to print to console)
  160. * Returns:
  161. * %ds:di : next character in output buffer (if applicable)
  162. *****************************************************************************
  163. */
  164. .section ".prefix.lib", "awx", @progbits
  165. .code16
  166. .globl print_pci_busdevfn
  167. print_pci_busdevfn:
  168. /* Preserve registers */
  169. pushw %ax
  170. /* Print bus */
  171. xchgb %al, %ah
  172. call print_hex_byte
  173. /* Print ":" */
  174. movb $':', %al
  175. call print_character
  176. /* Print device */
  177. movb %ah, %al
  178. shrb $3, %al
  179. call print_hex_byte
  180. /* Print "." */
  181. movb $'.', %al
  182. call print_character
  183. /* Print function */
  184. movb %ah, %al
  185. andb $0x07, %al
  186. call print_hex_nibble
  187. /* Restore registers and return */
  188. popw %ax
  189. ret
  190. .size print_pci_busdevfn, . - print_pci_busdevfn
  191. /*****************************************************************************
  192. * Utility function: clear current line
  193. *
  194. * Parameters:
  195. * %ds:di : output buffer (or %di=0 to print to console)
  196. * Returns:
  197. * %ds:di : next character in output buffer (if applicable)
  198. *****************************************************************************
  199. */
  200. .section ".prefix.lib", "awx", @progbits
  201. .code16
  202. .globl print_kill_line
  203. print_kill_line:
  204. /* Preserve registers */
  205. pushw %ax
  206. pushw %cx
  207. /* Print CR */
  208. movb $'\r', %al
  209. call print_character
  210. /* Print 79 spaces */
  211. movb $' ', %al
  212. movw $79, %cx
  213. 1: call print_character
  214. loop 1b
  215. /* Print CR */
  216. movb $'\r', %al
  217. call print_character
  218. /* Restore registers and return */
  219. popw %cx
  220. popw %ax
  221. ret
  222. .size print_kill_line, . - print_kill_line
  223. /****************************************************************************
  224. * pm_call (real-mode near call)
  225. *
  226. * Call routine in 16-bit protected mode for access to extended memory
  227. *
  228. * Parameters:
  229. * %ax : address of routine to call in 16-bit protected mode
  230. * Returns:
  231. * none
  232. * Corrupts:
  233. * %ax
  234. *
  235. * The specified routine is called in 16-bit protected mode, with:
  236. *
  237. * %cs : 16-bit code segment with base matching real-mode %cs
  238. * %ss : 16-bit data segment with base matching real-mode %ss
  239. * %ds,%es,%fs,%gs : 32-bit data segment with zero base and 4GB limit
  240. *
  241. ****************************************************************************
  242. */
  243. #ifndef KEEP_IT_REAL
  244. /* GDT for protected-mode calls */
  245. .section ".prefix.lib", "awx", @progbits
  246. .align 16
  247. pm_call_vars:
  248. gdt:
  249. gdt_limit: .word gdt_length - 1
  250. gdt_base: .long 0
  251. .word 0 /* padding */
  252. pm_cs: /* 16-bit protected-mode code segment */
  253. .equ PM_CS, pm_cs - gdt
  254. .word 0xffff, 0
  255. .byte 0, 0x9b, 0x00, 0
  256. pm_ss: /* 16-bit protected-mode stack segment */
  257. .equ PM_SS, pm_ss - gdt
  258. .word 0xffff, 0
  259. .byte 0, 0x93, 0x00, 0
  260. pm_ds: /* 32-bit protected-mode flat data segment */
  261. .equ PM_DS, pm_ds - gdt
  262. .word 0xffff, 0
  263. .byte 0, 0x93, 0xcf, 0
  264. gdt_end:
  265. .equ gdt_length, . - gdt
  266. .size gdt, . - gdt
  267. .section ".prefix.lib", "awx", @progbits
  268. .align 16
  269. pm_saved_gdt:
  270. .long 0, 0
  271. .size pm_saved_gdt, . - pm_saved_gdt
  272. .equ pm_call_vars_size, . - pm_call_vars
  273. #define PM_CALL_VAR(x) ( -pm_call_vars_size + ( (x) - pm_call_vars ) )
  274. .section ".prefix.lib", "awx", @progbits
  275. .code16
  276. pm_call:
  277. /* Preserve registers, flags, and RM return point */
  278. pushw %bp
  279. movw %sp, %bp
  280. subw $pm_call_vars_size, %sp
  281. andw $0xfff0, %sp
  282. pushfl
  283. pushw %gs
  284. pushw %fs
  285. pushw %es
  286. pushw %ds
  287. pushw %ss
  288. pushw %cs
  289. pushw $99f
  290. /* Set up local variable block, and preserve GDT */
  291. pushw %cx
  292. pushw %si
  293. pushw %di
  294. pushw %ss
  295. popw %es
  296. movw $pm_call_vars, %si
  297. leaw PM_CALL_VAR(pm_call_vars)(%bp), %di
  298. movw $pm_call_vars_size, %cx
  299. cs rep movsb
  300. popw %di
  301. popw %si
  302. popw %cx
  303. sgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
  304. /* Set up GDT bases */
  305. pushl %eax
  306. pushl %edi
  307. xorl %eax, %eax
  308. movw %ss, %ax
  309. shll $4, %eax
  310. movzwl %bp, %edi
  311. addr32 leal PM_CALL_VAR(gdt)(%eax, %edi), %eax
  312. movl %eax, PM_CALL_VAR(gdt_base)(%bp)
  313. movw %cs, %ax
  314. movw $PM_CALL_VAR(pm_cs), %di
  315. call set_seg_base
  316. movw %ss, %ax
  317. movw $PM_CALL_VAR(pm_ss), %di
  318. call set_seg_base
  319. popl %edi
  320. popl %eax
  321. /* Switch CPU to protected mode and load up segment registers */
  322. pushl %eax
  323. cli
  324. data32 lgdt PM_CALL_VAR(gdt)(%bp)
  325. movl %cr0, %eax
  326. orb $CR0_PE, %al
  327. movl %eax, %cr0
  328. ljmp $PM_CS, $1f
  329. 1: movw $PM_SS, %ax
  330. movw %ax, %ss
  331. movw $PM_DS, %ax
  332. movw %ax, %ds
  333. movw %ax, %es
  334. movw %ax, %fs
  335. movw %ax, %gs
  336. popl %eax
  337. /* Call PM routine */
  338. call *%ax
  339. /* Set real-mode segment limits on %ds, %es, %fs and %gs */
  340. movw %ss, %ax
  341. movw %ax, %ds
  342. movw %ax, %es
  343. movw %ax, %fs
  344. movw %ax, %gs
  345. /* Return CPU to real mode */
  346. movl %cr0, %eax
  347. andb $0!CR0_PE, %al
  348. movl %eax, %cr0
  349. /* Restore registers and flags */
  350. lret /* will ljmp to 99f */
  351. 99: popw %ss
  352. popw %ds
  353. popw %es
  354. popw %fs
  355. popw %gs
  356. data32 lgdt PM_CALL_VAR(pm_saved_gdt)(%bp)
  357. popfl
  358. movw %bp, %sp
  359. popw %bp
  360. ret
  361. .size pm_call, . - pm_call
  362. set_seg_base:
  363. rolw $4, %ax
  364. movw %ax, 2(%bp,%di)
  365. andw $0xfff0, 2(%bp,%di)
  366. movb %al, 4(%bp,%di)
  367. andb $0x0f, 4(%bp,%di)
  368. ret
  369. .size set_seg_base, . - set_seg_base
  370. #endif /* KEEP_IT_REAL */
  371. /****************************************************************************
  372. * copy_bytes (real-mode or 16-bit protected-mode near call)
  373. *
  374. * Copy bytes
  375. *
  376. * Parameters:
  377. * %ds:esi : source address
  378. * %es:edi : destination address
  379. * %ecx : length
  380. * Returns:
  381. * %ds:esi : next source address
  382. * %es:edi : next destination address
  383. * Corrupts:
  384. * None
  385. ****************************************************************************
  386. */
  387. .section ".prefix.lib", "awx", @progbits
  388. .code16
  389. copy_bytes:
  390. pushl %ecx
  391. rep addr32 movsb
  392. popl %ecx
  393. ret
  394. .size copy_bytes, . - copy_bytes
  395. /****************************************************************************
  396. * install_block (real-mode near call)
  397. *
  398. * Install block to specified address
  399. *
  400. * Parameters:
  401. * %esi : source physical address (must be a multiple of 16)
  402. * %edi : destination physical address (must be a multiple of 16)
  403. * %ecx : length of (decompressed) data
  404. * %edx : total length of block (including any uninitialised data portion)
  405. * Returns:
  406. * %esi : next source physical address (will be a multiple of 16)
  407. * Corrupts:
  408. * none
  409. ****************************************************************************
  410. */
  411. .section ".prefix.lib", "awx", @progbits
  412. .code16
  413. install_block:
  414. #ifdef KEEP_IT_REAL
  415. /* Preserve registers */
  416. pushw %ds
  417. pushw %es
  418. pushl %ecx
  419. pushl %edi
  420. /* Convert %esi and %edi to segment registers */
  421. shrl $4, %esi
  422. movw %si, %ds
  423. xorw %si, %si
  424. shrl $4, %edi
  425. movw %di, %es
  426. xorw %di, %di
  427. #else /* KEEP_IT_REAL */
  428. /* Call self in protected mode */
  429. pushw %ax
  430. movw $1f, %ax
  431. call pm_call
  432. popw %ax
  433. ret
  434. 1:
  435. /* Preserve registers */
  436. pushl %ecx
  437. pushl %edi
  438. #endif /* KEEP_IT_REAL */
  439. #if COMPRESS
  440. /* Decompress source to destination */
  441. call decompress16
  442. #else
  443. /* Copy source to destination */
  444. call copy_bytes
  445. #endif
  446. /* Zero .bss portion */
  447. negl %ecx
  448. addl %edx, %ecx
  449. pushw %ax
  450. xorw %ax, %ax
  451. rep addr32 stosb
  452. popw %ax
  453. /* Round up %esi to start of next source block */
  454. addl $0xf, %esi
  455. andl $~0xf, %esi
  456. #ifdef KEEP_IT_REAL
  457. /* Convert %ds:esi back to a physical address */
  458. movzwl %ds, %cx
  459. shll $4, %ecx
  460. addl %ecx, %esi
  461. /* Restore registers */
  462. popl %edi
  463. popl %ecx
  464. popw %es
  465. popw %ds
  466. #else /* KEEP_IT_REAL */
  467. /* Restore registers */
  468. popl %edi
  469. popl %ecx
  470. #endif
  471. ret
  472. .size install_block, . - install_block
  473. /****************************************************************************
  474. * alloc_basemem (real-mode near call)
  475. *
  476. * Allocate space for .text16 and .data16 from top of base memory.
  477. * Memory is allocated using the BIOS free base memory counter at
  478. * 0x40:13.
  479. *
  480. * Parameters:
  481. * none
  482. * Returns:
  483. * %ax : .text16 segment address
  484. * %bx : .data16 segment address
  485. * Corrupts:
  486. * none
  487. ****************************************************************************
  488. */
  489. .section ".prefix.lib", "awx", @progbits
  490. .code16
  491. .globl alloc_basemem
  492. alloc_basemem:
  493. /* Preserve registers */
  494. pushw %fs
  495. /* FBMS => %ax as segment address */
  496. pushw $0x40
  497. popw %fs
  498. movw %fs:0x13, %ax
  499. shlw $6, %ax
  500. /* Calculate .data16 segment address */
  501. subw $_data16_memsz_pgh, %ax
  502. pushw %ax
  503. /* Calculate .text16 segment address */
  504. subw $_text16_memsz_pgh, %ax
  505. pushw %ax
  506. /* Update FBMS */
  507. shrw $6, %ax
  508. movw %ax, %fs:0x13
  509. /* Retrieve .text16 and .data16 segment addresses */
  510. popw %ax
  511. popw %bx
  512. /* Restore registers and return */
  513. popw %fs
  514. ret
  515. .size alloc_basemem, . - alloc_basemem
  516. /****************************************************************************
  517. * free_basemem (real-mode near call)
  518. *
  519. * Free space allocated with alloc_basemem.
  520. *
  521. * Parameters:
  522. * %ax : .text16 segment address
  523. * %bx : .data16 segment address
  524. * Returns:
  525. * %ax : 0 if successfully freed
  526. * Corrupts:
  527. * none
  528. ****************************************************************************
  529. */
  530. .section ".text16", "ax", @progbits
  531. .code16
  532. .globl free_basemem
  533. free_basemem:
  534. /* Preserve registers */
  535. pushw %fs
  536. /* Check FBMS counter */
  537. pushw %ax
  538. shrw $6, %ax
  539. pushw $0x40
  540. popw %fs
  541. cmpw %ax, %fs:0x13
  542. popw %ax
  543. jne 1f
  544. /* Check hooked interrupt count */
  545. cmpw $0, %cs:hooked_bios_interrupts
  546. jne 1f
  547. /* OK to free memory */
  548. addw $_text16_memsz_pgh, %ax
  549. addw $_data16_memsz_pgh, %ax
  550. shrw $6, %ax
  551. movw %ax, %fs:0x13
  552. xorw %ax, %ax
  553. 1: /* Restore registers and return */
  554. popw %fs
  555. ret
  556. .size free_basemem, . - free_basemem
  557. .section ".text16.data", "aw", @progbits
  558. .globl hooked_bios_interrupts
  559. hooked_bios_interrupts:
  560. .word 0
  561. .size hooked_bios_interrupts, . - hooked_bios_interrupts
  562. /****************************************************************************
  563. * install (real-mode near call)
  564. *
  565. * Install all text and data segments.
  566. *
  567. * Parameters:
  568. * none
  569. * Returns:
  570. * %ax : .text16 segment address
  571. * %bx : .data16 segment address
  572. * Corrupts:
  573. * none
  574. ****************************************************************************
  575. */
  576. .section ".prefix.lib", "awx", @progbits
  577. .code16
  578. .globl install
  579. install:
  580. /* Preserve registers */
  581. pushl %esi
  582. pushl %edi
  583. /* Allocate space for .text16 and .data16 */
  584. call alloc_basemem
  585. /* Image source = %cs:0000 */
  586. xorl %esi, %esi
  587. /* Image destination = HIGHMEM_LOADPOINT */
  588. movl $HIGHMEM_LOADPOINT, %edi
  589. /* Install text and data segments */
  590. call install_prealloc
  591. /* Restore registers and return */
  592. popl %edi
  593. popl %esi
  594. ret
  595. .size install, . - install
  596. /****************************************************************************
  597. * install_prealloc (real-mode near call)
  598. *
  599. * Install all text and data segments.
  600. *
  601. * Parameters:
  602. * %ax : .text16 segment address
  603. * %bx : .data16 segment address
  604. * %esi : Image source physical address (or zero for %cs:0000)
  605. * %edi : Decompression temporary area physical address
  606. * Corrupts:
  607. * none
  608. ****************************************************************************
  609. */
  610. .section ".prefix.lib", "awx", @progbits
  611. .code16
  612. .globl install_prealloc
  613. install_prealloc:
  614. /* Save registers */
  615. pushal
  616. pushw %ds
  617. pushw %es
  618. /* Sanity: clear the direction flag asap */
  619. cld
  620. /* Calculate physical address of payload (i.e. first source) */
  621. testl %esi, %esi
  622. jnz 1f
  623. movw %cs, %si
  624. shll $4, %esi
  625. 1: addl $_payload_lma, %esi
  626. /* Install .text16 and .data16 */
  627. pushl %edi
  628. movzwl %ax, %edi
  629. shll $4, %edi
  630. movl $_text16_memsz, %ecx
  631. movl %ecx, %edx
  632. call install_block /* .text16 */
  633. movzwl %bx, %edi
  634. shll $4, %edi
  635. movl $_data16_filesz, %ecx
  636. movl $_data16_memsz, %edx
  637. call install_block /* .data16 */
  638. popl %edi
  639. /* Set up %ds for access to .data16 */
  640. movw %bx, %ds
  641. #ifdef KEEP_IT_REAL
  642. /* Initialise libkir */
  643. movw %ax, (init_libkir_vector+2)
  644. lcall *init_libkir_vector
  645. #else
  646. /* Install .text and .data to temporary area in high memory,
  647. * prior to reading the E820 memory map and relocating
  648. * properly.
  649. */
  650. movl $_textdata_filesz, %ecx
  651. movl $_textdata_memsz, %edx
  652. call install_block
  653. /* Initialise librm at current location */
  654. movw %ax, (init_librm_vector+2)
  655. lcall *init_librm_vector
  656. /* Call relocate() to determine target address for relocation.
  657. * relocate() will return with %esi, %edi and %ecx set up
  658. * ready for the copy to the new location.
  659. */
  660. movw %ax, (prot_call_vector+2)
  661. pushl $relocate
  662. lcall *prot_call_vector
  663. popl %edx /* discard */
  664. /* Copy code to new location */
  665. pushl %edi
  666. pushw %ax
  667. movw $copy_bytes, %ax
  668. call pm_call
  669. popw %ax
  670. popl %edi
  671. /* Initialise librm at new location */
  672. lcall *init_librm_vector
  673. #endif
  674. /* Restore registers */
  675. popw %es
  676. popw %ds
  677. popal
  678. ret
  679. .size install_prealloc, . - install_prealloc
  680. /* Vectors for far calls to .text16 functions */
  681. .section ".data16", "aw", @progbits
  682. #ifdef KEEP_IT_REAL
  683. init_libkir_vector:
  684. .word init_libkir
  685. .word 0
  686. .size init_libkir_vector, . - init_libkir_vector
  687. #else
  688. init_librm_vector:
  689. .word init_librm
  690. .word 0
  691. .size init_librm_vector, . - init_librm_vector
  692. prot_call_vector:
  693. .word prot_call
  694. .word 0
  695. .size prot_call_vector, . - prot_call_vector
  696. #endif
  697. /****************************************************************************
  698. * uninstall (real-mode near call)
  699. *
  700. * Uninstall all text and data segments.
  701. *
  702. * Parameters:
  703. * %ax : .text16 segment address
  704. * %bx : .data16 segment address
  705. * Returns:
  706. * none
  707. * Corrupts:
  708. * none
  709. ****************************************************************************
  710. */
  711. .section ".text16", "ax", @progbits
  712. .code16
  713. .globl uninstall
  714. uninstall:
  715. call free_basemem
  716. ret
  717. .size uninstall, . - uninstall
  718. /* File split information for the compressor */
  719. #if COMPRESS
  720. .section ".zinfo", "a", @progbits
  721. .ascii "COPY"
  722. .long _prefix_lma
  723. .long _prefix_filesz
  724. .long _max_align
  725. .ascii "PACK"
  726. .long _text16_lma
  727. .long _text16_filesz
  728. .long _max_align
  729. .ascii "PACK"
  730. .long _data16_lma
  731. .long _data16_filesz
  732. .long _max_align
  733. .ascii "PACK"
  734. .long _textdata_lma
  735. .long _textdata_filesz
  736. .long _max_align
  737. #else /* COMPRESS */
  738. .section ".zinfo", "a", @progbits
  739. .ascii "COPY"
  740. .long _prefix_lma
  741. .long _filesz
  742. .long _max_align
  743. #endif /* COMPRESS */