2006-05-01 22:35:19 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2006 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2006-05-01 21:26:44 +00:00
|
|
|
|
2009-05-01 15:41:06 +01:00
|
|
|
FILE_LICENCE ( GPL2_OR_LATER )
|
|
|
|
|
|
2008-03-09 22:13:07 +00:00
|
|
|
.arch i386
|
|
|
|
|
|
2007-01-13 01:48:12 +00:00
|
|
|
/**
|
|
|
|
|
* High memory temporary load address
|
|
|
|
|
*
|
|
|
|
|
* Temporary buffer into which to copy (or decompress) our runtime
|
|
|
|
|
* image, prior to calling get_memmap() and relocate(). We don't
|
|
|
|
|
* actually leave anything here once install() has returned.
|
|
|
|
|
*
|
|
|
|
|
* We use the start of an even megabyte so that we don't have to worry
|
|
|
|
|
* about the current state of the A20 line.
|
|
|
|
|
*
|
2008-03-09 22:13:07 +00:00
|
|
|
* We use 4MB rather than 2MB because some PXE stack / PMM BIOS
|
|
|
|
|
* combinations are known to place data required by other UNDI ROMs
|
|
|
|
|
* loader around the 2MB mark.
|
2007-01-13 01:48:12 +00:00
|
|
|
*/
|
2008-03-09 22:13:07 +00:00
|
|
|
.globl HIGHMEM_LOADPOINT
|
|
|
|
|
.equ HIGHMEM_LOADPOINT, ( 4 << 20 )
|
2007-01-13 01:48:12 +00:00
|
|
|
|
2007-07-16 16:58:38 +01:00
|
|
|
/* Image compression enabled */
|
|
|
|
|
#define COMPRESS 1
|
|
|
|
|
|
2006-05-01 21:26:44 +00:00
|
|
|
#define CR0_PE 1
|
2006-05-01 22:35:19 +00:00
|
|
|
|
2008-03-11 11:32:19 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
|
* Utility function: print character (with LF -> LF,CR translation)
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %al : character to print
|
2008-05-21 18:43:58 +01:00
|
|
|
* %ds:di : output buffer (or %di=0 to print to console)
|
2008-03-11 11:32:19 +00:00
|
|
|
* Returns:
|
2008-05-21 18:43:58 +01:00
|
|
|
* %ds:di : next character in output buffer (if applicable)
|
2008-03-11 11:32:19 +00:00
|
|
|
*****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2008-03-11 11:32:19 +00:00
|
|
|
.code16
|
|
|
|
|
.globl print_character
|
|
|
|
|
print_character:
|
|
|
|
|
/* Preserve registers */
|
2008-05-21 18:43:58 +01:00
|
|
|
pushw %ax
|
2008-03-11 11:32:19 +00:00
|
|
|
pushw %bx
|
|
|
|
|
pushw %bp
|
2008-05-21 18:43:58 +01:00
|
|
|
/* If %di is non-zero, write character to buffer and exit */
|
|
|
|
|
testw %di, %di
|
|
|
|
|
jz 1f
|
|
|
|
|
movb %al, %ds:(%di)
|
|
|
|
|
incw %di
|
|
|
|
|
jmp 3f
|
|
|
|
|
1: /* Print character */
|
2008-03-11 11:32:19 +00:00
|
|
|
movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
|
|
|
|
movb $0x0e, %ah /* write char, tty mode */
|
|
|
|
|
cmpb $0x0a, %al /* '\n'? */
|
2008-05-21 18:43:58 +01:00
|
|
|
jne 2f
|
2008-03-11 11:32:19 +00:00
|
|
|
int $0x10
|
|
|
|
|
movb $0x0d, %al
|
2008-05-21 18:43:58 +01:00
|
|
|
2: int $0x10
|
2008-03-11 11:32:19 +00:00
|
|
|
/* Restore registers and return */
|
2008-05-21 18:43:58 +01:00
|
|
|
3: popw %bp
|
2008-03-11 11:32:19 +00:00
|
|
|
popw %bx
|
2008-05-21 18:43:58 +01:00
|
|
|
popw %ax
|
2008-03-11 11:32:19 +00:00
|
|
|
ret
|
|
|
|
|
.size print_character, . - print_character
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* Utility function: print a NUL-terminated string
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %ds:si : string to print
|
2008-05-21 18:43:58 +01:00
|
|
|
* %ds:di : output buffer (or %di=0 to print to console)
|
2008-03-11 11:32:19 +00:00
|
|
|
* Returns:
|
|
|
|
|
* %ds:si : character after terminating NUL
|
2008-05-21 18:43:58 +01:00
|
|
|
* %ds:di : next character in output buffer (if applicable)
|
2008-03-11 11:32:19 +00:00
|
|
|
*****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2008-03-11 11:32:19 +00:00
|
|
|
.code16
|
|
|
|
|
.globl print_message
|
|
|
|
|
print_message:
|
|
|
|
|
/* Preserve registers */
|
|
|
|
|
pushw %ax
|
|
|
|
|
/* Print string */
|
|
|
|
|
1: lodsb
|
|
|
|
|
testb %al, %al
|
|
|
|
|
je 2f
|
|
|
|
|
call print_character
|
|
|
|
|
jmp 1b
|
|
|
|
|
2: /* Restore registers and return */
|
|
|
|
|
popw %ax
|
|
|
|
|
ret
|
|
|
|
|
.size print_message, . - print_message
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* Utility functions: print hex digit/byte/word/dword
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %al (low nibble) : digit to print
|
|
|
|
|
* %al : byte to print
|
|
|
|
|
* %ax : word to print
|
|
|
|
|
* %eax : dword to print
|
2008-05-21 18:43:58 +01:00
|
|
|
* %ds:di : output buffer (or %di=0 to print to console)
|
2008-03-11 11:32:19 +00:00
|
|
|
* Returns:
|
2008-05-21 18:43:58 +01:00
|
|
|
* %ds:di : next character in output buffer (if applicable)
|
2008-03-11 11:32:19 +00:00
|
|
|
*****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2008-03-11 11:32:19 +00:00
|
|
|
.code16
|
|
|
|
|
.globl print_hex_dword
|
|
|
|
|
print_hex_dword:
|
|
|
|
|
rorl $16, %eax
|
|
|
|
|
call print_hex_word
|
|
|
|
|
rorl $16, %eax
|
|
|
|
|
/* Fall through */
|
|
|
|
|
.size print_hex_dword, . - print_hex_dword
|
|
|
|
|
.globl print_hex_word
|
|
|
|
|
print_hex_word:
|
|
|
|
|
xchgb %al, %ah
|
|
|
|
|
call print_hex_byte
|
|
|
|
|
xchgb %al, %ah
|
|
|
|
|
/* Fall through */
|
|
|
|
|
.size print_hex_word, . - print_hex_word
|
|
|
|
|
.globl print_hex_byte
|
|
|
|
|
print_hex_byte:
|
|
|
|
|
rorb $4, %al
|
|
|
|
|
call print_hex_nibble
|
|
|
|
|
rorb $4, %al
|
|
|
|
|
/* Fall through */
|
|
|
|
|
.size print_hex_byte, . - print_hex_byte
|
|
|
|
|
.globl print_hex_nibble
|
|
|
|
|
print_hex_nibble:
|
|
|
|
|
/* Preserve registers */
|
|
|
|
|
pushw %ax
|
|
|
|
|
/* Print digit (technique by Norbert Juffa <norbert.juffa@amd.com> */
|
|
|
|
|
andb $0x0f, %al
|
|
|
|
|
cmpb $10, %al
|
|
|
|
|
sbbb $0x69, %al
|
|
|
|
|
das
|
|
|
|
|
call print_character
|
|
|
|
|
/* Restore registers and return */
|
|
|
|
|
popw %ax
|
|
|
|
|
ret
|
|
|
|
|
.size print_hex_nibble, . - print_hex_nibble
|
|
|
|
|
|
2008-05-21 18:43:58 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
|
* Utility function: print PCI bus:dev.fn
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %ax : PCI bus:dev.fn to print
|
|
|
|
|
* %ds:di : output buffer (or %di=0 to print to console)
|
|
|
|
|
* Returns:
|
|
|
|
|
* %ds:di : next character in output buffer (if applicable)
|
|
|
|
|
*****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2008-05-21 18:43:58 +01:00
|
|
|
.code16
|
|
|
|
|
.globl print_pci_busdevfn
|
|
|
|
|
print_pci_busdevfn:
|
|
|
|
|
/* Preserve registers */
|
|
|
|
|
pushw %ax
|
|
|
|
|
/* Print bus */
|
|
|
|
|
xchgb %al, %ah
|
|
|
|
|
call print_hex_byte
|
|
|
|
|
/* Print ":" */
|
2009-02-16 03:53:25 +00:00
|
|
|
movb $( ':' ), %al
|
2008-05-21 18:43:58 +01:00
|
|
|
call print_character
|
|
|
|
|
/* Print device */
|
|
|
|
|
movb %ah, %al
|
|
|
|
|
shrb $3, %al
|
|
|
|
|
call print_hex_byte
|
|
|
|
|
/* Print "." */
|
2009-02-16 03:53:25 +00:00
|
|
|
movb $( '.' ), %al
|
2008-05-21 18:43:58 +01:00
|
|
|
call print_character
|
|
|
|
|
/* Print function */
|
|
|
|
|
movb %ah, %al
|
|
|
|
|
andb $0x07, %al
|
|
|
|
|
call print_hex_nibble
|
|
|
|
|
/* Restore registers and return */
|
|
|
|
|
popw %ax
|
|
|
|
|
ret
|
|
|
|
|
.size print_pci_busdevfn, . - print_pci_busdevfn
|
|
|
|
|
|
2008-10-31 19:10:28 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
|
* Utility function: clear current line
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %ds:di : output buffer (or %di=0 to print to console)
|
|
|
|
|
* Returns:
|
|
|
|
|
* %ds:di : next character in output buffer (if applicable)
|
|
|
|
|
*****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2008-10-31 19:10:28 +00:00
|
|
|
.code16
|
|
|
|
|
.globl print_kill_line
|
|
|
|
|
print_kill_line:
|
|
|
|
|
/* Preserve registers */
|
|
|
|
|
pushw %ax
|
|
|
|
|
pushw %cx
|
|
|
|
|
/* Print CR */
|
2009-02-16 03:53:25 +00:00
|
|
|
movb $( '\r' ), %al
|
2008-10-31 19:10:28 +00:00
|
|
|
call print_character
|
|
|
|
|
/* Print 79 spaces */
|
2009-02-16 03:53:25 +00:00
|
|
|
movb $( ' ' ), %al
|
2008-10-31 19:10:28 +00:00
|
|
|
movw $79, %cx
|
|
|
|
|
1: call print_character
|
|
|
|
|
loop 1b
|
|
|
|
|
/* Print CR */
|
2009-02-16 03:53:25 +00:00
|
|
|
movb $( '\r' ), %al
|
2008-10-31 19:10:28 +00:00
|
|
|
call print_character
|
|
|
|
|
/* Restore registers and return */
|
|
|
|
|
popw %cx
|
|
|
|
|
popw %ax
|
|
|
|
|
ret
|
|
|
|
|
.size print_kill_line, . - print_kill_line
|
|
|
|
|
|
2006-05-01 21:26:44 +00:00
|
|
|
/****************************************************************************
|
2010-04-19 22:22:11 +01:00
|
|
|
* flatten_real_mode
|
2007-09-25 18:01:15 +01:00
|
|
|
*
|
2010-04-19 22:22:11 +01:00
|
|
|
* Set up 4GB segment limits
|
2007-09-25 18:01:15 +01:00
|
|
|
*
|
|
|
|
|
* Parameters:
|
2010-04-19 22:22:11 +01:00
|
|
|
* none
|
2007-09-25 18:01:15 +01:00
|
|
|
* Returns:
|
|
|
|
|
* none
|
|
|
|
|
* Corrupts:
|
2010-04-19 22:22:11 +01:00
|
|
|
* none
|
2007-09-25 18:01:15 +01:00
|
|
|
****************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
#ifndef KEEP_IT_REAL
|
|
|
|
|
|
|
|
|
|
/* GDT for protected-mode calls */
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2007-09-25 18:01:15 +01:00
|
|
|
.align 16
|
2010-04-19 22:22:11 +01:00
|
|
|
flatten_vars:
|
|
|
|
|
flatten_gdt:
|
|
|
|
|
flatten_gdt_limit: .word flatten_gdt_length - 1
|
|
|
|
|
flatten_gdt_base: .long 0
|
2007-09-25 18:01:15 +01:00
|
|
|
.word 0 /* padding */
|
2010-04-19 22:22:11 +01:00
|
|
|
flatten_cs: /* 16-bit protected-mode flat code segment */
|
|
|
|
|
.equ FLAT_CS, flatten_cs - flatten_gdt
|
2007-09-25 18:01:15 +01:00
|
|
|
.word 0xffff, 0
|
2010-04-19 21:53:36 +01:00
|
|
|
.byte 0, 0x9b, 0x8f, 0
|
2010-04-19 22:22:11 +01:00
|
|
|
flatten_ss: /* 16-bit protected-mode flat stack segment */
|
|
|
|
|
.equ FLAT_SS, flatten_ss - flatten_gdt
|
2007-09-25 18:01:15 +01:00
|
|
|
.word 0xffff, 0
|
2010-04-19 21:53:36 +01:00
|
|
|
.byte 0, 0x93, 0x8f, 0
|
2010-04-19 22:22:11 +01:00
|
|
|
flatten_gdt_end:
|
|
|
|
|
.equ flatten_gdt_length, . - flatten_gdt
|
|
|
|
|
.size flatten_gdt, . - flatten_gdt
|
2007-09-25 18:01:15 +01:00
|
|
|
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2007-09-25 18:01:15 +01:00
|
|
|
.align 16
|
2010-04-19 22:22:11 +01:00
|
|
|
flatten_saved_gdt:
|
2007-09-25 18:01:15 +01:00
|
|
|
.long 0, 0
|
2010-04-19 22:22:11 +01:00
|
|
|
.size flatten_saved_gdt, . - flatten_saved_gdt
|
2007-09-25 18:01:15 +01:00
|
|
|
|
2010-04-19 22:22:11 +01:00
|
|
|
.equ flatten_vars_size, . - flatten_vars
|
|
|
|
|
#define FLATTEN_VAR(x) ( -flatten_vars_size + ( (x) - flatten_vars ) )
|
2008-03-11 13:26:46 +00:00
|
|
|
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2007-09-25 18:01:15 +01:00
|
|
|
.code16
|
2010-04-19 22:22:11 +01:00
|
|
|
flatten_real_mode:
|
|
|
|
|
/* Preserve registers and flags, allocate local variable block */
|
2008-03-11 13:26:46 +00:00
|
|
|
pushw %bp
|
|
|
|
|
movw %sp, %bp
|
2010-04-19 22:22:11 +01:00
|
|
|
subw $flatten_vars_size, %sp
|
2008-03-11 13:26:46 +00:00
|
|
|
andw $0xfff0, %sp
|
2007-09-25 18:01:15 +01:00
|
|
|
pushfl
|
2010-04-19 22:22:11 +01:00
|
|
|
pushl %eax
|
|
|
|
|
pushl %edi
|
|
|
|
|
pushw %si
|
|
|
|
|
pushw %cx
|
2007-09-25 18:01:15 +01:00
|
|
|
pushw %gs
|
|
|
|
|
pushw %fs
|
|
|
|
|
pushw %es
|
|
|
|
|
pushw %ds
|
|
|
|
|
pushw %ss
|
|
|
|
|
|
2010-04-19 22:22:11 +01:00
|
|
|
/* Fill local variable block and preserve GDT */
|
2008-03-11 13:26:46 +00:00
|
|
|
pushw %ss
|
|
|
|
|
popw %es
|
2010-04-19 22:22:11 +01:00
|
|
|
movw $flatten_vars, %si
|
|
|
|
|
leaw FLATTEN_VAR(flatten_vars)(%bp), %di
|
|
|
|
|
movw $flatten_vars_size, %cx
|
2008-03-11 13:26:46 +00:00
|
|
|
cs rep movsb
|
2010-04-19 22:22:11 +01:00
|
|
|
sgdt FLATTEN_VAR(flatten_saved_gdt)(%bp)
|
2008-03-11 13:26:46 +00:00
|
|
|
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Set up GDT bases */
|
|
|
|
|
xorl %eax, %eax
|
2008-03-11 13:26:46 +00:00
|
|
|
movw %ss, %ax
|
2007-09-25 18:01:15 +01:00
|
|
|
shll $4, %eax
|
2008-03-11 13:26:46 +00:00
|
|
|
movzwl %bp, %edi
|
2010-04-19 22:22:11 +01:00
|
|
|
addr32 leal FLATTEN_VAR(flatten_gdt)(%eax, %edi), %eax
|
|
|
|
|
movl %eax, FLATTEN_VAR(flatten_gdt_base)(%bp)
|
2007-09-25 18:01:15 +01:00
|
|
|
movw %cs, %ax
|
2010-04-19 22:22:11 +01:00
|
|
|
movw $FLATTEN_VAR(flatten_cs), %di
|
2007-09-25 18:01:15 +01:00
|
|
|
call set_seg_base
|
|
|
|
|
movw %ss, %ax
|
2010-04-19 22:22:11 +01:00
|
|
|
movw $FLATTEN_VAR(flatten_ss), %di
|
2007-09-25 18:01:15 +01:00
|
|
|
call set_seg_base
|
|
|
|
|
|
2010-04-19 22:22:11 +01:00
|
|
|
/* Switch temporarily to protected mode and set segment registers */
|
|
|
|
|
pushw %cs
|
|
|
|
|
pushw $2f
|
2007-09-25 18:01:15 +01:00
|
|
|
cli
|
2010-04-19 22:22:11 +01:00
|
|
|
data32 lgdt FLATTEN_VAR(flatten_gdt)(%bp)
|
2007-09-25 18:01:15 +01:00
|
|
|
movl %cr0, %eax
|
|
|
|
|
orb $CR0_PE, %al
|
|
|
|
|
movl %eax, %cr0
|
2010-04-19 22:22:11 +01:00
|
|
|
ljmp $FLAT_CS, $1f
|
|
|
|
|
1: movw $FLAT_SS, %ax
|
2007-09-25 18:01:15 +01:00
|
|
|
movw %ax, %ss
|
|
|
|
|
movw %ax, %ds
|
|
|
|
|
movw %ax, %es
|
|
|
|
|
movw %ax, %fs
|
|
|
|
|
movw %ax, %gs
|
|
|
|
|
movl %cr0, %eax
|
|
|
|
|
andb $0!CR0_PE, %al
|
|
|
|
|
movl %eax, %cr0
|
2010-04-19 22:22:11 +01:00
|
|
|
lret
|
|
|
|
|
2: /* lret will ljmp to here */
|
2007-09-25 18:01:15 +01:00
|
|
|
|
2010-04-19 22:22:11 +01:00
|
|
|
/* Restore GDT, registers and flags */
|
|
|
|
|
data32 lgdt FLATTEN_VAR(flatten_saved_gdt)(%bp)
|
|
|
|
|
popw %ss
|
2007-09-25 18:01:15 +01:00
|
|
|
popw %ds
|
|
|
|
|
popw %es
|
|
|
|
|
popw %fs
|
|
|
|
|
popw %gs
|
2010-04-19 22:22:11 +01:00
|
|
|
popw %cx
|
|
|
|
|
popw %si
|
|
|
|
|
popl %edi
|
|
|
|
|
popl %eax
|
2007-09-25 18:01:15 +01:00
|
|
|
popfl
|
2008-03-11 13:26:46 +00:00
|
|
|
movw %bp, %sp
|
|
|
|
|
popw %bp
|
2007-09-25 18:01:15 +01:00
|
|
|
ret
|
2010-04-19 22:22:11 +01:00
|
|
|
.size flatten_real_mode, . - flatten_real_mode
|
2007-09-25 18:01:15 +01:00
|
|
|
|
|
|
|
|
set_seg_base:
|
|
|
|
|
rolw $4, %ax
|
2008-03-11 13:26:46 +00:00
|
|
|
movw %ax, 2(%bp,%di)
|
|
|
|
|
andw $0xfff0, 2(%bp,%di)
|
|
|
|
|
movb %al, 4(%bp,%di)
|
|
|
|
|
andb $0x0f, 4(%bp,%di)
|
2007-09-25 18:01:15 +01:00
|
|
|
ret
|
|
|
|
|
.size set_seg_base, . - set_seg_base
|
|
|
|
|
|
|
|
|
|
#endif /* KEEP_IT_REAL */
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
2010-04-19 22:22:11 +01:00
|
|
|
* copy_bytes
|
2007-09-25 18:01:15 +01:00
|
|
|
*
|
|
|
|
|
* Copy bytes
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %ds:esi : source address
|
|
|
|
|
* %es:edi : destination address
|
|
|
|
|
* %ecx : length
|
|
|
|
|
* Returns:
|
|
|
|
|
* %ds:esi : next source address
|
2008-03-11 13:26:46 +00:00
|
|
|
* %es:edi : next destination address
|
2007-09-25 18:01:15 +01:00
|
|
|
* Corrupts:
|
|
|
|
|
* None
|
|
|
|
|
****************************************************************************
|
|
|
|
|
*/
|
2010-04-19 22:22:11 +01:00
|
|
|
#if ! COMPRESS
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2007-09-25 18:01:15 +01:00
|
|
|
.code16
|
|
|
|
|
copy_bytes:
|
|
|
|
|
pushl %ecx
|
|
|
|
|
rep addr32 movsb
|
|
|
|
|
popl %ecx
|
|
|
|
|
ret
|
|
|
|
|
.size copy_bytes, . - copy_bytes
|
2010-04-19 22:22:11 +01:00
|
|
|
#endif /* COMPRESS */
|
2007-09-25 18:01:15 +01:00
|
|
|
|
|
|
|
|
/****************************************************************************
|
2010-04-19 22:22:11 +01:00
|
|
|
* install_block
|
2006-05-01 21:26:44 +00:00
|
|
|
*
|
2006-05-01 22:35:19 +00:00
|
|
|
* Install block to specified address
|
2006-05-01 21:26:44 +00:00
|
|
|
*
|
2006-05-01 22:35:19 +00:00
|
|
|
* Parameters:
|
2008-03-11 13:26:46 +00:00
|
|
|
* %esi : source physical address (must be a multiple of 16)
|
|
|
|
|
* %edi : destination physical address (must be a multiple of 16)
|
2006-05-02 20:51:07 +00:00
|
|
|
* %ecx : length of (decompressed) data
|
|
|
|
|
* %edx : total length of block (including any uninitialised data portion)
|
2006-05-01 21:26:44 +00:00
|
|
|
* Returns:
|
2008-03-11 13:26:46 +00:00
|
|
|
* %esi : next source physical address (will be a multiple of 16)
|
2010-04-20 11:05:53 +01:00
|
|
|
* %edi : next destination physical address (will be a multiple of 16)
|
2006-05-01 22:35:19 +00:00
|
|
|
* Corrupts:
|
2008-03-11 13:26:46 +00:00
|
|
|
* none
|
2006-05-01 21:26:44 +00:00
|
|
|
****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2006-05-01 21:26:44 +00:00
|
|
|
.code16
|
2006-05-01 22:35:19 +00:00
|
|
|
install_block:
|
2008-03-09 22:13:07 +00:00
|
|
|
/* Preserve registers */
|
2008-03-11 13:26:46 +00:00
|
|
|
pushw %ds
|
|
|
|
|
pushw %es
|
|
|
|
|
pushl %ecx
|
2008-03-09 22:13:07 +00:00
|
|
|
|
2010-04-19 22:22:11 +01:00
|
|
|
/* Convert %esi and %edi to %ds:esi and %es:edi */
|
2008-03-11 13:26:46 +00:00
|
|
|
shrl $4, %esi
|
|
|
|
|
movw %si, %ds
|
|
|
|
|
xorw %si, %si
|
2010-04-19 22:22:11 +01:00
|
|
|
shll $4, %esi
|
2008-03-11 13:26:46 +00:00
|
|
|
shrl $4, %edi
|
|
|
|
|
movw %di, %es
|
|
|
|
|
xorw %di, %di
|
2010-04-19 22:22:11 +01:00
|
|
|
shll $4, %edi
|
2008-03-11 13:26:46 +00:00
|
|
|
|
2007-07-16 16:58:38 +01:00
|
|
|
#if COMPRESS
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Decompress source to destination */
|
2007-07-16 16:58:38 +01:00
|
|
|
call decompress16
|
|
|
|
|
#else
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Copy source to destination */
|
|
|
|
|
call copy_bytes
|
2007-07-16 16:58:38 +01:00
|
|
|
#endif
|
2006-05-02 20:51:07 +00:00
|
|
|
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Zero .bss portion */
|
|
|
|
|
negl %ecx
|
|
|
|
|
addl %edx, %ecx
|
|
|
|
|
pushw %ax
|
|
|
|
|
xorw %ax, %ax
|
2006-05-02 20:51:07 +00:00
|
|
|
rep addr32 stosb
|
2007-09-25 18:01:15 +01:00
|
|
|
popw %ax
|
2006-05-01 22:35:19 +00:00
|
|
|
|
2010-04-20 11:05:53 +01:00
|
|
|
/* Round up %esi and %edi to start of next blocks */
|
2007-07-15 02:52:02 +01:00
|
|
|
addl $0xf, %esi
|
|
|
|
|
andl $~0xf, %esi
|
2010-04-20 11:05:53 +01:00
|
|
|
addl $0xf, %edi
|
|
|
|
|
andl $~0xf, %edi
|
2007-07-15 02:52:02 +01:00
|
|
|
|
2010-04-20 11:05:53 +01:00
|
|
|
/* Convert %ds:esi and %es:edi back to physical addresses */
|
2010-04-19 22:22:11 +01:00
|
|
|
xorl %ecx, %ecx
|
|
|
|
|
movw %ds, %cx
|
2008-03-11 13:26:46 +00:00
|
|
|
shll $4, %ecx
|
|
|
|
|
addl %ecx, %esi
|
2010-04-20 11:05:53 +01:00
|
|
|
xorl %ecx, %ecx
|
|
|
|
|
movw %es, %cx
|
|
|
|
|
shll $4, %ecx
|
|
|
|
|
addl %ecx, %edi
|
2008-03-11 13:26:46 +00:00
|
|
|
|
2010-04-19 22:22:11 +01:00
|
|
|
/* Restore registers and return */
|
2008-03-11 13:26:46 +00:00
|
|
|
popl %ecx
|
|
|
|
|
popw %es
|
|
|
|
|
popw %ds
|
2006-05-01 22:35:19 +00:00
|
|
|
ret
|
|
|
|
|
.size install_block, . - install_block
|
2010-04-19 22:22:11 +01:00
|
|
|
|
2006-05-01 22:35:19 +00:00
|
|
|
/****************************************************************************
|
2010-04-19 22:22:11 +01:00
|
|
|
* alloc_basemem
|
2006-05-01 22:35:19 +00:00
|
|
|
*
|
|
|
|
|
* Allocate space for .text16 and .data16 from top of base memory.
|
|
|
|
|
* Memory is allocated using the BIOS free base memory counter at
|
|
|
|
|
* 0x40:13.
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* none
|
|
|
|
|
* Returns:
|
|
|
|
|
* %ax : .text16 segment address
|
|
|
|
|
* %bx : .data16 segment address
|
|
|
|
|
* Corrupts:
|
|
|
|
|
* none
|
|
|
|
|
****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2006-05-01 22:35:19 +00:00
|
|
|
.code16
|
2008-03-09 22:13:07 +00:00
|
|
|
.globl alloc_basemem
|
2006-05-01 22:35:19 +00:00
|
|
|
alloc_basemem:
|
2008-11-18 19:43:13 +00:00
|
|
|
/* Preserve registers */
|
|
|
|
|
pushw %fs
|
|
|
|
|
|
2006-05-01 22:35:19 +00:00
|
|
|
/* FBMS => %ax as segment address */
|
2008-11-18 19:43:13 +00:00
|
|
|
pushw $0x40
|
|
|
|
|
popw %fs
|
2006-05-01 21:26:44 +00:00
|
|
|
movw %fs:0x13, %ax
|
|
|
|
|
shlw $6, %ax
|
|
|
|
|
|
2008-11-18 19:43:13 +00:00
|
|
|
/* Calculate .data16 segment address */
|
2008-10-09 22:22:01 +01:00
|
|
|
subw $_data16_memsz_pgh, %ax
|
2006-05-01 22:35:19 +00:00
|
|
|
pushw %ax
|
|
|
|
|
|
2008-11-18 19:43:13 +00:00
|
|
|
/* Calculate .text16 segment address */
|
2008-10-09 22:22:01 +01:00
|
|
|
subw $_text16_memsz_pgh, %ax
|
2006-05-01 22:35:19 +00:00
|
|
|
pushw %ax
|
|
|
|
|
|
|
|
|
|
/* Update FBMS */
|
|
|
|
|
shrw $6, %ax
|
|
|
|
|
movw %ax, %fs:0x13
|
|
|
|
|
|
2008-11-18 19:43:13 +00:00
|
|
|
/* Retrieve .text16 and .data16 segment addresses */
|
2006-05-01 21:26:44 +00:00
|
|
|
popw %ax
|
2006-05-01 22:35:19 +00:00
|
|
|
popw %bx
|
2008-11-18 19:43:13 +00:00
|
|
|
|
|
|
|
|
/* Restore registers and return */
|
|
|
|
|
popw %fs
|
2006-05-01 21:26:44 +00:00
|
|
|
ret
|
2006-05-01 22:35:19 +00:00
|
|
|
.size alloc_basemem, . - alloc_basemem
|
2006-05-01 21:26:44 +00:00
|
|
|
|
2008-11-18 19:43:13 +00:00
|
|
|
/****************************************************************************
|
2010-04-19 22:22:11 +01:00
|
|
|
* free_basemem
|
2008-11-18 19:43:13 +00:00
|
|
|
*
|
|
|
|
|
* Free space allocated with alloc_basemem.
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %ax : .text16 segment address
|
|
|
|
|
* %bx : .data16 segment address
|
|
|
|
|
* Returns:
|
|
|
|
|
* %ax : 0 if successfully freed
|
|
|
|
|
* Corrupts:
|
|
|
|
|
* none
|
|
|
|
|
****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".text16", "ax", @progbits
|
2008-11-18 19:43:13 +00:00
|
|
|
.code16
|
|
|
|
|
.globl free_basemem
|
|
|
|
|
free_basemem:
|
|
|
|
|
/* Preserve registers */
|
|
|
|
|
pushw %fs
|
|
|
|
|
|
|
|
|
|
/* Check FBMS counter */
|
|
|
|
|
pushw %ax
|
|
|
|
|
shrw $6, %ax
|
|
|
|
|
pushw $0x40
|
|
|
|
|
popw %fs
|
|
|
|
|
cmpw %ax, %fs:0x13
|
|
|
|
|
popw %ax
|
|
|
|
|
jne 1f
|
|
|
|
|
|
|
|
|
|
/* Check hooked interrupt count */
|
|
|
|
|
cmpw $0, %cs:hooked_bios_interrupts
|
|
|
|
|
jne 1f
|
|
|
|
|
|
|
|
|
|
/* OK to free memory */
|
|
|
|
|
addw $_text16_memsz_pgh, %ax
|
|
|
|
|
addw $_data16_memsz_pgh, %ax
|
|
|
|
|
shrw $6, %ax
|
|
|
|
|
movw %ax, %fs:0x13
|
|
|
|
|
xorw %ax, %ax
|
|
|
|
|
|
|
|
|
|
1: /* Restore registers and return */
|
|
|
|
|
popw %fs
|
|
|
|
|
ret
|
|
|
|
|
.size free_basemem, . - free_basemem
|
|
|
|
|
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".text16.data", "aw", @progbits
|
2008-11-18 19:43:13 +00:00
|
|
|
.globl hooked_bios_interrupts
|
|
|
|
|
hooked_bios_interrupts:
|
|
|
|
|
.word 0
|
|
|
|
|
.size hooked_bios_interrupts, . - hooked_bios_interrupts
|
|
|
|
|
|
2006-05-02 20:51:07 +00:00
|
|
|
/****************************************************************************
|
2010-04-19 22:22:11 +01:00
|
|
|
* install
|
2006-05-02 20:51:07 +00:00
|
|
|
*
|
|
|
|
|
* Install all text and data segments.
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
2008-03-09 22:13:07 +00:00
|
|
|
* none
|
2006-05-02 20:51:07 +00:00
|
|
|
* Returns:
|
2008-03-09 22:13:07 +00:00
|
|
|
* %ax : .text16 segment address
|
|
|
|
|
* %bx : .data16 segment address
|
2006-05-02 20:51:07 +00:00
|
|
|
* Corrupts:
|
|
|
|
|
* none
|
|
|
|
|
****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2006-05-02 20:51:07 +00:00
|
|
|
.code16
|
|
|
|
|
.globl install
|
|
|
|
|
install:
|
2008-03-09 22:13:07 +00:00
|
|
|
/* Preserve registers */
|
|
|
|
|
pushl %esi
|
|
|
|
|
pushl %edi
|
2006-05-02 20:51:07 +00:00
|
|
|
/* Allocate space for .text16 and .data16 */
|
|
|
|
|
call alloc_basemem
|
2008-03-09 22:13:07 +00:00
|
|
|
/* Image source = %cs:0000 */
|
|
|
|
|
xorl %esi, %esi
|
|
|
|
|
/* Image destination = HIGHMEM_LOADPOINT */
|
|
|
|
|
movl $HIGHMEM_LOADPOINT, %edi
|
|
|
|
|
/* Install text and data segments */
|
|
|
|
|
call install_prealloc
|
|
|
|
|
/* Restore registers and return */
|
|
|
|
|
popl %edi
|
|
|
|
|
popl %esi
|
|
|
|
|
ret
|
2006-05-02 20:51:07 +00:00
|
|
|
.size install, . - install
|
2008-03-09 22:13:07 +00:00
|
|
|
|
|
|
|
|
/****************************************************************************
|
2010-04-19 22:22:11 +01:00
|
|
|
* install_prealloc
|
2008-03-09 22:13:07 +00:00
|
|
|
*
|
|
|
|
|
* Install all text and data segments.
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %ax : .text16 segment address
|
|
|
|
|
* %bx : .data16 segment address
|
|
|
|
|
* %esi : Image source physical address (or zero for %cs:0000)
|
|
|
|
|
* %edi : Decompression temporary area physical address
|
|
|
|
|
* Corrupts:
|
|
|
|
|
* none
|
|
|
|
|
****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".prefix.lib", "awx", @progbits
|
2008-03-09 22:13:07 +00:00
|
|
|
.code16
|
2006-05-02 20:51:07 +00:00
|
|
|
.globl install_prealloc
|
|
|
|
|
install_prealloc:
|
2007-07-15 02:52:02 +01:00
|
|
|
/* Save registers */
|
2008-03-09 22:13:07 +00:00
|
|
|
pushal
|
2007-09-25 18:01:15 +01:00
|
|
|
pushw %ds
|
2007-09-25 19:06:38 +01:00
|
|
|
pushw %es
|
2007-09-25 18:01:15 +01:00
|
|
|
|
|
|
|
|
/* Sanity: clear the direction flag asap */
|
|
|
|
|
cld
|
|
|
|
|
|
2010-04-20 11:05:53 +01:00
|
|
|
/* Copy decompression temporary area physical address to %ebp */
|
|
|
|
|
movl %edi, %ebp
|
|
|
|
|
|
|
|
|
|
/* Install .text16.early */
|
|
|
|
|
pushl %esi
|
|
|
|
|
xorl %esi, %esi
|
|
|
|
|
movw %cs, %si
|
|
|
|
|
shll $4, %esi
|
|
|
|
|
addl $_text16_early_lma, %esi
|
|
|
|
|
movzwl %ax, %edi
|
|
|
|
|
shll $4, %edi
|
|
|
|
|
movl $_text16_early_filesz, %ecx
|
|
|
|
|
movl $_text16_early_memsz, %edx
|
|
|
|
|
call install_block /* .text16.early */
|
|
|
|
|
popl %esi
|
|
|
|
|
|
|
|
|
|
/* Open up access to payload */
|
2010-04-19 22:22:11 +01:00
|
|
|
#ifndef KEEP_IT_REAL
|
|
|
|
|
/* Flatten real mode */
|
|
|
|
|
call flatten_real_mode
|
|
|
|
|
#endif
|
|
|
|
|
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Calculate physical address of payload (i.e. first source) */
|
2008-03-09 22:13:07 +00:00
|
|
|
testl %esi, %esi
|
|
|
|
|
jnz 1f
|
2007-09-25 18:01:15 +01:00
|
|
|
movw %cs, %si
|
|
|
|
|
shll $4, %esi
|
2010-04-20 11:05:53 +01:00
|
|
|
1: addl %cs:payload_lma, %esi
|
2007-09-25 18:01:15 +01:00
|
|
|
|
2010-04-20 11:05:53 +01:00
|
|
|
/* Install .text16.late and .data16 */
|
|
|
|
|
movl $_text16_late_filesz, %ecx
|
|
|
|
|
movl $_text16_late_memsz, %edx
|
|
|
|
|
call install_block /* .text16.late */
|
2008-03-11 13:26:46 +00:00
|
|
|
movzwl %bx, %edi
|
|
|
|
|
shll $4, %edi
|
2008-10-09 22:22:01 +01:00
|
|
|
movl $_data16_filesz, %ecx
|
|
|
|
|
movl $_data16_memsz, %edx
|
2008-03-11 13:26:46 +00:00
|
|
|
call install_block /* .data16 */
|
2006-05-02 20:51:07 +00:00
|
|
|
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Set up %ds for access to .data16 */
|
2006-08-24 13:18:05 +00:00
|
|
|
movw %bx, %ds
|
2007-09-25 18:01:15 +01:00
|
|
|
|
|
|
|
|
#ifdef KEEP_IT_REAL
|
|
|
|
|
/* Initialise libkir */
|
2006-08-24 13:18:05 +00:00
|
|
|
movw %ax, (init_libkir_vector+2)
|
|
|
|
|
lcall *init_libkir_vector
|
|
|
|
|
#else
|
2007-01-13 01:48:12 +00:00
|
|
|
/* Install .text and .data to temporary area in high memory,
|
|
|
|
|
* prior to reading the E820 memory map and relocating
|
|
|
|
|
* properly.
|
2006-05-02 20:51:07 +00:00
|
|
|
*/
|
2010-04-20 11:05:53 +01:00
|
|
|
movl %ebp, %edi
|
2008-10-09 22:22:01 +01:00
|
|
|
movl $_textdata_filesz, %ecx
|
|
|
|
|
movl $_textdata_memsz, %edx
|
2008-03-11 13:26:46 +00:00
|
|
|
call install_block
|
2006-05-02 20:51:07 +00:00
|
|
|
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Initialise librm at current location */
|
|
|
|
|
movw %ax, (init_librm_vector+2)
|
2010-04-20 11:05:53 +01:00
|
|
|
movl %ebp, %edi
|
2007-09-25 18:01:15 +01:00
|
|
|
lcall *init_librm_vector
|
|
|
|
|
|
|
|
|
|
/* Call relocate() to determine target address for relocation.
|
2006-05-25 00:06:45 +00:00
|
|
|
* relocate() will return with %esi, %edi and %ecx set up
|
|
|
|
|
* ready for the copy to the new location.
|
|
|
|
|
*/
|
2007-09-25 18:01:15 +01:00
|
|
|
movw %ax, (prot_call_vector+2)
|
2006-05-02 20:51:07 +00:00
|
|
|
pushl $relocate
|
2006-05-25 00:06:45 +00:00
|
|
|
lcall *prot_call_vector
|
2007-09-25 19:06:38 +01:00
|
|
|
popl %edx /* discard */
|
2006-05-02 20:51:07 +00:00
|
|
|
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Copy code to new location */
|
2010-04-19 22:22:11 +01:00
|
|
|
xorw %ax, %ax
|
|
|
|
|
movw %ax, %es
|
2010-04-20 11:05:53 +01:00
|
|
|
movl %ebp, %edi
|
2010-04-19 22:22:11 +01:00
|
|
|
es rep addr32 movsb
|
2007-01-14 00:53:56 +00:00
|
|
|
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Initialise librm at new location */
|
2010-04-20 11:05:53 +01:00
|
|
|
movl %ebp, %edi
|
2007-09-25 18:01:15 +01:00
|
|
|
lcall *init_librm_vector
|
2007-09-25 19:06:38 +01:00
|
|
|
#endif
|
2010-04-19 22:22:11 +01:00
|
|
|
|
2007-09-25 18:01:15 +01:00
|
|
|
/* Restore registers */
|
2007-09-25 19:06:38 +01:00
|
|
|
popw %es
|
2007-09-25 18:01:15 +01:00
|
|
|
popw %ds
|
2008-03-09 22:13:07 +00:00
|
|
|
popal
|
2006-05-02 20:51:07 +00:00
|
|
|
ret
|
|
|
|
|
.size install_prealloc, . - install_prealloc
|
2006-05-25 00:06:45 +00:00
|
|
|
|
2010-04-19 22:22:11 +01:00
|
|
|
/* Vectors for far calls to .text16 functions. Must be in
|
|
|
|
|
* .data16, since .prefix may not be writable.
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".data16", "aw", @progbits
|
2006-08-24 13:18:05 +00:00
|
|
|
#ifdef KEEP_IT_REAL
|
|
|
|
|
init_libkir_vector:
|
|
|
|
|
.word init_libkir
|
|
|
|
|
.word 0
|
|
|
|
|
.size init_libkir_vector, . - init_libkir_vector
|
|
|
|
|
#else
|
2006-05-25 00:06:45 +00:00
|
|
|
init_librm_vector:
|
|
|
|
|
.word init_librm
|
|
|
|
|
.word 0
|
|
|
|
|
.size init_librm_vector, . - init_librm_vector
|
|
|
|
|
prot_call_vector:
|
|
|
|
|
.word prot_call
|
|
|
|
|
.word 0
|
|
|
|
|
.size prot_call_vector, . - prot_call_vector
|
|
|
|
|
#endif
|
2007-07-17 12:52:54 +01:00
|
|
|
|
2010-04-20 11:05:53 +01:00
|
|
|
/* Payload address */
|
|
|
|
|
.section ".prefix.lib", "awx", @progbits
|
|
|
|
|
payload_lma:
|
|
|
|
|
.long 0
|
|
|
|
|
.section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
|
|
|
|
|
.ascii "ADHL"
|
|
|
|
|
.long payload_lma
|
|
|
|
|
.long 1
|
|
|
|
|
.long 0
|
|
|
|
|
.previous
|
|
|
|
|
|
2008-11-18 19:43:13 +00:00
|
|
|
/****************************************************************************
|
2010-04-19 22:22:11 +01:00
|
|
|
* uninstall
|
2008-11-18 19:43:13 +00:00
|
|
|
*
|
|
|
|
|
* Uninstall all text and data segments.
|
|
|
|
|
*
|
|
|
|
|
* Parameters:
|
|
|
|
|
* %ax : .text16 segment address
|
|
|
|
|
* %bx : .data16 segment address
|
|
|
|
|
* Returns:
|
|
|
|
|
* none
|
|
|
|
|
* Corrupts:
|
|
|
|
|
* none
|
|
|
|
|
****************************************************************************
|
|
|
|
|
*/
|
[i386] Add explicit flags and type on all .section declarations
Try to avoid future problems caused by implicit section flags and/or
type information by instituting a policy that all .section
declarations must explicitly state the flags and type.
Most of this change was achieved using
perl -pi \
-e 's/".text"$/".text", "ax", \@progbits/ ; ' \
-e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \
-e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \
-e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \
-e 's/".data"$/".data", "aw", \@progbits/ ; ' \
-e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \
-e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \
-e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \
-e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \
-e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \
-e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \
-e 's/".weak"$/".weak", "a", \@nobits/ ; ' \
`git grep -l '\.section'`
2009-02-15 10:54:52 +00:00
|
|
|
.section ".text16", "ax", @progbits
|
2008-11-18 19:43:13 +00:00
|
|
|
.code16
|
|
|
|
|
.globl uninstall
|
|
|
|
|
uninstall:
|
|
|
|
|
call free_basemem
|
|
|
|
|
ret
|
|
|
|
|
.size uninstall, . - uninstall
|
|
|
|
|
|
|
|
|
|
|
2007-07-17 12:52:54 +01:00
|
|
|
|
|
|
|
|
/* File split information for the compressor */
|
|
|
|
|
#if COMPRESS
|
2010-04-20 11:05:53 +01:00
|
|
|
#define PACK_OR_COPY "PACK"
|
|
|
|
|
#else
|
|
|
|
|
#define PACK_OR_COPY "COPY"
|
|
|
|
|
#endif
|
2008-10-16 20:39:48 -04:00
|
|
|
.section ".zinfo", "a", @progbits
|
2007-07-17 12:52:54 +01:00
|
|
|
.ascii "COPY"
|
2008-10-09 22:22:01 +01:00
|
|
|
.long _prefix_lma
|
|
|
|
|
.long _prefix_filesz
|
2007-07-17 12:52:54 +01:00
|
|
|
.long _max_align
|
2010-04-20 11:05:53 +01:00
|
|
|
.ascii PACK_OR_COPY
|
|
|
|
|
.long _text16_early_lma
|
|
|
|
|
.long _text16_early_filesz
|
2007-07-17 12:52:54 +01:00
|
|
|
.long _max_align
|
2010-04-20 11:05:53 +01:00
|
|
|
.ascii "PAYL"
|
|
|
|
|
.long 0
|
|
|
|
|
.long 0
|
|
|
|
|
.long _max_align
|
|
|
|
|
.ascii PACK_OR_COPY
|
|
|
|
|
.long _text16_late_lma
|
|
|
|
|
.long _text16_late_filesz
|
|
|
|
|
.long _max_align
|
|
|
|
|
.ascii PACK_OR_COPY
|
2008-10-09 22:22:01 +01:00
|
|
|
.long _data16_lma
|
|
|
|
|
.long _data16_filesz
|
2007-07-17 12:52:54 +01:00
|
|
|
.long _max_align
|
2010-04-20 11:05:53 +01:00
|
|
|
.ascii PACK_OR_COPY
|
2008-10-09 22:22:01 +01:00
|
|
|
.long _textdata_lma
|
|
|
|
|
.long _textdata_filesz
|
2007-07-17 12:52:54 +01:00
|
|
|
.long _max_align
|