2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
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.
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.
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/>.
21
* Note: These functions defined in this file may be called from C.
22
* Be careful of that you must not modify some registers. Quote
23
* from gcc-2.95.2/gcc/config/i386/i386.h:
25
1 for registers not available across function calls.
26
These must include the FIXED_REGISTERS and also any
27
registers that can be used without being saved.
28
The latter must include the registers where values are returned
29
and the register where structure-value addresses are passed.
30
Aside from that, you can include as many other registers as you like.
32
ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
33
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
37
* Note: GRUB is compiled with the options -mrtd and -mregparm=3.
38
* So the first three arguments are passed in %eax, %edx, and %ecx,
39
* respectively, and if a function has a fixed number of arguments
40
* and the number is greater than three, the function must return
41
* with "ret $N" where N is ((the number of arguments) - 3) * 4.
45
#include <grub/symbol.h>
46
#include <grub/boot.h>
47
#include <grub/machine/boot.h>
48
#include <grub/machine/memory.h>
49
#include <grub/machine/console.h>
50
#include <grub/cpu/linux.h>
51
#include <grub/machine/kernel.h>
52
#include <grub/term.h>
53
#include <multiboot.h>
54
#include <multiboot2.h>
56
#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
62
/* Tell GAS to generate 16-bit instructions so that this code works
71
* Guarantee that "main" is loaded at 0x0:0x8200.
74
ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000)
76
ljmp $0, $ABS(LOCAL (codestart))
79
* Compatibility version number
81
* These MUST be at byte offset 6 and 7 of the executable
85
.byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
88
* This is a special data area 8 bytes from the beginning.
93
VARIABLE(grub_total_module_size)
95
VARIABLE(grub_kernel_image_size)
97
VARIABLE(grub_compressed_size)
99
VARIABLE(grub_install_dos_part)
101
VARIABLE(grub_install_bsd_part)
103
VARIABLE(grub_prefix)
104
/* to be filled by grub-mkimage */
107
* Leave some breathing room for the prefix.
110
. = _start + GRUB_KERNEL_MACHINE_DATA_END
120
* Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
121
* This uses the a.out kludge to load raw binary to the area starting at 1MB,
122
* and relocates itself after loaded.
124
.p2align 2 /* force 4-byte alignment */
131
.long -0x1BADB002 - (1 << 16)
133
.long multiboot_header - _start + 0x100000 + 0x200
141
.long multiboot_entry - _start + 0x100000 + 0x200
145
/* obtain the boot device */
148
movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp
151
/* relocate the code */
152
movl $(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx
153
addl EXT_C(grub_compressed_size) - _start + 0x100000 + 0x200, %ecx
155
movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi
159
/* jump to the real address */
160
movl $multiboot_trampoline, %eax
163
multiboot_trampoline:
164
/* fill the boot information */
171
movl %ebx, EXT_C(grub_install_dos_part)
176
movl %ebx, EXT_C(grub_install_bsd_part)
180
/* enter the usual booting */
184
/* the real mode code continues... */
186
cli /* we're not safe here! */
188
/* set up %ds, %ss, and %es */
194
/* set up the real mode/BIOS stack */
195
movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
198
sti /* we're safe again */
200
/* save the boot drive */
201
ADDR32 movb %dl, EXT_C(grub_boot_drive)
203
/* reset disk system (%ah = 0) */
206
/* transition to protected mode */
207
DATA32 call real_to_prot
209
/* The ".code32" directive takes GAS out of 16-bit mode. */
213
call EXT_C(grub_gate_a20)
216
movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
217
movl $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi
220
movl EXT_C(grub_kernel_image_size), %ecx
221
addl EXT_C(grub_total_module_size), %ecx
222
subl $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx
224
leal (%edi, %ecx), %ebx
226
/* _LzmaDecodeA clears DF, so no need to run cld */
232
/* copy back the decompressed part (except the modules) */
233
subl EXT_C(grub_total_module_size), %ecx
238
/* copy modules before cleaning out the bss */
239
movl EXT_C(grub_total_module_size), %ecx
240
movl EXT_C(grub_kernel_image_size), %esi
244
movl $END_SYMBOL, %edi
253
/* clean out the bss */
254
bss_start_abs = ABS (bss_start)
255
bss_end_abs = ABS (bss_end)
257
movl bss_start_abs, %edi
259
/* compute the bss length */
260
movl bss_end_abs, %ecx
263
/* clean out the bss */
264
movl $BSS_START_SYMBOL, %edi
266
/* compute the bss length */
267
movl $END_SYMBOL, %ecx
278
* Call the start of main body of C code.
280
call EXT_C(grub_main)
283
* This is the area for all of the special variables.
286
VARIABLE(grub_boot_drive)
289
.p2align 2 /* force 4-byte alignment */
291
#include "../realmode.S"
294
* grub_gate_a20(int on)
296
* Gate address-line 20 for high memory.
298
* This routine is probably overconservative in what it does, but so what?
300
* It also eats any keystrokes in the keyboard buffer. :-(
303
FUNCTION(grub_gate_a20)
306
gate_a20_test_current_state:
307
/* first of all, test if already in a good state */
308
call gate_a20_check_state
310
jnz gate_a20_try_bios
314
/* second, try a BIOS call */
325
DATA32 call real_to_prot
329
call gate_a20_check_state
331
jnz gate_a20_try_system_control_port_a
334
gate_a20_try_system_control_port_a:
336
* In macbook, the keyboard test would hang the machine, so we move
339
/* fourth, try the system control port A */
347
/* When turning off Gate A20, do not check the state strictly,
348
because a failure is not fatal usually, and Gate A20 is always
349
on some modern machines. */
352
call gate_a20_check_state
354
jnz gate_a20_try_keyboard_controller
357
gate_a20_flush_keyboard_buffer:
360
jnz gate_a20_flush_keyboard_buffer
370
gate_a20_try_keyboard_controller:
371
/* third, try the keyboard controller */
372
call gate_a20_flush_keyboard_buffer
386
call gate_a20_flush_keyboard_buffer
388
/* output a dummy command (USB keyboard hack) */
391
call gate_a20_flush_keyboard_buffer
393
call gate_a20_check_state
395
/* everything failed, so restart from the beginning */
396
jnz gate_a20_try_bios
399
gate_a20_check_state:
400
/* iterate the checking for a while */
413
/* compare the byte at 0x8000 with that at 0x108000 */
414
movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx
416
/* save the original byte in CL */
418
/* store the value at 0x108000 in AL */
421
/* try to set one less value at 0x8000 */
429
/* obtain the value at 0x108000 in CH */
433
/* this result is 1 if A20 is on or 0 if it is off */
436
/* restore the original */
444
#include "lzma_decode.S"
448
* The code beyond this point is compressed. Assert that the uncompressed
449
* code fits GRUB_KERNEL_MACHINE_RAW_SIZE.
451
. = _start + GRUB_KERNEL_MACHINE_RAW_SIZE
454
* This next part is sort of evil. It takes advantage of the
455
* byte ordering on the x86 to work in either 16-bit or 32-bit
456
* mode, so think about it before changing it.
459
FUNCTION(grub_hard_stop)
461
jmp EXT_C(grub_hard_stop)
467
* Stop the floppy drive from spinning, so that other software is
468
* jumped to with a known state.
470
FUNCTION(grub_stop_floppy)
484
/* Tell the BIOS a boot failure. If this does not work, reboot. */
490
* grub_halt(int no_apm)
492
* Halt the system, using APM if possible. If NO_APM is true, don't use
493
* APM even if it is available.
507
jc EXT_C(grub_hard_stop)
508
/* don't check %bx for buggy BIOSes... */
510
/* disconnect APM first */
519
jc EXT_C(grub_hard_stop)
521
/* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */
526
jc EXT_C(grub_hard_stop)
528
/* set the power state to off */
534
/* shouldn't reach here */
535
jmp EXT_C(grub_hard_stop)
540
* void grub_chainloader_real_boot (int drive, void *part_addr)
542
* This starts another boot loader.
545
FUNCTION(grub_chainloader_real_boot)
549
call EXT_C(grub_dl_unload_all)
551
/* Turn off Gate A20 */
553
call EXT_C(grub_gate_a20)
555
/* set up to pass boot drive */
558
/* ESI must point to a partition table entry */
563
ljmp $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR
566
#include "../loader.S"
569
* int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
571
* Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP
572
* is passed for disk address packet. If an error occurs, return
573
* non-zero, otherwise zero.
576
FUNCTION(grub_biosdisk_rw_int13_extensions)
580
/* compute the address of disk_address_packet */
583
shrl $4, %ecx /* save the segment to cx */
587
/* enter real mode */
593
int $0x13 /* do the operation */
594
movb %ah, %dl /* save return value */
595
/* back to protected mode */
596
DATA32 call real_to_prot
599
movb %dl, %al /* return value in %eax */
607
* int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
608
* int soff, int nsec, int segment)
610
* Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
611
* NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
612
* return non-zero, otherwise zero.
615
FUNCTION(grub_biosdisk_rw_standard)
623
/* set up CHS information */
625
/* set %ch to low eight bits of cylinder */
627
/* set bits 6-7 of %cl to high two bits of cylinder */
629
/* set bits 0-5 of %cl to sector */
631
/* set %dh to head */
635
/* set %al to NSEC */
637
/* save %ax in %di */
639
/* save SEGMENT in %bx */
642
/* enter real mode */
648
movw $3, %si /* attempt at least three times */
652
int $0x13 /* do the operation */
653
jnc 2f /* check if successful */
655
movb %ah, %bl /* save return value */
656
/* if fail, reset the disk system */
666
/* back to protected mode */
667
DATA32 call real_to_prot
670
movb %bl, %al /* return value in %eax */
681
* int grub_biosdisk_check_int13_extensions (int drive)
683
* Check if LBA is supported for DRIVE. If it is supported, then return
684
* the major version of extensions, otherwise zero.
687
FUNCTION(grub_biosdisk_check_int13_extensions)
693
/* enter real mode */
699
int $0x13 /* do the operation */
701
/* check the result */
706
movb %ah, %bl /* save the major version into %bl */
708
/* check if AH=0x42 is supported */
715
/* back to protected mode */
716
DATA32 call real_to_prot
719
movb %bl, %al /* return value in %eax */
728
* int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
730
* Return the cdrom information of DRIVE in CDRP. If an error occurs,
731
* then return non-zero, otherwise zero.
734
FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions)
739
* int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
741
* Return the geometry of DRIVE in a drive parameters, DRP. If an error
742
* occurs, then return non-zero, otherwise zero.
745
FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
752
/* compute the address of drive parameters */
756
movw %dx, %bx /* save the segment into %bx */
759
/* enter real mode */
765
int $0x13 /* do the operation */
767
/* Clean return value if carry isn't set to workaround
768
some buggy BIOSes. */
771
movb %ah, %bl /* save return value in %bl */
772
/* back to protected mode */
773
DATA32 call real_to_prot
776
movb %bl, %al /* return value in %eax */
786
* int grub_biosdisk_get_diskinfo_standard (int drive,
787
* unsigned long *cylinders,
788
* unsigned long *heads,
789
* unsigned long *sectors)
791
* Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
792
* error occurs, then return non-zero, otherwise zero.
795
FUNCTION(grub_biosdisk_get_diskinfo_standard)
804
/* SECTORS is on the stack */
808
/* enter real mode */
813
int $0x13 /* do the operation */
815
/* Clean return value if carry isn't set to workaround
816
some buggy BIOSes. */
819
/* check if successful */
822
/* bogus BIOSes may not return an error number */
823
testb $0x3f, %cl /* 0 sectors means no disk */
824
jnz 1f /* if non-zero, then succeed */
825
/* XXX 0x60 is one of the unused error numbers */
828
movb %ah, %bl /* save return value in %bl */
829
/* back to protected mode */
830
DATA32 call real_to_prot
836
incl %eax /* the number of heads is counted from zero */
843
shrb $6, %ah /* the number of cylinders is counted from zero */
848
movl 0x10(%esp), %edi
854
movb %bl, %al /* return value in %eax */
864
* int grub_biosdisk_get_num_floppies (void)
866
FUNCTION(grub_biosdisk_get_num_floppies)
873
/* reset the disk system first */
878
/* call GET DISK TYPE */
884
/* check if this drive exists */
892
DATA32 call real_to_prot
902
* grub_get_memsize(i) : return the memory size in KB. i == 0 for conventional
903
* memory, i == 1 for extended memory
904
* BIOS call "INT 12H" to get conventional memory size
905
* BIOS call "INT 15H, AH=88H" to get extended memory size
906
* Both have the return value in AX.
910
FUNCTION(grub_get_memsize)
915
call prot_to_real /* enter real mode */
931
DATA32 call real_to_prot
942
* grub_get_eisa_mmap() : return packed EISA memory map, lower 16 bits is
943
* memory between 1M and 16M in 1K parts, upper 16 bits is
944
* memory above 16M in 64K parts. If error, return zero.
945
* BIOS call "INT 15H, AH=E801H" to get EISA memory map,
946
* AX = memory between 1M and 16M in 1K parts.
947
* BX = memory above 16M in 64K parts.
951
FUNCTION(grub_get_eisa_mmap)
955
call prot_to_real /* enter real mode */
964
DATA32 call real_to_prot
979
* grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to
980
* start), for the Query System Address Map BIOS call.
982
* Sets the first 4-byte int value of "addr" to the size returned by
983
* the call. If the call fails, sets it to zero.
985
* Returns: new (non-zero) continuation value, 0 if done.
988
FUNCTION(grub_get_mmap_entry)
997
/* place address (+4) in ES:DI */
1004
/* set continuation value */
1007
/* set default maximum buffer size */
1010
/* set EDX to 'SMAP' */
1011
movl $0x534d4150, %edx
1013
call prot_to_real /* enter real mode */
1022
cmpl $0x534d4150, %eax
1036
/* Apple's cc jumps few bytes before the correct
1037
label in this context. Hence nops. */
1048
DATA32 call real_to_prot
1051
/* write length of buffer (zero if error) into ADDR */
1055
/* set return value to continuation */
1066
* void grub_console_putchar (const struct grub_unicode_glyph *c)
1068
* Put the character C on the console. Because GRUB wants to write a
1069
* character with an attribute, this implementation is a bit tricky.
1070
* If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh
1071
* (TELETYPE OUTPUT). Otherwise, save the original position, put a space,
1072
* save the current position, restore the original position, write the
1073
* character and the attribute, and restore the current position.
1075
* The reason why this is so complicated is that there is no easy way to
1076
* get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't
1077
* support setting a background attribute.
1079
FUNCTION(grub_console_putchar)
1080
/* Retrieve the base character. */
1083
movb EXT_C(grub_console_cur_color), %bl
1090
/* use teletype output if control character */
1100
/* save the character and the attribute on the stack */
1104
/* get the current position */
1108
/* check the column with the width */
1112
/* print CR and LF, if next write will exceed the width */
1118
/* get the current position */
1123
/* restore the character and the attribute */
1127
/* write the character with the attribute */
1132
/* move the cursor forward */
1143
3: DATA32 call real_to_prot
1151
* int grub_console_getkey (void)
1152
* BIOS call "INT 16H Function 00H" to read character from keyboard
1153
* Call with %ah = 0x0
1154
* Return: %ah = keyboard scan code
1155
* %al = ASCII character
1158
/* this table is used in translate_keycode below */
1159
LOCAL (translation_table):
1160
.word GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT
1161
.word GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT
1162
.word GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP
1163
.word GRUB_CONSOLE_KEY_DOWN, GRUB_TERM_DOWN
1164
.word GRUB_CONSOLE_KEY_HOME, GRUB_TERM_HOME
1165
.word GRUB_CONSOLE_KEY_END, GRUB_TERM_END
1166
.word GRUB_CONSOLE_KEY_DC, GRUB_TERM_DC
1167
.word GRUB_CONSOLE_KEY_BACKSPACE, GRUB_TERM_BACKSPACE
1168
.word GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE
1169
.word GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE
1173
* translate_keycode translates the key code %dx to an ascii code.
1182
movw $(ABS(LOCAL (translation_table)) - 0x10000), %si
1184
movw $ABS(LOCAL (translation_table)), %si
1188
/* check if this is the end */
1191
/* load the ascii code into %ax */
1194
/* check if this matches the key code */
1197
/* translate %dx, if successful */
1206
FUNCTION(grub_console_getkey)
1213
* Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would
1214
* cause the machine to hang at the second keystroke. However, we can
1215
* work around this problem by ensuring the presence of keystroke with
1216
* INT 16/AH = 1 before calling INT 16/AH = 0.
1231
movw %ax, %dx /* real_to_prot uses %eax */
1232
call translate_keycode
1234
DATA32 call real_to_prot
1244
* int grub_console_checkkey (void)
1245
* if there is a character pending, return it; otherwise return -1
1246
* BIOS call "INT 16H Function 01H" to check whether a character is pending
1247
* Call with %ah = 0x1
1249
* If key waiting to be input:
1250
* %ah = keyboard scan code
1251
* %al = ASCII character
1256
FUNCTION(grub_console_checkkey)
1260
call prot_to_real /* enter real mode */
1275
DATA32 call real_to_prot
1285
* grub_uint16_t grub_console_getxy (void)
1286
* BIOS call "INT 10H Function 03h" to get cursor position
1287
* Call with %ah = 0x03
1289
* Returns %ch = starting scan line
1290
* %cl = ending scan line
1291
* %dh = row (0 is top)
1292
* %dl = column (0 is left)
1296
FUNCTION(grub_console_getxy)
1298
pushl %ebx /* save EBX */
1303
xorb %bh, %bh /* set page to 0 */
1305
int $0x10 /* get cursor position */
1307
DATA32 call real_to_prot
1319
* void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y)
1320
* BIOS call "INT 10H Function 02h" to set cursor position
1321
* Call with %ah = 0x02
1323
* %dh = row (0 is top)
1324
* %dl = column (0 is left)
1328
FUNCTION(grub_console_gotoxy)
1330
pushl %ebx /* save EBX */
1332
movb %cl, %dh /* %dh = y */
1338
xorb %bh, %bh /* set page to 0 */
1340
int $0x10 /* set cursor position */
1342
DATA32 call real_to_prot
1351
* void grub_console_cls (void)
1352
* BIOS call "INT 10H Function 09h" to write character and attribute
1353
* Call with %ah = 0x09
1355
* %bh = (page number)
1357
* %cx = (number of times)
1360
FUNCTION(grub_console_cls)
1362
pushl %ebx /* save EBX */
1367
/* move the cursor to the beginning */
1373
/* write spaces to the entire screen */
1376
movw $(80 * 25), %cx
1379
/* move back the cursor */
1383
DATA32 call real_to_prot
1392
* void grub_console_setcursor (int on)
1393
* BIOS call "INT 10H Function 01h" to set cursor type
1394
* Call with %ah = 0x01
1395
* %ch = cursor starting scanline
1396
* %cl = cursor ending scanline
1399
console_cursor_state:
1401
console_cursor_shape:
1404
FUNCTION(grub_console_setcursor)
1411
/* check if the standard cursor shape has already been saved */
1412
movw console_cursor_shape, %ax
1423
DATA32 call real_to_prot
1426
movw %cx, console_cursor_shape
1428
/* set %cx to the designated cursor shape */
1433
movw console_cursor_shape, %cx
1441
DATA32 call real_to_prot
1450
* return the real time in ticks, of which there are about
1453
FUNCTION(grub_get_rtc)
1456
call prot_to_real /* enter real mode */
1459
/* %ax is already zero */
1462
DATA32 call real_to_prot
1474
* unsigned char grub_vga_set_mode (unsigned char mode)
1476
FUNCTION(grub_vga_set_mode)
1483
/* get current mode */
1489
/* set the new mode */
1494
DATA32 call real_to_prot
1503
* grub_vbe_bios_status_t grub_vbe_get_controller_info (struct grub_vbe_info_block *controller_info)
1505
* Register allocations for parameters:
1506
* %eax *controller_info
1508
FUNCTION(grub_vbe_bios_get_controller_info)
1513
movw %ax, %di /* Store *controller_info to %edx:%di. */
1516
mov %eax, %edx /* prot_to_real destroys %eax. */
1523
movw %dx, %es /* *controller_info is now on %es:%di. */
1527
movw %ax, %dx /* real_to_prot destroys %eax. */
1531
DATA32 call real_to_prot
1535
andl $0x0FFFF, %eax /* Return value in %eax. */
1543
* grub_vbe_status_t grub_vbe_bios_get_mode_info (grub_uint32_t mode,
1544
* struct grub_vbe_mode_info_block *mode_info)
1546
* Register allocations for parameters:
1550
FUNCTION(grub_vbe_bios_get_mode_info)
1554
movl %eax, %ecx /* Store mode number to %ecx. */
1556
movw %dx, %di /* Store *mode_info to %edx:%di. */
1565
movw %dx, %es /* *mode_info is now on %es:%di. */
1569
movw %ax, %dx /* real_to_prot destroys %eax. */
1573
DATA32 call real_to_prot
1577
andl $0x0FFFF, %eax /* Return value in %eax. */
1584
* grub_vbe_status_t grub_vbe_bios_set_mode (grub_uint32_t mode,
1585
* struct grub_vbe_crtc_info_block *crtc_info)
1587
* Register allocations for parameters:
1591
FUNCTION(grub_vbe_bios_set_mode)
1596
movl %eax, %ebx /* Store mode in %ebx. */
1598
movw %dx, %di /* Store *crtc_info to %edx:%di. */
1607
movw %dx, %es /* *crtc_info is now on %es:%di. */
1612
movw %ax, %dx /* real_to_prot destroys %eax. */
1616
DATA32 call real_to_prot
1620
andl $0xFFFF, %eax /* Return value in %eax. */
1628
* grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode)
1630
* Register allocations for parameters:
1633
FUNCTION(grub_vbe_bios_get_mode)
1638
pushl %eax /* Push *mode to stack. */
1646
movw %ax, %dx /* real_to_prot destroys %eax. */
1648
DATA32 call real_to_prot
1651
popl %edi /* Pops *mode from stack to %edi. */
1656
andl $0xFFFF, %eax /* Return value in %eax. */
1665
* grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *dac_mask_size)
1667
* Register allocations for parameters:
1669
* %edx *dac_mask_size
1671
FUNCTION(grub_vbe_bios_getset_dac_palette_width)
1677
/* If we only want to fetch the value, set %bl to 1. */
1683
/* Put desired width in %bh. */
1693
movw %ax, %cx /* real_to_prot destroys %eax. */
1695
DATA32 call real_to_prot
1698
/* Move result back to *dac_mask_size. */
1703
/* Return value in %eax. */
1711
* grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window,
1712
* grub_uint32_t position);
1714
* Register allocations for parameters:
1718
FUNCTION(grub_vbe_bios_set_memory_window)
1728
andw $0x00ff, %bx /* BL = window, BH = 0, Set memory window. */
1731
movw %ax, %dx /* real_to_prot destroys %eax. */
1733
DATA32 call real_to_prot
1737
andl $0xFFFF, %eax /* Return value in %eax. */
1744
* grub_vbe_status_t grub_vbe_bios_get_memory_window (grub_uint32_t window,
1745
* grub_uint32_t *position);
1747
* Register allocations for parameters:
1751
FUNCTION(grub_vbe_bios_get_memory_window)
1755
pushl %edx /* Push *position to stack. */
1757
movl %eax, %ebx /* Store window in %ebx. */
1763
andw $0x00ff, %bx /* BL = window. */
1764
orw $0x0100, %bx /* BH = 1, Get memory window. */
1767
movw %ax, %bx /* real_to_prot destroys %eax. */
1769
DATA32 call real_to_prot
1772
popl %edi /* pops *position from stack to %edi. */
1774
movl %edx, (%edi) /* Return position to caller. */
1777
andl $0xFFFF, %eax /* Return value in %eax. */
1785
* grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length)
1787
* Register allocations for parameters:
1790
FUNCTION(grub_vbe_bios_set_scanline_length)
1795
movl %eax, %ecx /* Store length in %ecx. */
1801
movw $0x0002, %bx /* BL = 2, Set Scan Line in Bytes. */
1804
movw %ax, %dx /* real_to_prot destroys %eax. */
1806
DATA32 call real_to_prot
1810
andl $0xFFFF, %eax /* Return value in %eax. */
1818
* grub_vbe_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length)
1820
* Register allocations for parameters:
1823
FUNCTION(grub_vbe_bios_get_scanline_length)
1827
pushl %edx /* Push *length to stack. */
1833
movw $0x0001, %bx /* BL = 1, Get Scan Line Length (in bytes). */
1836
movw %ax, %dx /* real_to_prot destroys %eax. */
1838
DATA32 call real_to_prot
1841
popl %edi /* Pops *length from stack to %edi. */
1843
movl %ebx, (%edi) /* Return length to caller. */
1846
andl $0xFFFF, %eax /* Return value in %eax. */
1854
* grub_vbe_status_t grub_vbe_bios_set_display_start (grub_uint32_t x,
1857
* Register allocations for parameters:
1861
FUNCTION(grub_vbe_bios_set_display_start)
1865
movl %eax, %ecx /* Store x in %ecx. */
1871
movw $0x0080, %bx /* BL = 80h, Set Display Start
1872
during Vertical Retrace. */
1875
movw %ax, %dx /* real_to_prot destroys %eax. */
1877
DATA32 call real_to_prot
1881
andl $0xFFFF, %eax /* Return value in %eax. */
1888
* grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x,
1891
* Register allocations for parameters:
1895
FUNCTION(grub_vbe_bios_get_display_start)
1899
pushl %eax /* Push *x to stack. */
1900
pushl %edx /* Push *y to stack. */
1906
movw $0x0001, %bx /* BL = 1, Get Display Start. */
1909
movw %ax, %bx /* real_to_prot destroys %eax. */
1911
DATA32 call real_to_prot
1914
popl %edi /* Pops *y from stack to %edi. */
1916
movl %edx, (%edi) /* Return y-position to caller. */
1918
popl %edi /* Pops *x from stack to %edi. */
1920
movl %ecx, (%edi) /* Return x-position to caller. */
1923
andl $0xFFFF, %eax /* Return value in %eax. */
1931
* grub_vbe_status_t grub_vbe_bios_set_palette_data (grub_uint32_t color_count,
1932
* grub_uint32_t start_index,
1933
* struct grub_vbe_palette_data *palette_data)
1935
* Register allocations for parameters:
1938
* %ecx *palette_data
1940
FUNCTION(grub_vbe_bios_set_palette_data)
1945
movl %eax, %ebx /* Store color_count in %ebx. */
1947
movw %cx, %di /* Store *palette_data to %ecx:%di. */
1956
movw %cx, %es /* *palette_data is now on %es:%di. */
1957
movw %bx, %cx /* color_count is now on %cx. */
1960
xorw %bx, %bx /* BL = 0, Set Palette Data. */
1963
movw %ax, %dx /* real_to_prot destroys %eax. */
1967
DATA32 call real_to_prot
1971
andl $0xFFFF, %eax /* Return value in %eax. */
1983
* struct grub_pxenv *grub_pxe_scan (void);
1985
FUNCTION(grub_pxe_scan)
2001
cmpl $0x4E455850, %es:(%bx) /* PXEN(V+) */
2003
cmpw $0x201, %es:6(%bx) /* API version */
2005
lesw %es:0x28(%bx), %bx /* !PXE structure */
2006
cmpl $0x45585021, %es:(%bx) /* !PXE */
2017
DATA32 call real_to_prot
2021
leal (%eax, %ecx, 4), %ecx
2022
leal (%ebx, %ecx, 4), %eax /* eax = ecx * 16 + ebx */
2027
movl 0x10(%eax), %ecx
2028
movl %ecx, pxe_rm_entry
2037
* int grub_pxe_call (int func, void* data);
2039
FUNCTION(grub_pxe_call)
2052
movl pxe_rm_entry, %ebx
2066
DATA32 call real_to_prot