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