endif
if COND_i386_coreboot
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/boot.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/console.h
-KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/init.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
- KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
endif
if COND_i386_multiboot
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/boot.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/console.h
-KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/init.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
- KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
endif
if COND_i386_qemu
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
- KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/msdos_partition.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/boot.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/console.h
-KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/init.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
- KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
endif
if COND_i386_ieee1275
ljmp $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR
.code32
- #include "../loader.S"
-
/*
- * int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
+ * void grub_console_putchar (int c)
*
- * Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP
- * is passed for disk address packet. If an error occurs, return
- * non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_rw_int13_extensions)
- pushl %ebp
- pushl %esi
-
- /* compute the address of disk_address_packet */
- movw %cx, %si
- xorw %cx, %cx
- shrl $4, %ecx /* save the segment to cx */
-
- /* ah */
- movb %al, %dh
- /* enter real mode */
- call prot_to_real
-
- .code16
- movb %dh, %ah
- movw %cx, %ds
- int $0x13 /* do the operation */
- movb %ah, %dl /* save return value */
- /* back to protected mode */
- DATA32 call real_to_prot
- .code32
-
- movb %dl, %al /* return value in %eax */
-
- popl %esi
- popl %ebp
-
- ret
-
-/*
- * int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
- * int soff, int nsec, int segment)
+ * Put the character C on the console. Because GRUB wants to write a
+ * character with an attribute, this implementation is a bit tricky.
+ * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh
+ * (TELETYPE OUTPUT). Otherwise, save the original position, put a space,
+ * save the current position, restore the original position, write the
+ * character and the attribute, and restore the current position.
*
- * Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
- * NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
- * return non-zero, otherwise zero.
+ * The reason why this is so complicated is that there is no easy way to
+ * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't
+ * support setting a background attribute.
*/
+FUNCTION(grub_console_putchar)
+ /* Retrieve the base character. */
+ movl 0(%edx), %edx
+ pusha
+ movb EXT_C(grub_console_cur_color), %bl
-FUNCTION(grub_biosdisk_rw_standard)
- pushl %ebp
- movl %esp, %ebp
-
- pushl %ebx
- pushl %edi
- pushl %esi
-
- /* set up CHS information */
-
- /* set %ch to low eight bits of cylinder */
- xchgb %cl, %ch
- /* set bits 6-7 of %cl to high two bits of cylinder */
- shlb $6, %cl
- /* set bits 0-5 of %cl to sector */
- addb 0xc(%ebp), %cl
- /* set %dh to head */
- movb 0x8(%ebp), %dh
- /* set %ah to AH */
- movb %al, %ah
- /* set %al to NSEC */
- movb 0x10(%ebp), %al
- /* save %ax in %di */
- movw %ax, %di
- /* save SEGMENT in %bx */
- movw 0x14(%ebp), %bx
-
- /* enter real mode */
call prot_to_real
-
.code16
- movw %bx, %es
- xorw %bx, %bx
- movw $3, %si /* attempt at least three times */
-
-1:
- movw %di, %ax
- int $0x13 /* do the operation */
- jnc 2f /* check if successful */
-
- movb %ah, %bl /* save return value */
- /* if fail, reset the disk system */
- xorw %ax, %ax
- int $0x13
-
- decw %si
- cmpw $0, %si
- je 2f
- xorb %bl, %bl
- jmp 1b /* retry */
-2:
- /* back to protected mode */
- DATA32 call real_to_prot
- .code32
-
- movb %bl, %al /* return value in %eax */
-
- popl %esi
- popl %edi
- popl %ebx
- popl %ebp
-
- ret $(4 * 4)
-
-
-/*
- * int grub_biosdisk_check_int13_extensions (int drive)
- *
- * Check if LBA is supported for DRIVE. If it is supported, then return
- * the major version of extensions, otherwise zero.
- */
+ movb %dl, %al
+ xorb %bh, %bh
-FUNCTION(grub_biosdisk_check_int13_extensions)
- pushl %ebp
- pushl %ebx
+ /* use teletype output if control character */
+ cmpb $0x7, %al
+ je 1f
+ cmpb $0x8, %al
+ je 1f
+ cmpb $0xa, %al
+ je 1f
+ cmpb $0xd, %al
+ je 1f
- /* drive */
- movb %al, %dl
- /* enter real mode */
- call prot_to_real
+ /* save the character and the attribute on the stack */
+ pushw %ax
+ pushw %bx
- .code16
- movb $0x41, %ah
- movw $0x55aa, %bx
- int $0x13 /* do the operation */
+ /* get the current position */
+ movb $0x3, %ah
+ int $0x10
- /* check the result */
- jc 1f
- cmpw $0xaa55, %bx
- jne 1f
+ /* check the column with the width */
+ cmpb $79, %dl
+ jl 2f
- movb %ah, %bl /* save the major version into %bl */
+ /* print CR and LF, if next write will exceed the width */
+ movw $0x0e0d, %ax
+ int $0x10
+ movb $0x0a, %al
+ int $0x10
- /* check if AH=0x42 is supported */
- andw $1, %cx
- jnz 2f
+ /* get the current position */
+ movb $0x3, %ah
+ int $0x10
-1:
- xorb %bl, %bl
2:
- /* back to protected mode */
- DATA32 call real_to_prot
- .code32
-
- movb %bl, %al /* return value in %eax */
-
- popl %ebx
- popl %ebp
-
- ret
-
-
-/*
- * int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
- *
- * Return the cdrom information of DRIVE in CDRP. If an error occurs,
- * then return non-zero, otherwise zero.
- */
+ /* restore the character and the attribute */
+ popw %bx
+ popw %ax
-FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions)
- movw $0x4B01, %cx
- jmp 1f
+ /* write the character with the attribute */
+ movb $0x9, %ah
+ movw $1, %cx
+ int $0x10
-/*
- * int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
- *
- * Return the geometry of DRIVE in a drive parameters, DRP. If an error
- * occurs, then return non-zero, otherwise zero.
- */
+ /* move the cursor forward */
+ incb %dl
+ movb $0x2, %ah
+ int $0x10
-FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
- movb $0x48, %ch
-1:
- pushl %ebp
- pushl %ebx
- pushl %esi
+ jmp 3f
- /* compute the address of drive parameters */
- movw %dx, %si
- andl $0xf, %esi
- shrl $4, %edx
- movw %dx, %bx /* save the segment into %bx */
- /* drive */
- movb %al, %dl
- /* enter real mode */
- call prot_to_real
+1: movw $1, %bx
+ movb $0xe, %ah
+ int $0x10
- .code16
- movw %cx, %ax
- movw %bx, %ds
- int $0x13 /* do the operation */
- jc noclean
- /* Clean return value if carry isn't set to workaround
- some buggy BIOSes. */
- xor %ax, %ax
-noclean:
- movb %ah, %bl /* save return value in %bl */
- /* back to protected mode */
- DATA32 call real_to_prot
+3: DATA32 call real_to_prot
.code32
- movb %bl, %al /* return value in %eax */
-
- popl %esi
- popl %ebx
- popl %ebp
-
+ popa
ret
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/mm.h>
+ #include <grub/cpu/relocator.h>
#include <grub/video.h>
++#include <grub/floppy.h>
#define GRUB_LINUX_CL_OFFSET 0x9000
#define GRUB_LINUX_CL_END_OFFSET 0x90FF
static grub_size_t linux_mem_size;
static int loaded;
+ static struct grub_relocator *relocator = NULL;
+ static grub_addr_t grub_linux_real_target;
+ static char *grub_linux_real_chunk;
+ static grub_size_t grub_linux16_prot_size;
static grub_err_t
- grub_linux_unload (void)
+ grub_linux16_boot (void)
{
- grub_dl_unref (my_mod);
- loaded = 0;
- return GRUB_ERR_NONE;
+ grub_uint16_t segment;
+ struct grub_relocator16_state state;
+
+ segment = grub_linux_real_target >> 4;
+ state.gs = state.fs = state.es = state.ds = state.ss = segment;
+ state.sp = GRUB_LINUX_SETUP_STACK;
+ state.cs = segment + 0x20;
+ state.ip = 0;
+
+ grub_video_set_mode ("text", 0, 0);
++
++ grub_stop_floppy ();
+
+ return grub_relocator16_boot (relocator, state);
}
static grub_err_t