2007-12-06  Bean  <bean123ch@gmail.com>

	* conf/i386-pc.rmk (pkgdata_IMAGES): Add lnxboot.img.
	(lnxboot_img_SOURCES): New variable.
	(lnxboot_img_ASFLAGS): Likewise.
	(lnxboot_img_LDFLAGS): Likewise.

	* boot/i386/pc/lnxboot.S: New file.


Index: conf/i386-pc.rmk
===================================================================
RCS file: /sources/grub/grub2/conf/i386-pc.rmk,v
retrieving revision 1.94
diff -u -p -r1.94 i386-pc.rmk
--- conf/i386-pc.rmk	18 Nov 2007 06:41:45 -0000	1.94
+++ conf/i386-pc.rmk	6 Dec 2007 15:56:02 -0000
@@ -5,7 +5,7 @@ COMMON_CFLAGS = -fno-builtin -mrtd -mreg
 COMMON_LDFLAGS = -m32 -nostdlib
 
 # Images.
-pkgdata_IMAGES = boot.img diskboot.img kernel.img pxeboot.img
+pkgdata_IMAGES = boot.img diskboot.img kernel.img pxeboot.img lnxboot.img
 
 # For boot.img.
 boot_img_SOURCES = boot/i386/pc/boot.S
@@ -22,6 +22,11 @@ diskboot_img_SOURCES = boot/i386/pc/disk
 diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
 diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,8000
 
+# For lnxboot.img.
+lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S
+lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,6000
+
 # For kernel.img.
 kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \
 	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
Index: boot/i386/pc/lnxboot.S
===================================================================
RCS file: /sources/grub/grub2/boot/i386/pc/lnxboot.S,v
diff -Nu boot/i386/pc/lnxboot.S
--- /dev/null	2007-12-07 07:38:42.252044265 +0800
+++ boot/i386/pc/lnxboot.S	2007-12-06 23:49:09.359375000 +0800
@@ -0,0 +1,292 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  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/>.
+ */
+
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+
+        .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:
+	pushw	%cs
+	popw	%ds
+	xorl	%eax, %eax
+	xorl	%ebx, %ebx
+	call	data_next
+
+data_next:
+	popw	%bx
+	movw	%cs, %ax
+	shll	$4, %eax
+	leal	0x200 + data_start - data_next(%ebx,%eax), %eax
+	movzbl	setup_sects - data_next(%bx), %ecx
+	shll	$9, %ecx
+	addl	%ecx, %eax
+	movl	%eax, code32_start - data_next(%bx)
+
+	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:
+
+	jmp linux_code
+
+	.ascii	"HdrS"			// Header signature
+	.word	0x0203			// Header version number
+
+realmode_swtch:
+	.word	0, 0			// default_switch, SETUPSEG
+start_sys_seg:
+	.word	0x1000			// obsolete
+version_ptr:
+	.word	0			// version string ptr
+type_of_loader:
+	.byte	0			// Filled in by boot loader
+loadflags:
+	.byte	1			// Please load high
+setup_move_size:
+	.word	0			// Unused
+code32_start:
+	.long	0x100000		// 32-bit start address
+ramdisk_image:
+	.long	0			// Loaded ramdisk image address
+ramdisk_size:
+	.long	0			// Size of loaded ramdisk
+bootsect_kludge:
+	.word	0, 0
+heap_end_ptr:
+	.word	0
+pad1:
+	.word	0
+cmd_line_ptr:
+	.long	0			// Command line
+ramdisk_max:
+	.long	0xffffffff		// Highest allowed ramdisk address
+
+gdt:
+	.long	0, 0, 0, 0		// Must be zero
+	.word	0xffff			// 64 K segment size
+gdt_src1:
+	.byte	0, 0 ,0			// Low 24 bits of source addy
+	.byte	0x93			// Access rights
+	.byte	0			// Extended access rights
+gdt_src2:
+	.byte	0			// High 8 bits of source addy
+	.word	0xffff			// 64 K segment size
+gdt_dst1:
+	.byte	0, 0, 0			// Low 24 bits of target addy
+	.byte	0x93			// Access rights
+	.byte	0			// Extended access rights
+gdt_dst2:
+	.byte	0			// High 8 bits of source addy
+	.long	0, 0, 0, 0		// More space for the BIOS
+
+reg_edx:
+	.byte	0x80,0,0xFF,0xFF
+
+data_leng:
+	.long	0
+
+linux_code:
+
+	movw	%cs:(reg_edx - start), %dx
+
+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)
+	lret				// jump to real_code
+
+real_code:
+	subw	$0x20, %ax
+	movw	%ax, %ds
+	movw	(setup_sects - data_start), %cx
+	shlw	$7, %cx
+
+	// Setup stack
+
+	xorw	%si, %si
+	movw	%si, %ss
+	movw	$(CODE_ADDR), %sp
+
+	pushl	%esi
+	pushl	%edi
+
+	// Move itself to 0:CODE_ADDR
+
+	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:
+
+	pushw	%es
+	popw	%ds
+
+	movl	(ramdisk_image - start), %esi
+	or	%esi, %esi
+	jnz	1f
+	movl	(code32_start - start), %esi
+1:
+
+	movl	$0x200, %ecx
+	addl	%ecx, %esi
+	movl	$DATA_ADDR, %edi
+
+	call	move_memory
+
+	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)
+
+	movl	%ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
+	addl	$(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
+
+	call	move_memory
+
+	popl	%edi
+	popl	%esi
+
+	ljmp	$(DATA_ADDR >> 4), $0
+
+// Parameters:
+//   esi: source address
+//   edi: target address
+//   ecx: number of bytes
+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:
+
+	leal	(%esi, %eax), %esi
+	leal	(%edi, %eax), %edi
+	subl	%eax, %ecx
+	jnz	1b
+
+
+	popw	%dx
+	ret
+
+// Parameters:
+//   si: message
+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:
