Statistics
| Branch: | Revision:

root / pc-bios / optionrom / linuxboot.S @ 076d2471

History | View | Annotate | Download (2.8 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 57a46d05 Alexander Graf
BOOT_ROM_START
26 57a46d05 Alexander Graf
27 57a46d05 Alexander Graf
run_linuxboot:
28 57a46d05 Alexander Graf
29 57a46d05 Alexander Graf
	cli
30 57a46d05 Alexander Graf
	cld
31 57a46d05 Alexander Graf
32 57a46d05 Alexander Graf
	jmp		copy_kernel
33 57a46d05 Alexander Graf
boot_kernel:
34 57a46d05 Alexander Graf
35 57a46d05 Alexander Graf
	read_fw		FW_CFG_SETUP_ADDR
36 57a46d05 Alexander Graf
37 57a46d05 Alexander Graf
	mov		%eax, %ebx
38 57a46d05 Alexander Graf
	shr		$4, %ebx
39 57a46d05 Alexander Graf
40 57a46d05 Alexander Graf
	/* All segments contain real_addr */
41 57a46d05 Alexander Graf
	mov		%bx, %ds
42 57a46d05 Alexander Graf
	mov		%bx, %es
43 57a46d05 Alexander Graf
	mov		%bx, %fs
44 57a46d05 Alexander Graf
	mov		%bx, %gs
45 57a46d05 Alexander Graf
	mov		%bx, %ss
46 57a46d05 Alexander Graf
47 57a46d05 Alexander Graf
	/* CX = CS we want to jump to */
48 57a46d05 Alexander Graf
	add		$0x20, %bx
49 57a46d05 Alexander Graf
	mov		%bx, %cx
50 57a46d05 Alexander Graf
51 57a46d05 Alexander Graf
	/* SP = cmdline_addr-real_addr-16 */
52 57a46d05 Alexander Graf
	read_fw		FW_CFG_CMDLINE_ADDR
53 57a46d05 Alexander Graf
	mov		%eax, %ebx
54 57a46d05 Alexander Graf
	read_fw		FW_CFG_SETUP_ADDR
55 57a46d05 Alexander Graf
	sub		%eax, %ebx
56 57a46d05 Alexander Graf
	sub		$16, %ebx
57 57a46d05 Alexander Graf
	mov		%ebx, %esp
58 57a46d05 Alexander Graf
59 57a46d05 Alexander Graf
	/* Build indirect lret descriptor */
60 57a46d05 Alexander Graf
	pushw		%cx		/* CS */
61 57a46d05 Alexander Graf
	xor		%ax, %ax
62 57a46d05 Alexander Graf
	pushw		%ax		/* IP = 0 */
63 57a46d05 Alexander Graf
64 57a46d05 Alexander Graf
	/* Clear registers */
65 57a46d05 Alexander Graf
	xor		%eax, %eax
66 57a46d05 Alexander Graf
	xor		%ebx, %ebx
67 57a46d05 Alexander Graf
	xor		%ecx, %ecx
68 57a46d05 Alexander Graf
	xor		%edx, %edx
69 57a46d05 Alexander Graf
	xor		%edi, %edi
70 57a46d05 Alexander Graf
	xor		%ebp, %ebp
71 57a46d05 Alexander Graf
72 57a46d05 Alexander Graf
	/* Jump to Linux */
73 57a46d05 Alexander Graf
	lret
74 57a46d05 Alexander Graf
75 57a46d05 Alexander Graf
76 57a46d05 Alexander Graf
copy_kernel:
77 57a46d05 Alexander Graf
78 57a46d05 Alexander Graf
	/* We need to load the kernel into memory we can't access in 16 bit
79 57a46d05 Alexander Graf
	   mode, so let's get into 32 bit mode, write the kernel and jump
80 57a46d05 Alexander Graf
	   back again. */
81 57a46d05 Alexander Graf
82 36ecd7c0 Paolo Bonzini
	/* Reserve space on the stack for our GDT descriptor. */
83 36ecd7c0 Paolo Bonzini
	mov		%esp, %ebp
84 36ecd7c0 Paolo Bonzini
	sub		$16, %esp
85 57a46d05 Alexander Graf
86 57a46d05 Alexander Graf
	/* Now create the GDT descriptor */
87 36ecd7c0 Paolo Bonzini
	movw		$((3 * 8) - 1), -16(%bp)
88 57a46d05 Alexander Graf
	mov		%cs, %eax
89 57a46d05 Alexander Graf
	shl		$4, %eax
90 36ecd7c0 Paolo Bonzini
	addl		$gdt, %ebx
91 36ecd7c0 Paolo Bonzini
	movl		%ebx, -14(%bp)
92 57a46d05 Alexander Graf
93 57a46d05 Alexander Graf
	/* And load the GDT */
94 36ecd7c0 Paolo Bonzini
	data32 lgdt	-16(%bp)
95 36ecd7c0 Paolo Bonzini
	mov		%ebp, %esp
96 57a46d05 Alexander Graf
97 57a46d05 Alexander Graf
	/* Get us to protected mode now */
98 57a46d05 Alexander Graf
	mov		$1, %eax
99 57a46d05 Alexander Graf
	mov		%eax, %cr0
100 57a46d05 Alexander Graf
101 dc61b0dc Alexander Graf
	/* So we can set ES to a 32-bit segment */
102 57a46d05 Alexander Graf
	mov		$0x10, %eax
103 dc61b0dc Alexander Graf
	mov		%eax, %es
104 57a46d05 Alexander Graf
105 dc61b0dc Alexander Graf
	/* We're now running in 16-bit CS, but 32-bit ES! */
106 57a46d05 Alexander Graf
107 57a46d05 Alexander Graf
	/* Load kernel and initrd */
108 57a46d05 Alexander Graf
	read_fw_blob(FW_CFG_KERNEL)
109 57a46d05 Alexander Graf
	read_fw_blob(FW_CFG_INITRD)
110 57a46d05 Alexander Graf
	read_fw_blob(FW_CFG_CMDLINE)
111 57a46d05 Alexander Graf
	read_fw_blob(FW_CFG_SETUP)
112 57a46d05 Alexander Graf
113 57a46d05 Alexander Graf
	/* And now jump into Linux! */
114 57a46d05 Alexander Graf
	mov		$0, %eax
115 57a46d05 Alexander Graf
	mov		%eax, %cr0
116 57a46d05 Alexander Graf
117 dc61b0dc Alexander Graf
	/* ES = CS */
118 57a46d05 Alexander Graf
	mov		%cs, %ax
119 dc61b0dc Alexander Graf
	mov		%ax, %es
120 57a46d05 Alexander Graf
121 57a46d05 Alexander Graf
	jmp		boot_kernel
122 57a46d05 Alexander Graf
123 57a46d05 Alexander Graf
/* Variables */
124 57a46d05 Alexander Graf
125 57a46d05 Alexander Graf
.align 4, 0
126 57a46d05 Alexander Graf
gdt:
127 57a46d05 Alexander Graf
	/* 0x00 */
128 57a46d05 Alexander Graf
.byte	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
129 57a46d05 Alexander Graf
130 57a46d05 Alexander Graf
	/* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
131 57a46d05 Alexander Graf
.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
132 57a46d05 Alexander Graf
133 57a46d05 Alexander Graf
	/* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
134 57a46d05 Alexander Graf
.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
135 57a46d05 Alexander Graf
136 57a46d05 Alexander Graf
BOOT_ROM_END