~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, Robert Millan, Updated translations
  • Date: 2010-11-22 12:24:56 UTC
  • mfrom: (1.26.4 upstream) (17.3.36 sid)
  • mto: (17.3.43 sid)
  • mto: This revision was merged to the branch mainline in revision 89.
  • Revision ID: james.westby@ubuntu.com-20101122122456-y82z3sfb7k4zfdcc
Tags: 1.99~20101122-1
[ Colin Watson ]
* New Bazaar snapshot.  Too many changes to list in full, but some of the
  more user-visible ones are as follows:
  - GRUB script:
    + Function parameters, "break", "continue", "shift", "setparams",
      "return", and "!".
    + "export" command supports multiple variable names.
    + Multi-line quoted strings support.
    + Wildcard expansion.
  - sendkey support.
  - USB hotunplugging and USB serial support.
  - Rename CD-ROM to cd on BIOS.
  - Add new --boot-directory option to grub-install, grub-reboot, and
    grub-set-default; the old --root-directory option is still accepted
    but was often confusing.
  - Basic btrfs detection/UUID support (but no file reading yet).
  - bash-completion for utilities.
  - If a device is listed in device.map, always assume that it is
    BIOS-visible rather than using extra layers such as LVM or RAID.
  - Add grub-mknetdir script (closes: #550658).
  - Remove deprecated "root" command.
  - Handle RAID devices containing virtio components.
  - GRUB Legacy configuration file support (via grub-menulst2cfg).
  - Keyboard layout support (via grub-mklayout and grub-kbdcomp).
  - Check generated grub.cfg for syntax errors before saving.
  - Pause execution for at most ten seconds if any errors are displayed,
    so that the user has a chance to see them.
  - Support submenus.
  - Write embedding zone using Reed-Solomon, so that it's robust against
    being partially overwritten (closes: #550702, #591416, #593347).
  - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged
    into a single GRUB_DISABLE_RECOVERY variable.
  - Fix loader memory allocation failure (closes: #551627).
  - Don't call savedefault on recovery entries (closes: #589325).
  - Support triple-indirect blocks on ext2 (closes: #543924).
  - Recognise DDF1 fake RAID (closes: #603354).

[ Robert Millan ]
* Use dpkg architecture wildcards.

[ Updated translations ]
* Slovenian (Vanja Cvelbar).  Closes: #604003
* Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102

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