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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  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. * flatten_real_mode
  226. *
  227. * Set up 4GB segment limits
  228. *
  229. * Parameters:
  230. * none
  231. * Returns:
  232. * none
  233. * Corrupts:
  234. * none
  235. ****************************************************************************
  236. */
  237. #ifndef KEEP_IT_REAL
  238. /* GDT for protected-mode calls */
  239. .section ".prefix.lib", "awx", @progbits
  240. .align 16
  241. flatten_vars:
  242. flatten_gdt:
  243. flatten_gdt_limit: .word flatten_gdt_length - 1
  244. flatten_gdt_base: .long 0
  245. .word 0 /* padding */
  246. flatten_cs: /* 16-bit protected-mode flat code segment */
  247. .equ FLAT_CS, flatten_cs - flatten_gdt
  248. .word 0xffff, 0
  249. .byte 0, 0x9b, 0x8f, 0
  250. flatten_ss: /* 16-bit protected-mode flat stack segment */
  251. .equ FLAT_SS, flatten_ss - flatten_gdt
  252. .word 0xffff, 0
  253. .byte 0, 0x93, 0x8f, 0
  254. flatten_gdt_end:
  255. .equ flatten_gdt_length, . - flatten_gdt
  256. .size flatten_gdt, . - flatten_gdt
  257. .section ".prefix.lib", "awx", @progbits
  258. .align 16
  259. flatten_saved_gdt:
  260. .long 0, 0
  261. .size flatten_saved_gdt, . - flatten_saved_gdt
  262. .equ flatten_vars_size, . - flatten_vars
  263. #define FLATTEN_VAR(x) ( -flatten_vars_size + ( (x) - flatten_vars ) )
  264. .section ".prefix.lib", "awx", @progbits
  265. .code16
  266. flatten_real_mode:
  267. /* Preserve registers and flags, allocate local variable block */
  268. pushw %bp
  269. movw %sp, %bp
  270. subw $flatten_vars_size, %sp
  271. andw $0xfff0, %sp
  272. pushfl
  273. pushl %eax
  274. pushl %edi
  275. pushw %si
  276. pushw %cx
  277. pushw %gs
  278. pushw %fs
  279. pushw %es
  280. pushw %ds
  281. pushw %ss
  282. /* Fill local variable block and preserve GDT */
  283. pushw %ss
  284. popw %es
  285. movw $flatten_vars, %si
  286. leaw FLATTEN_VAR(flatten_vars)(%bp), %di
  287. movw $flatten_vars_size, %cx
  288. cs rep movsb
  289. sgdt FLATTEN_VAR(flatten_saved_gdt)(%bp)
  290. /* Set up GDT bases */
  291. xorl %eax, %eax
  292. movw %ss, %ax
  293. shll $4, %eax
  294. movzwl %bp, %edi
  295. addr32 leal FLATTEN_VAR(flatten_gdt)(%eax, %edi), %eax
  296. movl %eax, FLATTEN_VAR(flatten_gdt_base)(%bp)
  297. movw %cs, %ax
  298. movw $FLATTEN_VAR(flatten_cs), %di
  299. call set_seg_base
  300. movw %ss, %ax
  301. movw $FLATTEN_VAR(flatten_ss), %di
  302. call set_seg_base
  303. /* Switch temporarily to protected mode and set segment registers */
  304. pushw %cs
  305. pushw $2f
  306. cli
  307. data32 lgdt FLATTEN_VAR(flatten_gdt)(%bp)
  308. movl %cr0, %eax
  309. orb $CR0_PE, %al
  310. movl %eax, %cr0
  311. ljmp $FLAT_CS, $1f
  312. 1: movw $FLAT_SS, %ax
  313. movw %ax, %ss
  314. movw %ax, %ds
  315. movw %ax, %es
  316. movw %ax, %fs
  317. movw %ax, %gs
  318. movl %cr0, %eax
  319. andb $0!CR0_PE, %al
  320. movl %eax, %cr0
  321. lret
  322. 2: /* lret will ljmp to here */
  323. /* Restore GDT, registers and flags */
  324. data32 lgdt FLATTEN_VAR(flatten_saved_gdt)(%bp)
  325. popw %ss
  326. popw %ds
  327. popw %es
  328. popw %fs
  329. popw %gs
  330. popw %cx
  331. popw %si
  332. popl %edi
  333. popl %eax
  334. popfl
  335. movw %bp, %sp
  336. popw %bp
  337. ret
  338. .size flatten_real_mode, . - flatten_real_mode
  339. set_seg_base:
  340. rolw $4, %ax
  341. movw %ax, 2(%bp,%di)
  342. andw $0xfff0, 2(%bp,%di)
  343. movb %al, 4(%bp,%di)
  344. andb $0x0f, 4(%bp,%di)
  345. ret
  346. .size set_seg_base, . - set_seg_base
  347. #endif /* KEEP_IT_REAL */
  348. /****************************************************************************
  349. * copy_bytes
  350. *
  351. * Copy bytes
  352. *
  353. * Parameters:
  354. * %ds:esi : source address
  355. * %es:edi : destination address
  356. * %ecx : length
  357. * Returns:
  358. * %ds:esi : next source address
  359. * %es:edi : next destination address
  360. * Corrupts:
  361. * None
  362. ****************************************************************************
  363. */
  364. #if ! COMPRESS
  365. .section ".prefix.lib", "awx", @progbits
  366. .code16
  367. copy_bytes:
  368. pushl %ecx
  369. rep addr32 movsb
  370. popl %ecx
  371. ret
  372. .size copy_bytes, . - copy_bytes
  373. #endif /* COMPRESS */
  374. /****************************************************************************
  375. * install_block
  376. *
  377. * Install block to specified address
  378. *
  379. * Parameters:
  380. * %esi : source physical address (must be a multiple of 16)
  381. * %edi : destination physical address (must be a multiple of 16)
  382. * %ecx : length of (decompressed) data
  383. * %edx : total length of block (including any uninitialised data portion)
  384. * Returns:
  385. * %esi : next source physical address (will be a multiple of 16)
  386. * Corrupts:
  387. * none
  388. ****************************************************************************
  389. */
  390. .section ".prefix.lib", "awx", @progbits
  391. .code16
  392. install_block:
  393. /* Preserve registers */
  394. pushw %ds
  395. pushw %es
  396. pushl %ecx
  397. pushl %edi
  398. /* Convert %esi and %edi to %ds:esi and %es:edi */
  399. shrl $4, %esi
  400. movw %si, %ds
  401. xorw %si, %si
  402. shll $4, %esi
  403. shrl $4, %edi
  404. movw %di, %es
  405. xorw %di, %di
  406. shll $4, %edi
  407. #if COMPRESS
  408. /* Decompress source to destination */
  409. call decompress16
  410. #else
  411. /* Copy source to destination */
  412. call copy_bytes
  413. #endif
  414. /* Zero .bss portion */
  415. negl %ecx
  416. addl %edx, %ecx
  417. pushw %ax
  418. xorw %ax, %ax
  419. rep addr32 stosb
  420. popw %ax
  421. /* Round up %esi to start of next source block */
  422. addl $0xf, %esi
  423. andl $~0xf, %esi
  424. /* Convert %ds:esi back to a physical address */
  425. xorl %ecx, %ecx
  426. movw %ds, %cx
  427. shll $4, %ecx
  428. addl %ecx, %esi
  429. /* Restore registers and return */
  430. popl %edi
  431. popl %ecx
  432. popw %es
  433. popw %ds
  434. ret
  435. .size install_block, . - install_block
  436. /****************************************************************************
  437. * alloc_basemem
  438. *
  439. * Allocate space for .text16 and .data16 from top of base memory.
  440. * Memory is allocated using the BIOS free base memory counter at
  441. * 0x40:13.
  442. *
  443. * Parameters:
  444. * none
  445. * Returns:
  446. * %ax : .text16 segment address
  447. * %bx : .data16 segment address
  448. * Corrupts:
  449. * none
  450. ****************************************************************************
  451. */
  452. .section ".prefix.lib", "awx", @progbits
  453. .code16
  454. .globl alloc_basemem
  455. alloc_basemem:
  456. /* Preserve registers */
  457. pushw %fs
  458. /* FBMS => %ax as segment address */
  459. pushw $0x40
  460. popw %fs
  461. movw %fs:0x13, %ax
  462. shlw $6, %ax
  463. /* Calculate .data16 segment address */
  464. subw $_data16_memsz_pgh, %ax
  465. pushw %ax
  466. /* Calculate .text16 segment address */
  467. subw $_text16_memsz_pgh, %ax
  468. pushw %ax
  469. /* Update FBMS */
  470. shrw $6, %ax
  471. movw %ax, %fs:0x13
  472. /* Retrieve .text16 and .data16 segment addresses */
  473. popw %ax
  474. popw %bx
  475. /* Restore registers and return */
  476. popw %fs
  477. ret
  478. .size alloc_basemem, . - alloc_basemem
  479. /****************************************************************************
  480. * free_basemem
  481. *
  482. * Free space allocated with alloc_basemem.
  483. *
  484. * Parameters:
  485. * %ax : .text16 segment address
  486. * %bx : .data16 segment address
  487. * Returns:
  488. * %ax : 0 if successfully freed
  489. * Corrupts:
  490. * none
  491. ****************************************************************************
  492. */
  493. .section ".text16", "ax", @progbits
  494. .code16
  495. .globl free_basemem
  496. free_basemem:
  497. /* Preserve registers */
  498. pushw %fs
  499. /* Check FBMS counter */
  500. pushw %ax
  501. shrw $6, %ax
  502. pushw $0x40
  503. popw %fs
  504. cmpw %ax, %fs:0x13
  505. popw %ax
  506. jne 1f
  507. /* Check hooked interrupt count */
  508. cmpw $0, %cs:hooked_bios_interrupts
  509. jne 1f
  510. /* OK to free memory */
  511. addw $_text16_memsz_pgh, %ax
  512. addw $_data16_memsz_pgh, %ax
  513. shrw $6, %ax
  514. movw %ax, %fs:0x13
  515. xorw %ax, %ax
  516. 1: /* Restore registers and return */
  517. popw %fs
  518. ret
  519. .size free_basemem, . - free_basemem
  520. .section ".text16.data", "aw", @progbits
  521. .globl hooked_bios_interrupts
  522. hooked_bios_interrupts:
  523. .word 0
  524. .size hooked_bios_interrupts, . - hooked_bios_interrupts
  525. /****************************************************************************
  526. * install
  527. *
  528. * Install all text and data segments.
  529. *
  530. * Parameters:
  531. * none
  532. * Returns:
  533. * %ax : .text16 segment address
  534. * %bx : .data16 segment address
  535. * Corrupts:
  536. * none
  537. ****************************************************************************
  538. */
  539. .section ".prefix.lib", "awx", @progbits
  540. .code16
  541. .globl install
  542. install:
  543. /* Preserve registers */
  544. pushl %esi
  545. pushl %edi
  546. /* Allocate space for .text16 and .data16 */
  547. call alloc_basemem
  548. /* Image source = %cs:0000 */
  549. xorl %esi, %esi
  550. /* Image destination = HIGHMEM_LOADPOINT */
  551. movl $HIGHMEM_LOADPOINT, %edi
  552. /* Install text and data segments */
  553. call install_prealloc
  554. /* Restore registers and return */
  555. popl %edi
  556. popl %esi
  557. ret
  558. .size install, . - install
  559. /****************************************************************************
  560. * install_prealloc
  561. *
  562. * Install all text and data segments.
  563. *
  564. * Parameters:
  565. * %ax : .text16 segment address
  566. * %bx : .data16 segment address
  567. * %esi : Image source physical address (or zero for %cs:0000)
  568. * %edi : Decompression temporary area physical address
  569. * Corrupts:
  570. * none
  571. ****************************************************************************
  572. */
  573. .section ".prefix.lib", "awx", @progbits
  574. .code16
  575. .globl install_prealloc
  576. install_prealloc:
  577. /* Save registers */
  578. pushal
  579. pushw %ds
  580. pushw %es
  581. /* Sanity: clear the direction flag asap */
  582. cld
  583. #ifndef KEEP_IT_REAL
  584. /* Flatten real mode */
  585. call flatten_real_mode
  586. #endif
  587. /* Calculate physical address of payload (i.e. first source) */
  588. testl %esi, %esi
  589. jnz 1f
  590. movw %cs, %si
  591. shll $4, %esi
  592. 1: addl $_payload_lma, %esi
  593. /* Install .text16 and .data16 */
  594. pushl %edi
  595. movzwl %ax, %edi
  596. shll $4, %edi
  597. movl $_text16_memsz, %ecx
  598. movl %ecx, %edx
  599. call install_block /* .text16 */
  600. movzwl %bx, %edi
  601. shll $4, %edi
  602. movl $_data16_filesz, %ecx
  603. movl $_data16_memsz, %edx
  604. call install_block /* .data16 */
  605. popl %edi
  606. /* Set up %ds for access to .data16 */
  607. movw %bx, %ds
  608. #ifdef KEEP_IT_REAL
  609. /* Initialise libkir */
  610. movw %ax, (init_libkir_vector+2)
  611. lcall *init_libkir_vector
  612. #else
  613. /* Install .text and .data to temporary area in high memory,
  614. * prior to reading the E820 memory map and relocating
  615. * properly.
  616. */
  617. movl $_textdata_filesz, %ecx
  618. movl $_textdata_memsz, %edx
  619. call install_block
  620. /* Initialise librm at current location */
  621. movw %ax, (init_librm_vector+2)
  622. lcall *init_librm_vector
  623. /* Call relocate() to determine target address for relocation.
  624. * relocate() will return with %esi, %edi and %ecx set up
  625. * ready for the copy to the new location.
  626. */
  627. movw %ax, (prot_call_vector+2)
  628. pushl $relocate
  629. lcall *prot_call_vector
  630. popl %edx /* discard */
  631. /* Copy code to new location */
  632. pushl %edi
  633. xorw %ax, %ax
  634. movw %ax, %es
  635. es rep addr32 movsb
  636. popl %edi
  637. /* Initialise librm at new location */
  638. lcall *init_librm_vector
  639. #endif
  640. /* Restore registers */
  641. popw %es
  642. popw %ds
  643. popal
  644. ret
  645. .size install_prealloc, . - install_prealloc
  646. /* Vectors for far calls to .text16 functions. Must be in
  647. * .data16, since .prefix may not be writable.
  648. */
  649. .section ".data16", "aw", @progbits
  650. #ifdef KEEP_IT_REAL
  651. init_libkir_vector:
  652. .word init_libkir
  653. .word 0
  654. .size init_libkir_vector, . - init_libkir_vector
  655. #else
  656. init_librm_vector:
  657. .word init_librm
  658. .word 0
  659. .size init_librm_vector, . - init_librm_vector
  660. prot_call_vector:
  661. .word prot_call
  662. .word 0
  663. .size prot_call_vector, . - prot_call_vector
  664. #endif
  665. /****************************************************************************
  666. * uninstall
  667. *
  668. * Uninstall all text and data segments.
  669. *
  670. * Parameters:
  671. * %ax : .text16 segment address
  672. * %bx : .data16 segment address
  673. * Returns:
  674. * none
  675. * Corrupts:
  676. * none
  677. ****************************************************************************
  678. */
  679. .section ".text16", "ax", @progbits
  680. .code16
  681. .globl uninstall
  682. uninstall:
  683. call free_basemem
  684. ret
  685. .size uninstall, . - uninstall
  686. /* File split information for the compressor */
  687. #if COMPRESS
  688. .section ".zinfo", "a", @progbits
  689. .ascii "COPY"
  690. .long _prefix_lma
  691. .long _prefix_filesz
  692. .long _max_align
  693. .ascii "PACK"
  694. .long _text16_lma
  695. .long _text16_filesz
  696. .long _max_align
  697. .ascii "PACK"
  698. .long _data16_lma
  699. .long _data16_filesz
  700. .long _max_align
  701. .ascii "PACK"
  702. .long _textdata_lma
  703. .long _textdata_filesz
  704. .long _max_align
  705. #else /* COMPRESS */
  706. .section ".zinfo", "a", @progbits
  707. .ascii "COPY"
  708. .long _prefix_lma
  709. .long _filesz
  710. .long _max_align
  711. #endif /* COMPRESS */