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.

bImageprefix.S 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. /*
  2. Copyright (C) 2000, Entity Cyber, Inc.
  3. Authors: Gary Byers (gb@thinguin.org)
  4. Marty Connor (mdc@thinguin.org)
  5. Eric Biederman (ebiederman@lnxi.com)
  6. This code also derives a lot from arch/i386/boot/setup.S in
  7. the linux kernel.
  8. This software may be used and distributed according to the terms
  9. of the GNU Public License (GPL), incorporated herein by reference.
  10. Description:
  11. This is just a little bit of code and data that can get prepended
  12. to an Etherboot ROM image in order to allow LILO to load the
  13. result as if it were a Linux kernel image.
  14. A real Linux kernel image consists of a one-sector boot loader
  15. (to load the image from a floppy disk), followed a few sectors
  16. of setup code, followed by the kernel code itself. There's
  17. a table in the first sector (starting at offset 497) that indicates
  18. how many sectors of setup code follow the first sector and which
  19. contains some other parameters that aren't interesting in this
  20. case.
  21. When LILO loads the sectors that comprise a kernel image, it doesn't
  22. execute the code in the first sector (since that code would try to
  23. load the image from a floppy disk.) The code in the first sector
  24. below doesn't expect to get executed (and prints an error message
  25. if it ever -is- executed.) LILO's only interested in knowing the
  26. number of setup sectors advertised in the table (at offset 497 in
  27. the first sector.)
  28. Etherboot doesn't require much in the way of setup code.
  29. Historically, the Linux kernel required at least 4 sectors of
  30. setup code. Current versions of LILO look at the byte at
  31. offset 497 in the first sector to indicate how many sectors
  32. of setup code are contained in the image.
  33. The setup code that is present here does a lot of things
  34. exactly the way the linux kernel does them instead of in
  35. ways more typical of etherboot. Generally this is so
  36. the code can be strongly compatible with the linux kernel.
  37. In addition the general etherboot technique of enabling the a20
  38. after we switch into protected mode does not work if etherboot
  39. is being loaded at 1MB.
  40. */
  41. .equ CR0_PE,1
  42. #ifdef GAS291
  43. #define DATA32 data32;
  44. #define ADDR32 addr32;
  45. #define LJMPI(x) ljmp x
  46. #else
  47. #define DATA32 data32
  48. #define ADDR32 addr32
  49. /* newer GAS295 require #define LJMPI(x) ljmp *x */
  50. #define LJMPI(x) ljmp x
  51. #endif
  52. /* Simple and small GDT entries for booting only */
  53. #define GDT_ENTRY_BOOT_CS 2
  54. #define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1)
  55. #define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8)
  56. #define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8)
  57. #define SETUPSECS 4 /* Minimal nr of setup-sectors */
  58. #define PREFIXSIZE ((SETUPSECS+1)*512)
  59. #define PREFIXPGH (PREFIXSIZE / 16 )
  60. #define BOOTSEG 0x07C0 /* original address of boot-sector */
  61. #define INITSEG 0x9000 /* we move boot here - out of the way */
  62. #define SETUPSEG 0x9020 /* setup starts here */
  63. #define SYSSEG 0x1000 /* system loaded at 0x10000 (65536). */
  64. #define DELTA_INITSEG (SETUPSEG - INITSEG) /* 0x0020 */
  65. /* Signature words to ensure LILO loaded us right */
  66. #define SIG1 0xAA55
  67. #define SIG2 0x5A5A
  68. .text
  69. .code16
  70. .arch i386
  71. .org 0
  72. .section ".prefix", "ax", @progbits
  73. _prefix:
  74. /*
  75. This is a minimal boot sector. If anyone tries to execute it (e.g., if
  76. a .lilo file is dd'ed to a floppy), print an error message.
  77. */
  78. bootsector:
  79. jmp $BOOTSEG, $go - _prefix /* reload cs:ip to match relocation addr */
  80. go:
  81. movw $0x2000, %di /* 0x2000 is arbitrary value >= length
  82. of bootsect + room for stack */
  83. movw $BOOTSEG, %ax
  84. movw %ax,%ds
  85. movw %ax,%es
  86. cli
  87. movw %ax, %ss /* put stack at BOOTSEG:0x2000. */
  88. movw %di,%sp
  89. sti
  90. movw $why_end-why, %cx
  91. movw $why - _prefix, %si
  92. movw $0x0007, %bx /* page 0, attribute 7 (normal) */
  93. movb $0x0e, %ah /* write char, tty mode */
  94. prloop:
  95. lodsb
  96. int $0x10
  97. loop prloop
  98. freeze: jmp freeze
  99. why: .ascii "This image cannot be loaded from a floppy disk.\r\n"
  100. why_end:
  101. .org 497
  102. setup_sects:
  103. .byte SETUPSECS
  104. root_flags:
  105. .word 0
  106. syssize:
  107. .word _verbatim_size_pgh - PREFIXPGH
  108. swap_dev:
  109. .word 0
  110. ram_size:
  111. .word 0
  112. vid_mode:
  113. .word 0
  114. root_dev:
  115. .word 0
  116. boot_flag:
  117. .word 0xAA55
  118. /*
  119. We're now at the beginning of the second sector of the image -
  120. where the setup code goes.
  121. We don't need to do too much setup for Etherboot.
  122. This code gets loaded at SETUPSEG:0. It wants to start
  123. executing the Etherboot image that's loaded at SYSSEG:0 and
  124. whose entry point is SYSSEG:0.
  125. */
  126. setup_code:
  127. jmp trampoline
  128. # This is the setup header, and it must start at %cs:2 (old 0x9020:2)
  129. .ascii "HdrS" # header signature
  130. .word 0x0203 # header version number (>= 0x0105)
  131. # or else old loadlin-1.5 will fail)
  132. realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
  133. start_sys_seg: .word SYSSEG # low load segment (obsolete)
  134. .word kernel_version - setup_code
  135. # pointing to kernel version string
  136. # above section of header is compatible
  137. # with loadlin-1.5 (header v1.5). Don't
  138. # change it.
  139. type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin,
  140. # Bootlin, SYSLX, bootsect...)
  141. # See Documentation/i386/boot.txt for
  142. # assigned ids
  143. # flags, unused bits must be zero (RFU) bit within loadflags
  144. loadflags:
  145. LOADED_HIGH = 1 # If set, the kernel is loaded high
  146. CAN_USE_HEAP = 0x80 # If set, the loader also has set
  147. # heap_end_ptr to tell how much
  148. # space behind setup.S can be used for
  149. # heap purposes.
  150. # Only the loader knows what is free
  151. .byte LOADED_HIGH
  152. setup_move_size: .word 0x8000 # size to move, when setup is not
  153. # loaded at 0x90000. We will move setup
  154. # to 0x90000 then just before jumping
  155. # into the kernel. However, only the
  156. # loader knows how much data behind
  157. # us also needs to be loaded.
  158. code32_start: # here loaders can put a different
  159. # start address for 32-bit code.
  160. .long 0x100000 # 0x100000 = default for big kernel
  161. ramdisk_image: .long 0 # address of loaded ramdisk image
  162. # Here the loader puts the 32-bit
  163. # address where it loaded the image.
  164. # This only will be read by the kernel.
  165. ramdisk_size: .long 0 # its size in bytes
  166. bootsect_kludge:
  167. .long 0 # obsolete
  168. heap_end_ptr: .word 0 # (Header version 0x0201 or later)
  169. # space from here (exclusive) down to
  170. # end of setup code can be used by setup
  171. # for local heap purposes.
  172. pad1: .word 0
  173. cmd_line_ptr: .long 0 # (Header version 0x0202 or later)
  174. # If nonzero, a 32-bit pointer
  175. # to the kernel command line.
  176. # The command line should be
  177. # located between the start of
  178. # setup and the end of low
  179. # memory (0xa0000), or it may
  180. # get overwritten before it
  181. # gets read. If this field is
  182. # used, there is no longer
  183. # anything magical about the
  184. # 0x90000 segment; the setup
  185. # can be located anywhere in
  186. # low memory 0x10000 or higher.
  187. ramdisk_max: .long 0 # (Header version 0x0203 or later)
  188. # The highest safe address for
  189. # the contents of an initrd
  190. trampoline: call start_of_setup
  191. trampoline_end:
  192. .space 1024
  193. # End of setup header #####################################################
  194. start_of_setup:
  195. # Set %ds = %cs, we know that SETUPSEG = %cs at this point
  196. movw %cs, %ax # aka SETUPSEG
  197. movw %ax, %ds
  198. # Check signature at end of setup
  199. cmpw $SIG1, (setup_sig1 - setup_code)
  200. jne bad_sig
  201. cmpw $SIG2, (setup_sig2 - setup_code)
  202. jne bad_sig
  203. jmp good_sig1
  204. # Routine to print asciiz string at ds:si
  205. prtstr:
  206. lodsb
  207. andb %al, %al
  208. jz fin
  209. call prtchr
  210. jmp prtstr
  211. fin: ret
  212. # Part of above routine, this one just prints ascii al
  213. prtchr: pushw %ax
  214. pushw %cx
  215. movw $7,%bx
  216. movw $0x01, %cx
  217. movb $0x0e, %ah
  218. int $0x10
  219. popw %cx
  220. popw %ax
  221. ret
  222. no_sig_mess: .string "No setup signature found ..."
  223. good_sig1:
  224. jmp good_sig
  225. # We now have to find the rest of the setup code/data
  226. bad_sig:
  227. movw %cs, %ax # SETUPSEG
  228. subw $DELTA_INITSEG, %ax # INITSEG
  229. movw %ax, %ds
  230. xorb %bh, %bh
  231. movb (497), %bl # get setup sect from bootsect
  232. subw $4, %bx # LILO loads 4 sectors of setup
  233. shlw $8, %bx # convert to words (1sect=2^8 words)
  234. movw %bx, %cx
  235. shrw $3, %bx # convert to segment
  236. addw $SYSSEG, %bx
  237. movw %bx, %cs:(start_sys_seg - setup_code)
  238. # Move rest of setup code/data to here
  239. movw $2048, %di # four sectors loaded by LILO
  240. subw %si, %si
  241. pushw %cs
  242. popw %es
  243. movw $SYSSEG, %ax
  244. movw %ax, %ds
  245. rep
  246. movsw
  247. movw %cs, %ax # aka SETUPSEG
  248. movw %ax, %ds
  249. cmpw $SIG1, (setup_sig1 - setup_code)
  250. jne no_sig
  251. cmpw $SIG2, (setup_sig2 - setup_code)
  252. jne no_sig
  253. jmp good_sig
  254. no_sig:
  255. lea (no_sig_mess - setup_code), %si
  256. call prtstr
  257. no_sig_loop:
  258. hlt
  259. jmp no_sig_loop
  260. good_sig:
  261. cmpw $0, %cs:(realmode_swtch - setup_code)
  262. jz rmodeswtch_normal
  263. lcall *%cs:(realmode_swtch - setup_code)
  264. jmp rmodeswtch_end
  265. rmodeswtch_normal:
  266. pushw %cs
  267. call default_switch
  268. rmodeswtch_end:
  269. # we get the code32 start address and modify the below 'jmpi'
  270. # (loader may have changed it)
  271. movl %cs:(code32_start - setup_code), %eax
  272. movl %eax, %cs:(code32 - setup_code)
  273. # then we load the segment descriptors
  274. movw %cs, %ax # aka SETUPSEG
  275. movw %ax, %ds
  276. #
  277. # Enable A20. This is at the very best an annoying procedure.
  278. # A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
  279. #
  280. A20_TEST_LOOPS = 32 # Iterations per wait
  281. A20_ENABLE_LOOPS = 255 # Total loops to try
  282. a20_try_loop:
  283. # First, see if we are on a system with no A20 gate.
  284. a20_none:
  285. call a20_test
  286. jnz a20_done
  287. # Next, try the BIOS (INT 0x15, AX=0x2401)
  288. a20_bios:
  289. movw $0x2401, %ax
  290. pushfl # Be paranoid about flags
  291. int $0x15
  292. popfl
  293. call a20_test
  294. jnz a20_done
  295. # Try enabling A20 through the keyboard controller
  296. a20_kbc:
  297. call empty_8042
  298. call a20_test # Just in case the BIOS worked
  299. jnz a20_done # but had a delayed reaction.
  300. movb $0xD1, %al # command write
  301. outb %al, $0x64
  302. call empty_8042
  303. movb $0xDF, %al # A20 on
  304. outb %al, $0x60
  305. call empty_8042
  306. # Wait until a20 really *is* enabled; it can take a fair amount of
  307. # time on certain systems; Toshiba Tecras are known to have this
  308. # problem.
  309. a20_kbc_wait:
  310. xorw %cx, %cx
  311. a20_kbc_wait_loop:
  312. call a20_test
  313. jnz a20_done
  314. loop a20_kbc_wait_loop
  315. # Final attempt: use "configuration port A"
  316. a20_fast:
  317. inb $0x92, %al # Configuration Port A
  318. orb $0x02, %al # "fast A20" version
  319. andb $0xFE, %al # don't accidentally reset
  320. outb %al, $0x92
  321. # Wait for configuration port A to take effect
  322. a20_fast_wait:
  323. xorw %cx, %cx
  324. a20_fast_wait_loop:
  325. call a20_test
  326. jnz a20_done
  327. loop a20_fast_wait_loop
  328. # A20 is still not responding. Try frobbing it again.
  329. #
  330. decb (a20_tries - setup_code)
  331. jnz a20_try_loop
  332. movw $(a20_err_msg - setup_code), %si
  333. call prtstr
  334. a20_die:
  335. hlt
  336. jmp a20_die
  337. a20_tries:
  338. .byte A20_ENABLE_LOOPS
  339. a20_err_msg:
  340. .ascii "linux: fatal error: A20 gate not responding!"
  341. .byte 13, 10, 0
  342. # If we get here, all is good
  343. a20_done:
  344. # Leave the idt alone
  345. # set up gdt
  346. xorl %eax, %eax # Compute gdt_base
  347. movw %ds, %ax # (Convert %ds:gdt to a linear ptr)
  348. shll $4, %eax
  349. addl $(bImage_gdt - setup_code), %eax
  350. movl %eax, (bImage_gdt_48+2 - setup_code)
  351. DATA32 lgdt %ds:(bImage_gdt_48 - setup_code) # load gdt with whatever is
  352. # appropriate
  353. # Switch to protected mode
  354. movl %cr0, %eax
  355. orb $CR0_PE, %al
  356. movl %eax, %cr0
  357. DATA32 ljmp %ds:(code32 - setup_code)
  358. code32:
  359. .long 0x100000
  360. .word __BOOT_CS, 0
  361. # Here's a bunch of information about your current kernel..
  362. kernel_version: .ascii "Etherboot "
  363. .ascii VERSION
  364. .byte 0
  365. # This is the default real mode switch routine.
  366. # to be called just before protected mode transition
  367. default_switch:
  368. cli # no interrupts allowed !
  369. movb $0x80, %al # disable NMI for bootup
  370. # sequence
  371. outb %al, $0x70
  372. lret
  373. # This routine tests whether or not A20 is enabled. If so, it
  374. # exits with zf = 0.
  375. #
  376. # The memory address used, 0x200, is the int $0x80 vector, which
  377. # should be safe.
  378. A20_TEST_ADDR = 4*0x80
  379. a20_test:
  380. pushw %cx
  381. pushw %ax
  382. xorw %cx, %cx
  383. movw %cx, %fs # Low memory
  384. decw %cx
  385. movw %cx, %gs # High memory area
  386. movw $A20_TEST_LOOPS, %cx
  387. movw %fs:(A20_TEST_ADDR), %ax
  388. pushw %ax
  389. a20_test_wait:
  390. incw %ax
  391. movw %ax, %fs:(A20_TEST_ADDR)
  392. call delay # Serialize and make delay constant
  393. cmpw %gs:(A20_TEST_ADDR+0x10), %ax
  394. loope a20_test_wait
  395. popw %fs:(A20_TEST_ADDR)
  396. popw %ax
  397. popw %cx
  398. ret
  399. # This routine checks that the keyboard command queue is empty
  400. # (after emptying the output buffers)
  401. #
  402. # Some machines have delusions that the keyboard buffer is always full
  403. # with no keyboard attached...
  404. #
  405. # If there is no keyboard controller, we will usually get 0xff
  406. # to all the reads. With each IO taking a microsecond and
  407. # a timeout of 100,000 iterations, this can take about half a
  408. # second ("delay" == outb to port 0x80). That should be ok,
  409. # and should also be plenty of time for a real keyboard controller
  410. # to empty.
  411. #
  412. empty_8042:
  413. pushl %ecx
  414. movl $100000, %ecx
  415. empty_8042_loop:
  416. decl %ecx
  417. jz empty_8042_end_loop
  418. call delay
  419. inb $0x64, %al # 8042 status port
  420. testb $1, %al # output buffer?
  421. jz no_output
  422. call delay
  423. inb $0x60, %al # read it
  424. jmp empty_8042_loop
  425. no_output:
  426. testb $2, %al # is input buffer full?
  427. jnz empty_8042_loop # yes - loop
  428. empty_8042_end_loop:
  429. popl %ecx
  430. # Delay is needed after doing I/O
  431. delay:
  432. outb %al,$0x80
  433. ret
  434. # Descriptor tables
  435. #
  436. # NOTE: The intel manual says gdt should be sixteen bytes aligned for
  437. # efficiency reasons. However, there are machines which are known not
  438. # to boot with misaligned GDTs, so alter this at your peril! If you alter
  439. # GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
  440. # empty GDT entries (one for NULL and one reserved).
  441. #
  442. # NOTE: On some CPUs, the GDT must be 8 byte aligned. This is
  443. # true for the Voyager Quad CPU card which will not boot without
  444. # This directive. 16 byte aligment is recommended by intel.
  445. #
  446. .balign 16
  447. bImage_gdt:
  448. .fill GDT_ENTRY_BOOT_CS,8,0
  449. .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
  450. .word 0 # base address = 0
  451. .word 0x9A00 # code read/exec
  452. .word 0x00CF # granularity = 4096, 386
  453. # (+5th nibble of limit)
  454. .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
  455. .word 0 # base address = 0
  456. .word 0x9200 # data read/write
  457. .word 0x00CF # granularity = 4096, 386
  458. # (+5th nibble of limit)
  459. bImage_gdt_end:
  460. .balign 4
  461. .word 0 # alignment byte
  462. bImage_idt_48:
  463. .word 0 # idt limit = 0
  464. .long 0 # idt base = 0L
  465. .word 0 # alignment byte
  466. bImage_gdt_48:
  467. .word bImage_gdt_end - bImage_gdt - 1 # gdt limit
  468. .long bImage_gdt_48 - setup_code # gdt base (filled in later)
  469. .section ".text16", "ax", @progbits
  470. prefix_exit:
  471. int $0x19 /* should try to boot machine */
  472. prefix_exit_end:
  473. .previous
  474. .org (PREFIXSIZE - 4)
  475. # Setup signature -- must be last
  476. setup_sig1: .word SIG1
  477. setup_sig2: .word SIG2
  478. /* Etherboot expects to be contiguous in memory once loaded.
  479. * The linux bImage protocol does not do this, but since we
  480. * don't need any information that's left in the prefix, it
  481. * doesn't matter: we just have to ensure that we make it to _start
  482. *
  483. * protected_start will live at 0x100000 and it will be the
  484. * the first code called as we enter protected mode.
  485. */
  486. .code32
  487. protected_start:
  488. /* Load segment registers */
  489. movw $__BOOT_DS, %ax
  490. movw %ax, %ss
  491. movw %ax, %ds
  492. movw %ax, %es
  493. movw %ax, %fs
  494. movw %ax, %gs
  495. /* Use the internal etherboot stack */
  496. movl $(_prefix_stack_end - protected_start + 0x100000), %esp
  497. pushl $0 /* No parameters to preserve for exit path */
  498. pushl $0 /* Use prefix exit path mechanism */
  499. jmp _start
  500. /*
  501. That's about it.
  502. */