 75b9f69057
			
		
	
	
		75b9f69057
		
	
	
	
	
		
			
			Currently linuxboot.bin and multiboot.bin option roms override int19 vector to intercept boot process. No sane option rom should do that. Provide bev entry instead that will be called by BIOS if option rom is selected for booting. Signed-off-by: Gleb Natapov <gleb@redhat.com> Acked-by: Alexander Graf <agraf@suse.de> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
		
			
				
	
	
		
			140 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * Linux Boot Option ROM
 | |
|  *
 | |
|  * This program 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 2 of the License, or
 | |
|  * (at your option) any later version.
 | |
|  *
 | |
|  * This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
 | |
|  *
 | |
|  * Copyright Novell Inc, 2009
 | |
|  *   Authors: Alexander Graf <agraf@suse.de>
 | |
|  *
 | |
|  * Based on code in hw/pc.c.
 | |
|  */
 | |
| 
 | |
| #include "optionrom.h"
 | |
| 
 | |
| #define BOOT_ROM_PRODUCT "Linux loader"
 | |
| 
 | |
| BOOT_ROM_START
 | |
| 
 | |
| run_linuxboot:
 | |
| 
 | |
| 	cli
 | |
| 	cld
 | |
| 
 | |
| 	jmp		copy_kernel
 | |
| boot_kernel:
 | |
| 
 | |
| 	read_fw		FW_CFG_SETUP_ADDR
 | |
| 
 | |
| 	mov		%eax, %ebx
 | |
| 	shr		$4, %ebx
 | |
| 
 | |
| 	/* All segments contain real_addr */
 | |
| 	mov		%bx, %ds
 | |
| 	mov		%bx, %es
 | |
| 	mov		%bx, %fs
 | |
| 	mov		%bx, %gs
 | |
| 	mov		%bx, %ss
 | |
| 
 | |
| 	/* CX = CS we want to jump to */
 | |
| 	add		$0x20, %bx
 | |
| 	mov		%bx, %cx
 | |
| 
 | |
| 	/* SP = cmdline_addr-real_addr-16 */
 | |
| 	read_fw		FW_CFG_CMDLINE_ADDR
 | |
| 	mov		%eax, %ebx
 | |
| 	read_fw		FW_CFG_SETUP_ADDR
 | |
| 	sub		%eax, %ebx
 | |
| 	sub		$16, %ebx
 | |
| 	mov		%ebx, %esp
 | |
| 
 | |
| 	/* Build indirect lret descriptor */
 | |
| 	pushw		%cx		/* CS */
 | |
| 	xor		%ax, %ax
 | |
| 	pushw		%ax		/* IP = 0 */
 | |
| 
 | |
| 	/* Clear registers */
 | |
| 	xor		%eax, %eax
 | |
| 	xor		%ebx, %ebx
 | |
| 	xor		%ecx, %ecx
 | |
| 	xor		%edx, %edx
 | |
| 	xor		%edi, %edi
 | |
| 	xor		%ebp, %ebp
 | |
| 
 | |
| 	/* Jump to Linux */
 | |
| 	lret
 | |
| 
 | |
| 
 | |
| copy_kernel:
 | |
| 
 | |
| 	/* We need to load the kernel into memory we can't access in 16 bit
 | |
| 	   mode, so let's get into 32 bit mode, write the kernel and jump
 | |
| 	   back again. */
 | |
| 
 | |
| 	/* Reserve space on the stack for our GDT descriptor. */
 | |
| 	mov		%esp, %ebp
 | |
| 	sub		$16, %esp
 | |
| 
 | |
| 	/* Now create the GDT descriptor */
 | |
| 	movw		$((3 * 8) - 1), -16(%bp)
 | |
| 	mov		%cs, %eax
 | |
| 	movzwl		%ax, %eax
 | |
| 	shl		$4, %eax
 | |
| 	addl		$gdt, %eax
 | |
| 	movl		%eax, -14(%bp)
 | |
| 
 | |
| 	/* And load the GDT */
 | |
| 	data32 lgdt	-16(%bp)
 | |
| 	mov		%ebp, %esp
 | |
| 
 | |
| 	/* Get us to protected mode now */
 | |
| 	mov		$1, %eax
 | |
| 	mov		%eax, %cr0
 | |
| 
 | |
| 	/* So we can set ES to a 32-bit segment */
 | |
| 	mov		$0x10, %eax
 | |
| 	mov		%eax, %es
 | |
| 
 | |
| 	/* We're now running in 16-bit CS, but 32-bit ES! */
 | |
| 
 | |
| 	/* Load kernel and initrd */
 | |
| 	read_fw_blob_addr32(FW_CFG_KERNEL)
 | |
| 	read_fw_blob_addr32(FW_CFG_INITRD)
 | |
| 	read_fw_blob_addr32(FW_CFG_CMDLINE)
 | |
| 	read_fw_blob_addr32(FW_CFG_SETUP)
 | |
| 
 | |
| 	/* And now jump into Linux! */
 | |
| 	mov		$0, %eax
 | |
| 	mov		%eax, %cr0
 | |
| 
 | |
| 	/* ES = CS */
 | |
| 	mov		%cs, %ax
 | |
| 	mov		%ax, %es
 | |
| 
 | |
| 	jmp		boot_kernel
 | |
| 
 | |
| /* Variables */
 | |
| 
 | |
| .align 4, 0
 | |
| gdt:
 | |
| 	/* 0x00 */
 | |
| .byte	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 | |
| 
 | |
| 	/* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
 | |
| .byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
 | |
| 
 | |
| 	/* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
 | |
| .byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
 | |
| 
 | |
| BOOT_ROM_END
 |