2007-12-15 10:42:17 +00:00
|
|
|
/* -*-Asm-*- */
|
|
|
|
/*
|
|
|
|
* GRUB -- GRand Unified Bootloader
|
2008-01-29 10:59:56 +00:00
|
|
|
* Copyright (C) 2007,2008 Free Software Foundation, Inc.
|
2007-12-15 10:42:17 +00:00
|
|
|
*
|
|
|
|
* GRUB is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* GRUB is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2008-07-13 01:55:15 +00:00
|
|
|
#include <config.h>
|
2007-12-15 10:42:17 +00:00
|
|
|
#include <grub/boot.h>
|
|
|
|
#include <grub/machine/boot.h>
|
|
|
|
#include <grub/machine/kernel.h>
|
2008-01-29 10:59:56 +00:00
|
|
|
#include <multiboot.h>
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
.file "lnxboot.S"
|
|
|
|
|
|
|
|
#define CODE_ADDR 0x6000
|
|
|
|
#define CODE_LENG (code_end - start)
|
|
|
|
#define DATA_ADDR ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
|
|
|
|
|
|
|
|
#define BLCK_LENG 0x4000
|
|
|
|
|
|
|
|
.text
|
|
|
|
|
|
|
|
.code16
|
|
|
|
|
|
|
|
.globl start, _start
|
|
|
|
|
|
|
|
data_start:
|
2008-01-29 10:59:56 +00:00
|
|
|
xorl %ebp, %ebp
|
2007-12-15 10:42:17 +00:00
|
|
|
jmp linux_next
|
|
|
|
|
|
|
|
. = data_start + 0x1F1
|
|
|
|
|
|
|
|
setup_sects:
|
|
|
|
.byte (CODE_LENG >> 9)
|
|
|
|
root_flags:
|
|
|
|
.word 0
|
|
|
|
syssize:
|
|
|
|
.word 0
|
|
|
|
swap_dev:
|
|
|
|
.word 0
|
|
|
|
ram_size:
|
|
|
|
.word 0
|
|
|
|
vid_mode:
|
|
|
|
.word 0
|
|
|
|
root_dev:
|
|
|
|
.word 0
|
|
|
|
boot_flag:
|
|
|
|
.word 0xAA55
|
|
|
|
|
|
|
|
start:
|
|
|
|
_start:
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
jmp linux_init
|
2007-12-15 10:42:17 +00:00
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
.ascii "HdrS" /* Header signature. */
|
|
|
|
.word 0x0203 /* Header version number. */
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
realmode_swtch:
|
2008-01-29 10:59:56 +00:00
|
|
|
.word 0, 0 /* default_switch, SETUPSEG. */
|
2007-12-15 10:42:17 +00:00
|
|
|
start_sys_seg:
|
2008-01-29 10:59:56 +00:00
|
|
|
.word 0x1000 /* Obsolete. */
|
2007-12-15 10:42:17 +00:00
|
|
|
version_ptr:
|
2008-01-29 10:59:56 +00:00
|
|
|
.word 0 /* Version string ptr. */
|
2007-12-15 10:42:17 +00:00
|
|
|
type_of_loader:
|
2008-01-29 10:59:56 +00:00
|
|
|
.byte 0 /* Filled in by boot loader. */
|
2007-12-15 10:42:17 +00:00
|
|
|
loadflags:
|
2008-01-29 10:59:56 +00:00
|
|
|
.byte 1 /* Please load high. */
|
2007-12-15 10:42:17 +00:00
|
|
|
setup_move_size:
|
2008-01-29 10:59:56 +00:00
|
|
|
.word 0 /* Unused. */
|
2007-12-15 10:42:17 +00:00
|
|
|
code32_start:
|
2008-01-29 10:59:56 +00:00
|
|
|
.long 0x100000 /* 32-bit start address. */
|
2007-12-15 10:42:17 +00:00
|
|
|
ramdisk_image:
|
2008-01-29 10:59:56 +00:00
|
|
|
.long 0 /* Loaded ramdisk image address. */
|
2007-12-15 10:42:17 +00:00
|
|
|
ramdisk_size:
|
2008-01-29 10:59:56 +00:00
|
|
|
.long 0 /* Size of loaded ramdisk. */
|
2007-12-15 10:42:17 +00:00
|
|
|
bootsect_kludge:
|
|
|
|
.word 0, 0
|
|
|
|
heap_end_ptr:
|
|
|
|
.word 0
|
|
|
|
pad1:
|
|
|
|
.word 0
|
|
|
|
cmd_line_ptr:
|
2008-01-29 10:59:56 +00:00
|
|
|
.long 0 /* Command line. */
|
2007-12-15 10:42:17 +00:00
|
|
|
ramdisk_max:
|
2008-01-29 10:59:56 +00:00
|
|
|
.long 0xffffffff /* Highest allowed ramdisk address. */
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
gdt:
|
2008-01-29 10:59:56 +00:00
|
|
|
.long 0, 0, 0, 0 /* Must be zero. */
|
|
|
|
.word 0xffff /* 64 K segment size. */
|
2007-12-15 10:42:17 +00:00
|
|
|
gdt_src1:
|
2008-01-29 10:59:56 +00:00
|
|
|
.byte 0, 0 ,0 /* Low 24 bits of source address. */
|
|
|
|
.byte 0x93 /* Access rights. */
|
|
|
|
.byte 0 /* Extended access rights. */
|
2007-12-15 10:42:17 +00:00
|
|
|
gdt_src2:
|
2008-01-29 10:59:56 +00:00
|
|
|
.byte 0 /* High 8 bits of source address. */
|
|
|
|
.word 0xffff /* 64 K segment size. */
|
2007-12-15 10:42:17 +00:00
|
|
|
gdt_dst1:
|
2008-01-29 10:59:56 +00:00
|
|
|
.byte 0, 0, 0 /* Low 24 bits of target address. */
|
|
|
|
.byte 0x93 /* Access rights. */
|
|
|
|
.byte 0 /* Extended access rights. */
|
2007-12-15 10:42:17 +00:00
|
|
|
gdt_dst2:
|
2008-01-29 10:59:56 +00:00
|
|
|
.byte 0 /* High 8 bits of source address. */
|
|
|
|
.long 0, 0, 0, 0 /* More space for the BIOS. */
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
reg_edx:
|
2008-03-05 05:09:35 +00:00
|
|
|
.byte 0x80, 0, 0xFF, 0xFF
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
data_leng:
|
|
|
|
.long 0
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
linux_init:
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
movw %cs:(reg_edx - start), %dx
|
2008-01-29 10:59:56 +00:00
|
|
|
movl %cs:(code32_start - start), %ebp
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
linux_next:
|
|
|
|
|
|
|
|
call normalize
|
|
|
|
|
|
|
|
normalize:
|
|
|
|
popw %bx
|
|
|
|
subw $(normalize - start), %bx
|
|
|
|
shrw $4, %bx
|
|
|
|
movw %cs, %ax
|
|
|
|
addw %bx, %ax
|
|
|
|
pushw %ax
|
|
|
|
pushw $(real_code - start)
|
2008-01-29 10:59:56 +00:00
|
|
|
lret /* Jump to real_code. */
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
real_code:
|
|
|
|
subw $0x20, %ax
|
|
|
|
movw %ax, %ds
|
|
|
|
movw (setup_sects - data_start), %cx
|
|
|
|
shlw $7, %cx
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
/* Setup stack. */
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
xorw %si, %si
|
|
|
|
movw %si, %ss
|
|
|
|
movw $(CODE_ADDR), %sp
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
/* Move itself to 0:CODE_ADDR. */
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
cld
|
|
|
|
movw %cs, %ax
|
|
|
|
movw %ax, %ds
|
|
|
|
movw $(CODE_ADDR >> 4), %ax
|
|
|
|
movw %ax, %es
|
|
|
|
movw %si, %di
|
|
|
|
|
|
|
|
rep
|
|
|
|
movsl
|
|
|
|
|
|
|
|
ljmp $(CODE_ADDR >> 4), $(real_code_2 - start)
|
|
|
|
|
|
|
|
real_code_2:
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
xchgl %ebp, %esi
|
|
|
|
orl %esi, %esi
|
2007-12-15 10:42:17 +00:00
|
|
|
jnz 1f
|
2008-01-29 10:59:56 +00:00
|
|
|
movw %ds, %si
|
|
|
|
shll $4, %esi
|
|
|
|
addl %ebp, %esi
|
2007-12-15 10:42:17 +00:00
|
|
|
1:
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
pushw %es
|
|
|
|
popw %ds
|
|
|
|
|
2007-12-15 10:42:17 +00:00
|
|
|
movl $0x200, %ecx
|
|
|
|
addl %ecx, %esi
|
|
|
|
movl $DATA_ADDR, %edi
|
|
|
|
|
|
|
|
call move_memory
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
/* Check for multiboot signature. */
|
|
|
|
cmpl $MULTIBOOT_MAGIC, %ss:(DATA_ADDR + 0x50)
|
|
|
|
jz 1f
|
2007-12-15 10:42:17 +00:00
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
movl (ramdisk_image - start), %esi
|
|
|
|
movl (ramdisk_size - start), %ecx
|
|
|
|
movl $(DATA_ADDR - 0x200), %edi
|
|
|
|
jmp 2f
|
|
|
|
|
|
|
|
1:
|
2007-12-15 10:42:17 +00:00
|
|
|
|
|
|
|
movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
|
|
|
|
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
2:
|
2007-12-15 10:42:17 +00:00
|
|
|
call move_memory
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
movsbl %dh, %eax
|
|
|
|
movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)
|
|
|
|
|
|
|
|
movsbl (reg_edx + 2 - start), %eax
|
|
|
|
movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
|
2007-12-15 10:42:17 +00:00
|
|
|
|
2008-03-05 05:09:35 +00:00
|
|
|
movb $0xFF, %dh
|
|
|
|
|
2007-12-15 10:42:17 +00:00
|
|
|
ljmp $(DATA_ADDR >> 4), $0
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
/*
|
|
|
|
* Parameters:
|
|
|
|
* esi: source address
|
|
|
|
* edi: target address
|
|
|
|
* ecx: number of bytes
|
|
|
|
*/
|
|
|
|
|
2007-12-15 10:42:17 +00:00
|
|
|
move_memory:
|
|
|
|
incl %ecx
|
|
|
|
andb $0xFE, %cl
|
|
|
|
pushw %dx
|
|
|
|
1:
|
|
|
|
pushl %esi
|
|
|
|
pushl %edi
|
|
|
|
pushl %ecx
|
|
|
|
cmpl $BLCK_LENG, %ecx
|
|
|
|
jbe 2f
|
|
|
|
movl $BLCK_LENG, %ecx
|
|
|
|
2:
|
|
|
|
pushl %ecx
|
|
|
|
|
|
|
|
movl %esi, %eax
|
|
|
|
movw %si, (gdt_src1 - start)
|
|
|
|
shrl $16, %eax
|
|
|
|
movb %al, (gdt_src1 + 2 - start)
|
|
|
|
movb %ah, (gdt_src2 - start)
|
|
|
|
|
|
|
|
movl %edi, %eax
|
|
|
|
movw %di, (gdt_dst1 - start)
|
|
|
|
shrl $16, %eax
|
|
|
|
movb %al, (gdt_dst1 + 2 - start)
|
|
|
|
movb %ah, (gdt_dst2 - start)
|
|
|
|
|
|
|
|
movw $(gdt - start), %si
|
|
|
|
movb $0x87, %ah
|
|
|
|
shrw $1, %cx
|
|
|
|
|
|
|
|
int $0x15
|
|
|
|
|
|
|
|
popl %eax
|
|
|
|
popl %ecx
|
|
|
|
popl %edi
|
|
|
|
popl %esi
|
|
|
|
|
|
|
|
jnc 2f
|
|
|
|
movw $(err_int15_msg - start), %si
|
|
|
|
jmp fail
|
|
|
|
|
|
|
|
2:
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
addl %eax, %esi
|
|
|
|
addl %eax, %edi
|
2007-12-15 10:42:17 +00:00
|
|
|
subl %eax, %ecx
|
|
|
|
jnz 1b
|
|
|
|
|
|
|
|
|
|
|
|
popw %dx
|
|
|
|
ret
|
|
|
|
|
2008-01-29 10:59:56 +00:00
|
|
|
/*
|
|
|
|
* Parameters:
|
|
|
|
* si: message
|
|
|
|
*/
|
|
|
|
|
2007-12-15 10:42:17 +00:00
|
|
|
fail:
|
|
|
|
movb $0x0e, %ah
|
|
|
|
xorw %bx, %bx
|
|
|
|
1:
|
|
|
|
lodsb (%si), %al
|
|
|
|
int $0x10
|
|
|
|
cmpb $0, %al
|
|
|
|
jne 1b
|
|
|
|
1: jmp 1b
|
|
|
|
|
|
|
|
err_int15_msg:
|
|
|
|
.ascii "move memory fails\0"
|
|
|
|
|
|
|
|
. = (. & (~0x1FF)) + 0x1FF
|
|
|
|
|
|
|
|
.byte 0
|
|
|
|
|
|
|
|
code_end:
|