~darkmuggle-deactivatedaccount/ubuntu/quantal/grub2/fix-872244

« back to all changes in this revision

Viewing changes to kern/i386/realmode.S

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  GRUB  --  GRand Unified Bootloader
3
 
 *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc.
4
 
 *
5
 
 *  GRUB is free software: you can redistribute it and/or modify
6
 
 *  it under the terms of the GNU General Public License as published by
7
 
 *  the Free Software Foundation, either version 3 of the License, or
8
 
 *  (at your option) any later version.
9
 
 *
10
 
 *  GRUB is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
17
 
 */
18
 
 
19
 
#include <grub/i386/pc/memory.h>
20
 
 
21
 
/*
22
 
 * Note: These functions defined in this file may be called from C.
23
 
 *       Be careful of that you must not modify some registers. Quote
24
 
 *       from gcc-2.95.2/gcc/config/i386/i386.h:
25
 
 
26
 
   1 for registers not available across function calls.
27
 
   These must include the FIXED_REGISTERS and also any
28
 
   registers that can be used without being saved.
29
 
   The latter must include the registers where values are returned
30
 
   and the register where structure-value addresses are passed.
31
 
   Aside from that, you can include as many other registers as you like.
32
 
 
33
 
  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
34
 
{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
35
 
 */
36
 
 
37
 
/*
38
 
 * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
39
 
 *       So the first three arguments are passed in %eax, %edx, and %ecx,
40
 
 *       respectively, and if a function has a fixed number of arguments
41
 
 *       and the number if greater than three, the function must return
42
 
 *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
43
 
 */
44
 
 
45
 
/*
46
 
 *  This is the area for all of the special variables.
47
 
 */
48
 
 
49
 
        .p2align        2       /* force 4-byte alignment */
50
 
 
51
 
protstack:
52
 
        .long   GRUB_MEMORY_MACHINE_PROT_STACK
53
 
 
54
 
/*
55
 
 * This is the Global Descriptor Table
56
 
 *
57
 
 *  An entry, a "Segment Descriptor", looks like this:
58
 
 *
59
 
 * 31          24         19   16                 7           0
60
 
 * ------------------------------------------------------------
61
 
 * |             | |B| |A|       | |   |1|0|E|W|A|            |
62
 
 * | BASE 31..24 |G|/|L|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |  4
63
 
 * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
64
 
 * ------------------------------------------------------------
65
 
 * |                             |                            |
66
 
 * |        BASE 15..0           |       LIMIT 15..0          |  0
67
 
 * |                             |                            |
68
 
 * ------------------------------------------------------------
69
 
 *
70
 
 *  Note the ordering of the data items is reversed from the above
71
 
 *  description.
72
 
 */
73
 
 
74
 
        .p2align        2       /* force 4-byte alignment */
75
 
gdt:
76
 
        .word   0, 0
77
 
        .byte   0, 0, 0, 0
78
 
 
79
 
        /* -- code segment --
80
 
         * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
81
 
         * type = 32bit code execute/read, DPL = 0
82
 
         */
83
 
        .word   0xFFFF, 0
84
 
        .byte   0, 0x9A, 0xCF, 0
85
 
 
86
 
        /* -- data segment --
87
 
         * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
88
 
         * type = 32 bit data read/write, DPL = 0
89
 
         */
90
 
        .word   0xFFFF, 0
91
 
        .byte   0, 0x92, 0xCF, 0
92
 
 
93
 
        /* -- 16 bit real mode CS --
94
 
         * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
95
 
         * type = 16 bit code execute/read only/conforming, DPL = 0
96
 
         */
97
 
        .word   0xFFFF, 0
98
 
        .byte   0, 0x9E, 0, 0
99
 
 
100
 
        /* -- 16 bit real mode DS --
101
 
         * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
102
 
         * type = 16 bit data read/write, DPL = 0
103
 
         */
104
 
        .word   0xFFFF, 0
105
 
        .byte   0, 0x92, 0, 0
106
 
 
107
 
 
108
 
/* this is the GDT descriptor */
109
 
gdtdesc:
110
 
        .word   0x27                    /* limit */
111
 
        .long   gdt                     /* addr */
112
 
 
113
 
/*
114
 
 *  These next two routines, "real_to_prot" and "prot_to_real" are structured
115
 
 *  in a very specific way.  Be very careful when changing them.
116
 
 *
117
 
 *  NOTE:  Use of either one messes up %eax and %ebp.
118
 
 */
119
 
 
120
 
real_to_prot:
121
 
        .code16
122
 
        cli
123
 
 
124
 
        /* load the GDT register */
125
 
        xorw    %ax, %ax
126
 
        movw    %ax, %ds
127
 
        DATA32  ADDR32  lgdt    gdtdesc
128
 
 
129
 
        /* turn on protected mode */
130
 
        movl    %cr0, %eax
131
 
        orl     $GRUB_MEMORY_CPU_CR0_PE_ON, %eax
132
 
        movl    %eax, %cr0
133
 
 
134
 
        /* jump to relocation, flush prefetch queue, and reload %cs */
135
 
        DATA32  ljmp    $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
136
 
 
137
 
        .code32
138
 
protcseg:
139
 
        /* reload other segment registers */
140
 
        movw    $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
141
 
        movw    %ax, %ds
142
 
        movw    %ax, %es
143
 
        movw    %ax, %fs
144
 
        movw    %ax, %gs
145
 
        movw    %ax, %ss
146
 
 
147
 
        /* put the return address in a known safe location */
148
 
        movl    (%esp), %eax
149
 
        movl    %eax, GRUB_MEMORY_MACHINE_REAL_STACK
150
 
 
151
 
        /* get protected mode stack */
152
 
        movl    protstack, %eax
153
 
        movl    %eax, %esp
154
 
        movl    %eax, %ebp
155
 
 
156
 
        /* get return address onto the right stack */
157
 
        movl    GRUB_MEMORY_MACHINE_REAL_STACK, %eax
158
 
        movl    %eax, (%esp)
159
 
 
160
 
        /* zero %eax */
161
 
        xorl    %eax, %eax
162
 
 
163
 
        /* return on the old (or initialized) stack! */
164
 
        ret
165
 
 
166
 
prot_to_real:
167
 
        /* just in case, set GDT */
168
 
        lgdt    gdtdesc
169
 
 
170
 
        /* save the protected mode stack */
171
 
        movl    %esp, %eax
172
 
        movl    %eax, protstack
173
 
 
174
 
        /* get the return address */
175
 
        movl    (%esp), %eax
176
 
        movl    %eax, GRUB_MEMORY_MACHINE_REAL_STACK
177
 
 
178
 
        /* set up new stack */
179
 
        movl    $GRUB_MEMORY_MACHINE_REAL_STACK, %eax
180
 
        movl    %eax, %esp
181
 
        movl    %eax, %ebp
182
 
 
183
 
        /* set up segment limits */
184
 
        movw    $GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
185
 
        movw    %ax, %ds
186
 
        movw    %ax, %es
187
 
        movw    %ax, %fs
188
 
        movw    %ax, %gs
189
 
        movw    %ax, %ss
190
 
 
191
 
        /* this might be an extra step */
192
 
        /* jump to a 16 bit segment */
193
 
        ljmp    $GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
194
 
 
195
 
tmpcseg:
196
 
        .code16
197
 
 
198
 
        /* clear the PE bit of CR0 */
199
 
        movl    %cr0, %eax
200
 
        andl    $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax
201
 
        movl    %eax, %cr0
202
 
 
203
 
        /* flush prefetch queue, reload %cs */
204
 
        DATA32  ljmp    $0, $realcseg
205
 
 
206
 
realcseg:
207
 
        /* we are in real mode now
208
 
         * set up the real mode segment registers : DS, SS, ES
209
 
         */
210
 
        /* zero %eax */
211
 
        xorl    %eax, %eax
212
 
 
213
 
        movw    %ax, %ds
214
 
        movw    %ax, %es
215
 
        movw    %ax, %fs
216
 
        movw    %ax, %gs
217
 
        movw    %ax, %ss
218
 
 
219
 
#ifdef GRUB_MACHINE_PCBIOS
220
 
        /* restore interrupts */
221
 
        sti
222
 
#endif
223
 
 
224
 
        /* return on new stack! */
225
 
        DATA32  ret
226
 
 
227
 
        .code32
228
 
 
229
 
/*
230
 
 * grub_reboot()
231
 
 *
232
 
 * Reboot the system. At the moment, rely on BIOS.
233
 
 */
234
 
FUNCTION(grub_reboot)
235
 
        call    prot_to_real
236
 
        .code16
237
 
cold_reboot:
238
 
        /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */
239
 
        movw    $0x0472, %di
240
 
        movw    %ax, (%di)
241
 
        ljmp    $0xf000, $0xfff0
242
 
        .code32