head_64.S 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /*
  2. * linux/boot/head.S
  3. *
  4. * Copyright (C) 1991, 1992, 1993 Linus Torvalds
  5. */
  6. /*
  7. * head.S contains the 32-bit startup code.
  8. *
  9. * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
  10. * the page directory will exist. The startup code will be overwritten by
  11. * the page directory. [According to comments etc elsewhere on a compressed
  12. * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
  13. *
  14. * Page 0 is deliberately kept safe, since System Management Mode code in
  15. * laptops may need to access the BIOS data stored there. This is also
  16. * useful for future device drivers that either access the BIOS via VM86
  17. * mode.
  18. */
  19. /*
  20. * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  21. */
  22. .code32
  23. .text
  24. #include <linux/init.h>
  25. #include <linux/linkage.h>
  26. #include <asm/segment.h>
  27. #include <asm/boot.h>
  28. #include <asm/msr.h>
  29. #include <asm/processor-flags.h>
  30. #include <asm/asm-offsets.h>
  31. #include <asm/bootparam.h>
  32. __HEAD
  33. .code32
  34. ENTRY(startup_32)
  35. /*
  36. * 32bit entry is 0 and it is ABI so immutable!
  37. * If we come here directly from a bootloader,
  38. * kernel(text+data+bss+brk) ramdisk, zero_page, command line
  39. * all need to be under the 4G limit.
  40. */
  41. cld
  42. /*
  43. * Test KEEP_SEGMENTS flag to see if the bootloader is asking
  44. * us to not reload segments
  45. */
  46. testb $KEEP_SEGMENTS, BP_loadflags(%esi)
  47. jnz 1f
  48. cli
  49. movl $(__BOOT_DS), %eax
  50. movl %eax, %ds
  51. movl %eax, %es
  52. movl %eax, %ss
  53. 1:
  54. /*
  55. * Calculate the delta between where we were compiled to run
  56. * at and where we were actually loaded at. This can only be done
  57. * with a short local call on x86. Nothing else will tell us what
  58. * address we are running at. The reserved chunk of the real-mode
  59. * data at 0x1e4 (defined as a scratch field) are used as the stack
  60. * for this calculation. Only 4 bytes are needed.
  61. */
  62. leal (BP_scratch+4)(%esi), %esp
  63. call 1f
  64. 1: popl %ebp
  65. subl $1b, %ebp
  66. /* setup a stack and make sure cpu supports long mode. */
  67. movl $boot_stack_end, %eax
  68. addl %ebp, %eax
  69. movl %eax, %esp
  70. call verify_cpu
  71. testl %eax, %eax
  72. jnz no_longmode
  73. /*
  74. * Compute the delta between where we were compiled to run at
  75. * and where the code will actually run at.
  76. *
  77. * %ebp contains the address we are loaded at by the boot loader and %ebx
  78. * contains the address where we should move the kernel image temporarily
  79. * for safe in-place decompression.
  80. */
  81. #ifdef CONFIG_RELOCATABLE
  82. movl %ebp, %ebx
  83. movl BP_kernel_alignment(%esi), %eax
  84. decl %eax
  85. addl %eax, %ebx
  86. notl %eax
  87. andl %eax, %ebx
  88. cmpl $LOAD_PHYSICAL_ADDR, %ebx
  89. jge 1f
  90. #endif
  91. movl $LOAD_PHYSICAL_ADDR, %ebx
  92. 1:
  93. /* Target address to relocate to for decompression */
  94. addl $z_extract_offset, %ebx
  95. /*
  96. * Prepare for entering 64 bit mode
  97. */
  98. /* Load new GDT with the 64bit segments using 32bit descriptor */
  99. leal gdt(%ebp), %eax
  100. movl %eax, gdt+2(%ebp)
  101. lgdt gdt(%ebp)
  102. /* Enable PAE mode */
  103. movl %cr4, %eax
  104. orl $X86_CR4_PAE, %eax
  105. movl %eax, %cr4
  106. /*
  107. * Build early 4G boot pagetable
  108. */
  109. /* Initialize Page tables to 0 */
  110. leal pgtable(%ebx), %edi
  111. xorl %eax, %eax
  112. movl $((4096*6)/4), %ecx
  113. rep stosl
  114. /* Build Level 4 */
  115. leal pgtable + 0(%ebx), %edi
  116. leal 0x1007 (%edi), %eax
  117. movl %eax, 0(%edi)
  118. /* Build Level 3 */
  119. leal pgtable + 0x1000(%ebx), %edi
  120. leal 0x1007(%edi), %eax
  121. movl $4, %ecx
  122. 1: movl %eax, 0x00(%edi)
  123. addl $0x00001000, %eax
  124. addl $8, %edi
  125. decl %ecx
  126. jnz 1b
  127. /* Build Level 2 */
  128. leal pgtable + 0x2000(%ebx), %edi
  129. movl $0x00000183, %eax
  130. movl $2048, %ecx
  131. 1: movl %eax, 0(%edi)
  132. addl $0x00200000, %eax
  133. addl $8, %edi
  134. decl %ecx
  135. jnz 1b
  136. /* Enable the boot page tables */
  137. leal pgtable(%ebx), %eax
  138. movl %eax, %cr3
  139. /* Enable Long mode in EFER (Extended Feature Enable Register) */
  140. movl $MSR_EFER, %ecx
  141. rdmsr
  142. btsl $_EFER_LME, %eax
  143. wrmsr
  144. /* After gdt is loaded */
  145. xorl %eax, %eax
  146. lldt %ax
  147. movl $__BOOT_TSS, %eax
  148. ltr %ax
  149. /*
  150. * Setup for the jump to 64bit mode
  151. *
  152. * When the jump is performend we will be in long mode but
  153. * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1
  154. * (and in turn EFER.LMA = 1). To jump into 64bit mode we use
  155. * the new gdt/idt that has __KERNEL_CS with CS.L = 1.
  156. * We place all of the values on our mini stack so lret can
  157. * used to perform that far jump.
  158. */
  159. pushl $__KERNEL_CS
  160. leal startup_64(%ebp), %eax
  161. #ifdef CONFIG_EFI_MIXED
  162. movl efi32_config(%ebp), %ebx
  163. cmp $0, %ebx
  164. jz 1f
  165. leal handover_entry(%ebp), %eax
  166. 1:
  167. #endif
  168. pushl %eax
  169. /* Enter paged protected Mode, activating Long Mode */
  170. movl $(X86_CR0_PG | X86_CR0_PE), %eax /* Enable Paging and Protected mode */
  171. movl %eax, %cr0
  172. /* Jump from 32bit compatibility mode into 64bit mode. */
  173. lret
  174. ENDPROC(startup_32)
  175. #ifdef CONFIG_EFI_MIXED
  176. .org 0x190
  177. ENTRY(efi32_stub_entry)
  178. add $0x4, %esp /* Discard return address */
  179. popl %ecx
  180. popl %edx
  181. popl %esi
  182. leal (BP_scratch+4)(%esi), %esp
  183. call 1f
  184. 1: pop %ebp
  185. subl $1b, %ebp
  186. movl %ecx, efi32_config(%ebp)
  187. movl %edx, efi32_config+8(%ebp)
  188. sgdtl efi32_boot_gdt(%ebp)
  189. leal efi32_config(%ebp), %eax
  190. movl %eax, efi_config(%ebp)
  191. jmp startup_32
  192. ENDPROC(efi32_stub_entry)
  193. #endif
  194. .code64
  195. .org 0x200
  196. ENTRY(startup_64)
  197. /*
  198. * 64bit entry is 0x200 and it is ABI so immutable!
  199. * We come here either from startup_32 or directly from a
  200. * 64bit bootloader.
  201. * If we come here from a bootloader, kernel(text+data+bss+brk),
  202. * ramdisk, zero_page, command line could be above 4G.
  203. * We depend on an identity mapped page table being provided
  204. * that maps our entire kernel(text+data+bss+brk), zero page
  205. * and command line.
  206. */
  207. #ifdef CONFIG_EFI_STUB
  208. /*
  209. * The entry point for the PE/COFF executable is efi_pe_entry, so
  210. * only legacy boot loaders will execute this jmp.
  211. */
  212. jmp preferred_addr
  213. ENTRY(efi_pe_entry)
  214. movq %rcx, efi64_config(%rip) /* Handle */
  215. movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */
  216. leaq efi64_config(%rip), %rax
  217. movq %rax, efi_config(%rip)
  218. call 1f
  219. 1: popq %rbp
  220. subq $1b, %rbp
  221. /*
  222. * Relocate efi_config->call().
  223. */
  224. addq %rbp, efi64_config+88(%rip)
  225. movq %rax, %rdi
  226. call make_boot_params
  227. cmpq $0,%rax
  228. je fail
  229. mov %rax, %rsi
  230. leaq startup_32(%rip), %rax
  231. movl %eax, BP_code32_start(%rsi)
  232. jmp 2f /* Skip the relocation */
  233. handover_entry:
  234. call 1f
  235. 1: popq %rbp
  236. subq $1b, %rbp
  237. /*
  238. * Relocate efi_config->call().
  239. */
  240. movq efi_config(%rip), %rax
  241. addq %rbp, 88(%rax)
  242. 2:
  243. movq efi_config(%rip), %rdi
  244. call efi_main
  245. movq %rax,%rsi
  246. cmpq $0,%rax
  247. jne 2f
  248. fail:
  249. /* EFI init failed, so hang. */
  250. hlt
  251. jmp fail
  252. 2:
  253. movl BP_code32_start(%esi), %eax
  254. leaq preferred_addr(%rax), %rax
  255. jmp *%rax
  256. preferred_addr:
  257. #endif
  258. /* Setup data segments. */
  259. xorl %eax, %eax
  260. movl %eax, %ds
  261. movl %eax, %es
  262. movl %eax, %ss
  263. movl %eax, %fs
  264. movl %eax, %gs
  265. /*
  266. * Compute the decompressed kernel start address. It is where
  267. * we were loaded at aligned to a 2M boundary. %rbp contains the
  268. * decompressed kernel start address.
  269. *
  270. * If it is a relocatable kernel then decompress and run the kernel
  271. * from load address aligned to 2MB addr, otherwise decompress and
  272. * run the kernel from LOAD_PHYSICAL_ADDR
  273. *
  274. * We cannot rely on the calculation done in 32-bit mode, since we
  275. * may have been invoked via the 64-bit entry point.
  276. */
  277. /* Start with the delta to where the kernel will run at. */
  278. #ifdef CONFIG_RELOCATABLE
  279. leaq startup_32(%rip) /* - $startup_32 */, %rbp
  280. movl BP_kernel_alignment(%rsi), %eax
  281. decl %eax
  282. addq %rax, %rbp
  283. notq %rax
  284. andq %rax, %rbp
  285. cmpq $LOAD_PHYSICAL_ADDR, %rbp
  286. jge 1f
  287. #endif
  288. movq $LOAD_PHYSICAL_ADDR, %rbp
  289. 1:
  290. /* Target address to relocate to for decompression */
  291. leaq z_extract_offset(%rbp), %rbx
  292. /* Set up the stack */
  293. leaq boot_stack_end(%rbx), %rsp
  294. /* Zero EFLAGS */
  295. pushq $0
  296. popfq
  297. /*
  298. * Copy the compressed kernel to the end of our buffer
  299. * where decompression in place becomes safe.
  300. */
  301. pushq %rsi
  302. leaq (_bss-8)(%rip), %rsi
  303. leaq (_bss-8)(%rbx), %rdi
  304. movq $_bss /* - $startup_32 */, %rcx
  305. shrq $3, %rcx
  306. std
  307. rep movsq
  308. cld
  309. popq %rsi
  310. /*
  311. * Jump to the relocated address.
  312. */
  313. leaq relocated(%rbx), %rax
  314. jmp *%rax
  315. #ifdef CONFIG_EFI_STUB
  316. .org 0x390
  317. ENTRY(efi64_stub_entry)
  318. movq %rdi, efi64_config(%rip) /* Handle */
  319. movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */
  320. leaq efi64_config(%rip), %rax
  321. movq %rax, efi_config(%rip)
  322. movq %rdx, %rsi
  323. jmp handover_entry
  324. ENDPROC(efi64_stub_entry)
  325. #endif
  326. .text
  327. relocated:
  328. /*
  329. * Clear BSS (stack is currently empty)
  330. */
  331. xorl %eax, %eax
  332. leaq _bss(%rip), %rdi
  333. leaq _ebss(%rip), %rcx
  334. subq %rdi, %rcx
  335. shrq $3, %rcx
  336. rep stosq
  337. /*
  338. * Adjust our own GOT
  339. */
  340. leaq _got(%rip), %rdx
  341. leaq _egot(%rip), %rcx
  342. 1:
  343. cmpq %rcx, %rdx
  344. jae 2f
  345. addq %rbx, (%rdx)
  346. addq $8, %rdx
  347. jmp 1b
  348. 2:
  349. /*
  350. * Do the decompression, and jump to the new kernel..
  351. */
  352. pushq %rsi /* Save the real mode argument */
  353. movq $z_run_size, %r9 /* size of kernel with .bss and .brk */
  354. pushq %r9
  355. movq %rsi, %rdi /* real mode address */
  356. leaq boot_heap(%rip), %rsi /* malloc area for uncompression */
  357. leaq input_data(%rip), %rdx /* input_data */
  358. movl $z_input_len, %ecx /* input_len */
  359. movq %rbp, %r8 /* output target address */
  360. movq $z_output_len, %r9 /* decompressed length, end of relocs */
  361. call decompress_kernel /* returns kernel location in %rax */
  362. popq %r9
  363. popq %rsi
  364. /*
  365. * Jump to the decompressed kernel.
  366. */
  367. jmp *%rax
  368. .code32
  369. no_longmode:
  370. /* This isn't an x86-64 CPU so hang */
  371. 1:
  372. hlt
  373. jmp 1b
  374. #include "../../kernel/verify_cpu.S"
  375. .data
  376. gdt:
  377. .word gdt_end - gdt
  378. .long gdt
  379. .word 0
  380. .quad 0x0000000000000000 /* NULL descriptor */
  381. .quad 0x00af9a000000ffff /* __KERNEL_CS */
  382. .quad 0x00cf92000000ffff /* __KERNEL_DS */
  383. .quad 0x0080890000000000 /* TS descriptor */
  384. .quad 0x0000000000000000 /* TS continued */
  385. gdt_end:
  386. #ifdef CONFIG_EFI_STUB
  387. efi_config:
  388. .quad 0
  389. #ifdef CONFIG_EFI_MIXED
  390. .global efi32_config
  391. efi32_config:
  392. .fill 11,8,0
  393. .quad efi64_thunk
  394. .byte 0
  395. #endif
  396. .global efi64_config
  397. efi64_config:
  398. .fill 11,8,0
  399. .quad efi_call
  400. .byte 1
  401. #endif /* CONFIG_EFI_STUB */
  402. /*
  403. * Stack and heap for uncompression
  404. */
  405. .bss
  406. .balign 4
  407. boot_heap:
  408. .fill BOOT_HEAP_SIZE, 1, 0
  409. boot_stack:
  410. .fill BOOT_STACK_SIZE, 1, 0
  411. boot_stack_end:
  412. /*
  413. * Space for page tables (not in .bss so not zeroed)
  414. */
  415. .section ".pgtable","a",@nobits
  416. .balign 4096
  417. pgtable:
  418. .fill 6*4096, 1, 0