mirror of
https://github.com/grub4dos/ntloader.git
synced 2025-05-08 19:51:14 +08:00
217 lines
4.4 KiB
ArmAsm
217 lines
4.4 KiB
ArmAsm
/*
|
|
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
|
|
*
|
|
* 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, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* bzImage prefix
|
|
*
|
|
*/
|
|
|
|
#include "ntloader.h"
|
|
|
|
/* Refer to i386 symbols as needed */
|
|
#if __x86_64__
|
|
#define i386(symbol) __i386_ ## symbol
|
|
#else
|
|
#define i386(symbol) symbol
|
|
#endif
|
|
|
|
/** Standard number of setup sectors */
|
|
#define SETUP_SECTS 4
|
|
|
|
/** Sector size */
|
|
#define SECTOR_SIZE 512
|
|
|
|
/** Setup code length */
|
|
#define SETUP_LEN ( ( SETUP_SECTS + 1 ) * SECTOR_SIZE )
|
|
|
|
/** Protected-mode code will be loaded high */
|
|
#define LOADED_HIGH 0x01
|
|
|
|
/** Protected-mode code will be loaded to this linear address */
|
|
#define LOADED_HIGH_ADDRESS 0x100000
|
|
|
|
/** Protected-mode bit in CR0 */
|
|
#define CR0_PE 0x01
|
|
|
|
/** 32-bit protected mode code segment based at real-mode %cs:0000 */
|
|
#define PREFIX_CS 0x08
|
|
|
|
/** 32 bit protected mode flat code segment */
|
|
#define PREFIX_FLAT_CS 0x10
|
|
|
|
/** 32 bit protected mode flat data segment */
|
|
#define PREFIX_FLAT_DS 0x18
|
|
|
|
.section ".note.GNU-stack", "", @progbits
|
|
.text
|
|
.section ".prefix", "ax", @progbits
|
|
.org 0
|
|
_prefix:
|
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
|
|
.code32
|
|
.arch i386
|
|
|
|
.org 0x1f1
|
|
setup_sects:
|
|
.byte SETUP_SECTS
|
|
|
|
.org 0x1fe
|
|
boot_flag:
|
|
.word 0xaa55
|
|
|
|
.org 0x200
|
|
jump:
|
|
.byte 0xeb, setup - 1f
|
|
1:
|
|
|
|
.org 0x202
|
|
header:
|
|
.ascii "HdrS"
|
|
|
|
.org 0x206
|
|
version:
|
|
.word 0x206 /* Version 2.06 */
|
|
|
|
.org 0x20e
|
|
kernel_version:
|
|
.word ( version_string - _prefix - 0x200 )
|
|
|
|
.org 0x211
|
|
loadflags:
|
|
.byte LOADED_HIGH
|
|
|
|
.org 0x218
|
|
ramdisk_image:
|
|
.long 0 /* Filled in by boot loader */
|
|
|
|
.org 0x21c
|
|
ramdisk_size:
|
|
.long 0 /* Filled in by boot loader */
|
|
|
|
.org 0x228
|
|
cmd_line_ptr:
|
|
.long 0 /* Filled in by boot loader */
|
|
|
|
.org 0x22c
|
|
ramdisk_max:
|
|
.long 0xffffffff
|
|
|
|
.org 0x238
|
|
cmdline_size:
|
|
.long 4096
|
|
|
|
version_string:
|
|
.asciz VERSION
|
|
|
|
/* Setup code */
|
|
.code16
|
|
setup:
|
|
/* Reset %cs so that labels work */
|
|
pushw %ds
|
|
pushw $( 1f - _prefix )
|
|
lret
|
|
1:
|
|
/* Fix up GDT */
|
|
xorl %eax, %eax
|
|
movw %cs, %ax
|
|
shll $4, %eax
|
|
addl %eax, ( gdt - _prefix + 2 )
|
|
addl %eax, ( gdt - _prefix + PREFIX_CS + 2 )
|
|
|
|
/* Switch to protected mode and jump to startup code */
|
|
cli
|
|
data32 lgdt ( gdt - _prefix )
|
|
movl %cr0, %eax
|
|
orb $CR0_PE, %al
|
|
movl %eax, %cr0
|
|
data32 ljmp $PREFIX_CS, $( 1f - _prefix )
|
|
.code32
|
|
1:
|
|
/* Load data segment registers */
|
|
movw $PREFIX_FLAT_DS, %ax
|
|
movw %ax, %ds
|
|
movw %ax, %es
|
|
movw %ax, %fs
|
|
movw %ax, %gs
|
|
movw %ax, %ss
|
|
|
|
/* Zero real-mode and protected-mode .bss sections */
|
|
xorl %eax, %eax
|
|
movl $_bss16, %edi
|
|
movl $_bss16_len, %ecx
|
|
rep stosb
|
|
movl $_bss, %edi
|
|
movl $_bss_len, %ecx
|
|
rep stosb
|
|
|
|
/* Copy payload to runtime address */
|
|
movl $( LOADED_HIGH_ADDRESS + _payload_pos - SETUP_LEN ), %esi
|
|
movl $_payload, %edi
|
|
movl $_payload_len, %ecx
|
|
cld
|
|
rep movsb
|
|
|
|
/* Copy bcd */
|
|
movl $(LOADED_HIGH_ADDRESS + _payload_pos - SETUP_LEN), %eax
|
|
addl $_payload_len, %eax
|
|
movl %eax, %esi
|
|
movl $_bcd, %edi
|
|
movl $_bcd_len, %ecx
|
|
cld
|
|
rep movsb
|
|
|
|
/* Copy parameters required by runtime */
|
|
movl %cs:( cmd_line_ptr - _prefix ), %eax
|
|
movl %eax, i386(cmdline)
|
|
movl %cs:( ramdisk_image - _prefix ), %eax
|
|
movl %eax, i386(initrd)
|
|
movl %cs:( ramdisk_size - _prefix ), %eax
|
|
movl %eax, i386(initrd_len)
|
|
|
|
/* Jump to payload */
|
|
ljmp $PREFIX_FLAT_CS, $i386(startup)
|
|
.size setup, . - setup
|
|
|
|
/* Global descriptor table */
|
|
gdt:
|
|
.word gdt_limit
|
|
.long ( gdt - _prefix )
|
|
/* 32-bit protected mode code segment based at real-mode %cs:0000 */
|
|
.org ( gdt + PREFIX_CS )
|
|
.word 0xffff, 0
|
|
.byte 0, 0x9f, 0xcf, 0
|
|
/* 32 bit protected mode flat code segment */
|
|
.org ( gdt + PREFIX_FLAT_CS )
|
|
.word 0xffff, 0
|
|
.byte 0, 0x9f, 0xcf, 0
|
|
/* 32 bit protected mode flat data segment */
|
|
.org ( gdt + PREFIX_FLAT_DS )
|
|
.word 0xffff, 0
|
|
.byte 0, 0x93, 0xcf, 0
|
|
.size gdt, . - gdt
|
|
.equ gdt_limit, . - gdt - 1
|
|
|
|
#endif
|
|
|
|
.org SETUP_LEN
|