Statistics
| Branch: | Revision:

root / pc-bios / optionrom / linuxboot.S @ 75b9f690

History | View | Annotate | Download (2.9 kB)

1 57a46d05 Alexander Graf
/*
2 57a46d05 Alexander Graf
 * Linux Boot Option ROM
3 57a46d05 Alexander Graf
 *
4 57a46d05 Alexander Graf
 * This program is free software; you can redistribute it and/or modify
5 57a46d05 Alexander Graf
 * it under the terms of the GNU General Public License as published by
6 57a46d05 Alexander Graf
 * the Free Software Foundation; either version 2 of the License, or
7 57a46d05 Alexander Graf
 * (at your option) any later version.
8 57a46d05 Alexander Graf
 *
9 57a46d05 Alexander Graf
 * This program is distributed in the hope that it will be useful,
10 57a46d05 Alexander Graf
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 57a46d05 Alexander Graf
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 57a46d05 Alexander Graf
 * GNU General Public License for more details.
13 57a46d05 Alexander Graf
 *
14 57a46d05 Alexander Graf
 * You should have received a copy of the GNU General Public License
15 57a46d05 Alexander Graf
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 57a46d05 Alexander Graf
 *
17 57a46d05 Alexander Graf
 * Copyright Novell Inc, 2009
18 57a46d05 Alexander Graf
 *   Authors: Alexander Graf <agraf@suse.de>
19 57a46d05 Alexander Graf
 *
20 57a46d05 Alexander Graf
 * Based on code in hw/pc.c.
21 57a46d05 Alexander Graf
 */
22 57a46d05 Alexander Graf
23 57a46d05 Alexander Graf
#include "optionrom.h"
24 57a46d05 Alexander Graf
25 75b9f690 Gleb Natapov
#define BOOT_ROM_PRODUCT "Linux loader"
26 75b9f690 Gleb Natapov
27 57a46d05 Alexander Graf
BOOT_ROM_START
28 57a46d05 Alexander Graf
29 57a46d05 Alexander Graf
run_linuxboot:
30 57a46d05 Alexander Graf
31 57a46d05 Alexander Graf
	cli
32 57a46d05 Alexander Graf
	cld
33 57a46d05 Alexander Graf
34 57a46d05 Alexander Graf
	jmp		copy_kernel
35 57a46d05 Alexander Graf
boot_kernel:
36 57a46d05 Alexander Graf
37 57a46d05 Alexander Graf
	read_fw		FW_CFG_SETUP_ADDR
38 57a46d05 Alexander Graf
39 57a46d05 Alexander Graf
	mov		%eax, %ebx
40 57a46d05 Alexander Graf
	shr		$4, %ebx
41 57a46d05 Alexander Graf
42 57a46d05 Alexander Graf
	/* All segments contain real_addr */
43 57a46d05 Alexander Graf
	mov		%bx, %ds
44 57a46d05 Alexander Graf
	mov		%bx, %es
45 57a46d05 Alexander Graf
	mov		%bx, %fs
46 57a46d05 Alexander Graf
	mov		%bx, %gs
47 57a46d05 Alexander Graf
	mov		%bx, %ss
48 57a46d05 Alexander Graf
49 57a46d05 Alexander Graf
	/* CX = CS we want to jump to */
50 57a46d05 Alexander Graf
	add		$0x20, %bx
51 57a46d05 Alexander Graf
	mov		%bx, %cx
52 57a46d05 Alexander Graf
53 57a46d05 Alexander Graf
	/* SP = cmdline_addr-real_addr-16 */
54 57a46d05 Alexander Graf
	read_fw		FW_CFG_CMDLINE_ADDR
55 57a46d05 Alexander Graf
	mov		%eax, %ebx
56 57a46d05 Alexander Graf
	read_fw		FW_CFG_SETUP_ADDR
57 57a46d05 Alexander Graf
	sub		%eax, %ebx
58 57a46d05 Alexander Graf
	sub		$16, %ebx
59 57a46d05 Alexander Graf
	mov		%ebx, %esp
60 57a46d05 Alexander Graf
61 57a46d05 Alexander Graf
	/* Build indirect lret descriptor */
62 57a46d05 Alexander Graf
	pushw		%cx		/* CS */
63 57a46d05 Alexander Graf
	xor		%ax, %ax
64 57a46d05 Alexander Graf
	pushw		%ax		/* IP = 0 */
65 57a46d05 Alexander Graf
66 57a46d05 Alexander Graf
	/* Clear registers */
67 57a46d05 Alexander Graf
	xor		%eax, %eax
68 57a46d05 Alexander Graf
	xor		%ebx, %ebx
69 57a46d05 Alexander Graf
	xor		%ecx, %ecx
70 57a46d05 Alexander Graf
	xor		%edx, %edx
71 57a46d05 Alexander Graf
	xor		%edi, %edi
72 57a46d05 Alexander Graf
	xor		%ebp, %ebp
73 57a46d05 Alexander Graf
74 57a46d05 Alexander Graf
	/* Jump to Linux */
75 57a46d05 Alexander Graf
	lret
76 57a46d05 Alexander Graf
77 57a46d05 Alexander Graf
78 57a46d05 Alexander Graf
copy_kernel:
79 57a46d05 Alexander Graf
80 57a46d05 Alexander Graf
	/* We need to load the kernel into memory we can't access in 16 bit
81 57a46d05 Alexander Graf
	   mode, so let's get into 32 bit mode, write the kernel and jump
82 57a46d05 Alexander Graf
	   back again. */
83 57a46d05 Alexander Graf
84 36ecd7c0 Paolo Bonzini
	/* Reserve space on the stack for our GDT descriptor. */
85 36ecd7c0 Paolo Bonzini
	mov		%esp, %ebp
86 36ecd7c0 Paolo Bonzini
	sub		$16, %esp
87 57a46d05 Alexander Graf
88 57a46d05 Alexander Graf
	/* Now create the GDT descriptor */
89 36ecd7c0 Paolo Bonzini
	movw		$((3 * 8) - 1), -16(%bp)
90 57a46d05 Alexander Graf
	mov		%cs, %eax
91 d0652aa8 Avi Kivity
	movzwl		%ax, %eax
92 57a46d05 Alexander Graf
	shl		$4, %eax
93 d0652aa8 Avi Kivity
	addl		$gdt, %eax
94 d0652aa8 Avi Kivity
	movl		%eax, -14(%bp)
95 57a46d05 Alexander Graf
96 57a46d05 Alexander Graf
	/* And load the GDT */
97 36ecd7c0 Paolo Bonzini
	data32 lgdt	-16(%bp)
98 36ecd7c0 Paolo Bonzini
	mov		%ebp, %esp
99 57a46d05 Alexander Graf
100 57a46d05 Alexander Graf
	/* Get us to protected mode now */
101 57a46d05 Alexander Graf
	mov		$1, %eax
102 57a46d05 Alexander Graf
	mov		%eax, %cr0
103 57a46d05 Alexander Graf
104 dc61b0dc Alexander Graf
	/* So we can set ES to a 32-bit segment */
105 57a46d05 Alexander Graf
	mov		$0x10, %eax
106 dc61b0dc Alexander Graf
	mov		%eax, %es
107 57a46d05 Alexander Graf
108 dc61b0dc Alexander Graf
	/* We're now running in 16-bit CS, but 32-bit ES! */
109 57a46d05 Alexander Graf
110 57a46d05 Alexander Graf
	/* Load kernel and initrd */
111 590bf491 Alexander Graf
	read_fw_blob_addr32(FW_CFG_KERNEL)
112 590bf491 Alexander Graf
	read_fw_blob_addr32(FW_CFG_INITRD)
113 590bf491 Alexander Graf
	read_fw_blob_addr32(FW_CFG_CMDLINE)
114 590bf491 Alexander Graf
	read_fw_blob_addr32(FW_CFG_SETUP)
115 57a46d05 Alexander Graf
116 57a46d05 Alexander Graf
	/* And now jump into Linux! */
117 57a46d05 Alexander Graf
	mov		$0, %eax
118 57a46d05 Alexander Graf
	mov		%eax, %cr0
119 57a46d05 Alexander Graf
120 dc61b0dc Alexander Graf
	/* ES = CS */
121 57a46d05 Alexander Graf
	mov		%cs, %ax
122 dc61b0dc Alexander Graf
	mov		%ax, %es
123 57a46d05 Alexander Graf
124 57a46d05 Alexander Graf
	jmp		boot_kernel
125 57a46d05 Alexander Graf
126 57a46d05 Alexander Graf
/* Variables */
127 57a46d05 Alexander Graf
128 57a46d05 Alexander Graf
.align 4, 0
129 57a46d05 Alexander Graf
gdt:
130 57a46d05 Alexander Graf
	/* 0x00 */
131 57a46d05 Alexander Graf
.byte	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
132 57a46d05 Alexander Graf
133 57a46d05 Alexander Graf
	/* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
134 57a46d05 Alexander Graf
.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
135 57a46d05 Alexander Graf
136 57a46d05 Alexander Graf
	/* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
137 57a46d05 Alexander Graf
.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
138 57a46d05 Alexander Graf
139 57a46d05 Alexander Graf
BOOT_ROM_END