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

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