Statistics
| Branch: | Revision:

root / pc-bios / optionrom / linuxboot.S @ 57a46d05

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 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 57a46d05 Alexander Graf
	/* Set DS to SS+SP - 0x10, so we can write our GDT descriptor there */
83 57a46d05 Alexander Graf
	mov		%ss, %eax
84 57a46d05 Alexander Graf
	shl		$4, %eax
85 57a46d05 Alexander Graf
	add		%esp, %eax
86 57a46d05 Alexander Graf
	sub		$0x10, %eax
87 57a46d05 Alexander Graf
	shr		$4, %eax
88 57a46d05 Alexander Graf
89 57a46d05 Alexander Graf
	/* Now create the GDT descriptor */
90 57a46d05 Alexander Graf
	mov		%cs, %eax
91 57a46d05 Alexander Graf
	shl		$4, %eax
92 57a46d05 Alexander Graf
	movw		$((3 * 8) - 1), %bx
93 57a46d05 Alexander Graf
	movw		%bx, %gs:0
94 57a46d05 Alexander Graf
	movl		$gdt, %ebx
95 57a46d05 Alexander Graf
	add		%eax, %ebx
96 57a46d05 Alexander Graf
	movl		%ebx, %gs:2
97 57a46d05 Alexander Graf
98 57a46d05 Alexander Graf
	/* And load the GDT */
99 57a46d05 Alexander Graf
	data32 lgdt	%gs:0
100 57a46d05 Alexander Graf
101 57a46d05 Alexander Graf
	/* Get us to protected mode now */
102 57a46d05 Alexander Graf
	mov		$1, %eax
103 57a46d05 Alexander Graf
	mov		%eax, %cr0
104 57a46d05 Alexander Graf
105 57a46d05 Alexander Graf
	/* So we can set DS to a 32-bit segment */
106 57a46d05 Alexander Graf
	mov		$0x10, %eax
107 57a46d05 Alexander Graf
	mov		%eax, %ds
108 57a46d05 Alexander Graf
109 57a46d05 Alexander Graf
	/* We're now running in 16-bit CS, but 32-bit DS! */
110 57a46d05 Alexander Graf
111 57a46d05 Alexander Graf
	/* Load kernel and initrd */
112 57a46d05 Alexander Graf
	read_fw_blob(FW_CFG_KERNEL)
113 57a46d05 Alexander Graf
	read_fw_blob(FW_CFG_INITRD)
114 57a46d05 Alexander Graf
	read_fw_blob(FW_CFG_CMDLINE)
115 57a46d05 Alexander Graf
	read_fw_blob(FW_CFG_SETUP)
116 57a46d05 Alexander Graf
117 57a46d05 Alexander Graf
	/* And now jump into Linux! */
118 57a46d05 Alexander Graf
	mov		$0, %eax
119 57a46d05 Alexander Graf
	mov		%eax, %cr0
120 57a46d05 Alexander Graf
121 57a46d05 Alexander Graf
	/* DS = CS */
122 57a46d05 Alexander Graf
	mov		%cs, %ax
123 57a46d05 Alexander Graf
	mov		%ax, %ds
124 57a46d05 Alexander Graf
125 57a46d05 Alexander Graf
	jmp		boot_kernel
126 57a46d05 Alexander Graf
127 57a46d05 Alexander Graf
/* Variables */
128 57a46d05 Alexander Graf
129 57a46d05 Alexander Graf
.align 4, 0
130 57a46d05 Alexander Graf
gdt:
131 57a46d05 Alexander Graf
	/* 0x00 */
132 57a46d05 Alexander Graf
.byte	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
133 57a46d05 Alexander Graf
134 57a46d05 Alexander Graf
	/* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
135 57a46d05 Alexander Graf
.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
136 57a46d05 Alexander Graf
137 57a46d05 Alexander Graf
	/* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
138 57a46d05 Alexander Graf
.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
139 57a46d05 Alexander Graf
140 57a46d05 Alexander Graf
BOOT_ROM_END