~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to grub-core/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