]> git.proxmox.com Git - mirror_qemu.git/blame - pc-bios/optionrom/multiboot.S
Make -kernel for linux work with bochsbios
[mirror_qemu.git] / pc-bios / optionrom / multiboot.S
CommitLineData
f16408df
AG
1/*
2 * Multiboot Option ROM
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
8167ee88 15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
f16408df
AG
16 *
17 * Copyright Novell Inc, 2009
18 * Authors: Alexander Graf <agraf@suse.de>
19 */
20
dd4b2659 21#include "optionrom.h"
f16408df
AG
22
23#define MULTIBOOT_MAGIC 0x2badb002
24
77873196
AG
25#define GS_PROT_JUMP 0
26#define GS_GDT_DESC 6
27
f16408df 28
dd4b2659 29BOOT_ROM_START
f16408df
AG
30
31run_multiboot:
32
33 cli
34 cld
35
36 mov %cs, %eax
37 shl $0x4, %eax
38
77873196 39 /* set up a long jump descriptor that is PC relative */
f16408df 40
77873196
AG
41 /* move stack memory to %gs */
42 mov %ss, %ecx
43 shl $0x4, %ecx
44 mov %esp, %ebx
45 add %ebx, %ecx
46 sub $0x20, %ecx
47 sub $0x30, %esp
48 shr $0x4, %ecx
49 mov %cx, %gs
50
51 /* now push the indirect jump decriptor there */
f16408df
AG
52 mov (prot_jump), %ebx
53 add %eax, %ebx
77873196
AG
54 movl %ebx, %gs:GS_PROT_JUMP
55 mov $8, %bx
56 movw %bx, %gs:GS_PROT_JUMP + 4
57
58 /* fix the gdt descriptor to be PC relative */
59 movw (gdt_desc), %bx
60 movw %bx, %gs:GS_GDT_DESC
61 movl (gdt_desc+2), %ebx
62 add %eax, %ebx
63 movl %ebx, %gs:GS_GDT_DESC + 2
64
65 /* Read the bootinfo struct into RAM */
66 read_fw_blob(FW_CFG_INITRD)
f16408df
AG
67
68 /* FS = bootinfo_struct */
69 read_fw FW_CFG_INITRD_ADDR
70 shr $4, %eax
71 mov %ax, %fs
72
73 /* ES = mmap_addr */
77873196 74 mov %eax, %fs:0x48
f16408df
AG
75 shr $4, %eax
76 mov %ax, %es
77
78 /* Initialize multiboot mmap structs using int 0x15(e820) */
79 xor %ebx, %ebx
80 /* mmap start after first size */
81 movl $4, %edi
82
83mmap_loop:
84 /* entry size (mmap struct) & max buffer size (int15) */
85 movl $20, %ecx
86 /* store entry size */
ff56954b 87 /* old as(1) doesn't like this insn so emit the bytes instead:
f16408df 88 movl %ecx, %es:-4(%edi)
ff56954b
JL
89 */
90 .dc.b 0x26,0x67,0x66,0x89,0x4f,0xfc
f16408df
AG
91 /* e820 */
92 movl $0x0000e820, %eax
93 /* 'SMAP' magic */
94 movl $0x534d4150, %edx
95 int $0x15
96
97mmap_check_entry:
98 /* last entry? then we're done */
99 jb mmap_done
100 and %bx, %bx
101 jz mmap_done
102 /* valid entry, so let's loop on */
103
104mmap_store_entry:
105 /* %ax = entry_number * 24 */
106 mov $24, %ax
107 mul %bx
108 mov %ax, %di
109 movw %di, %fs:0x2c
110 /* %di = 4 + (entry_number * 24) */
111 add $4, %di
112 jmp mmap_loop
113
114mmap_done:
115real_to_prot:
116 /* Load the GDT before going into protected mode */
117lgdt:
77873196 118 data32 lgdt %gs:GS_GDT_DESC
f16408df
AG
119
120 /* get us to protected mode now */
121 movl $1, %eax
122 movl %eax, %cr0
123
124 /* the LJMP sets CS for us and gets us to 32-bit */
125ljmp:
77873196 126 data32 ljmp *%gs:GS_PROT_JUMP
f16408df
AG
127
128prot_mode:
129.code32
130
131 /* initialize all other segments */
132 movl $0x10, %eax
133 movl %eax, %ss
134 movl %eax, %ds
135 movl %eax, %es
136 movl %eax, %fs
137 movl %eax, %gs
138
77873196
AG
139 /* Read the kernel and modules into RAM */
140 read_fw_blob(FW_CFG_KERNEL)
141
f16408df 142 /* Jump off to the kernel */
77873196 143 read_fw FW_CFG_KERNEL_ENTRY
f16408df
AG
144 mov %eax, %ecx
145
146 /* EBX contains a pointer to the bootinfo struct */
147 read_fw FW_CFG_INITRD_ADDR
148 movl %eax, %ebx
149
150 /* EAX has to contain the magic */
151 movl $MULTIBOOT_MAGIC, %eax
152ljmp2:
153 jmp *%ecx
154
155/* Variables */
156.align 4, 0
f16408df
AG
157prot_jump: .long prot_mode
158 .short 8
159
160.align 4, 0
161gdt:
162 /* 0x00 */
163.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
164
165 /* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
166.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
167
168 /* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
169.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
170
171 /* 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b) */
172.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00
173
174 /* 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b) */
175.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00
176
177gdt_desc:
178.short (5 * 8) - 1
179.long gdt
180
dd4b2659 181BOOT_ROM_END