mirror of https://github.com/ipxe/ipxe.git
Merge from Etherboot 5.4
commit
bb7394b041
|
@ -82,6 +82,10 @@ MEDIA += dsk
|
||||||
OBJS_dskprefix = dskprefix zdskprefix
|
OBJS_dskprefix = dskprefix zdskprefix
|
||||||
CFLAGS_zdskprefix = $(CFLAGS_ZPREFIX)
|
CFLAGS_zdskprefix = $(CFLAGS_ZPREFIX)
|
||||||
|
|
||||||
|
MEDIA += hd
|
||||||
|
OBJS_hdprefix = hdprefix zhdprefix
|
||||||
|
CFLAGS_zhdprefix = $(CFLAGS_ZPREFIX)
|
||||||
|
|
||||||
MEDIA += raw
|
MEDIA += raw
|
||||||
OBJS_rawprefix = rawprefix zrawprefix
|
OBJS_rawprefix = rawprefix zrawprefix
|
||||||
CFLAGS_zrawprefix = $(CFLAGS_ZPREFIX)
|
CFLAGS_zrawprefix = $(CFLAGS_ZPREFIX)
|
||||||
|
|
|
@ -0,0 +1,296 @@
|
||||||
|
/****************************************************************\
|
||||||
|
|
||||||
|
hdprefix.S Copyright (C) 2005 Per Dalgas Jakobsen
|
||||||
|
|
||||||
|
This code has been inspired/derived by the OSLoader by Vladislav Aleksandrov.
|
||||||
|
http://www.programmersheaven.com/zone5/cat469/40546.htm.
|
||||||
|
|
||||||
|
This software may be used and distributed according to the terms
|
||||||
|
of the GNU Public License (GPL), incorporated herein by reference.
|
||||||
|
|
||||||
|
hdprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.
|
||||||
|
|
||||||
|
Actions performed by hdprefix:
|
||||||
|
1) Load the MBR to LOADSEG:0
|
||||||
|
2) Check which partition is active (or try first partition if none active)
|
||||||
|
3) Check wether LBA is supported.
|
||||||
|
3a) LBA
|
||||||
|
3a1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
|
||||||
|
3b) CHS (standard)
|
||||||
|
3b1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
|
||||||
|
4) Check loaded bootsector for BOOTMAGIC code.
|
||||||
|
5) Jump to payload LOADSEG:ENTRYPOINT.
|
||||||
|
|
||||||
|
Output with failure points (!#):
|
||||||
|
---
|
||||||
|
Loading (!1)partition #
|
||||||
|
Std. BIOS(!2) | Ext. BIOS(!3)
|
||||||
|
Booting...(!4)
|
||||||
|
(!5)
|
||||||
|
---
|
||||||
|
|
||||||
|
!1: Failed to load MBR with Int13,ah=2.
|
||||||
|
!2: Failed to load bootrecord+payload with Int13,ah=2.
|
||||||
|
!3: Failed to load bootrecord+payload with Int13,ah=42.
|
||||||
|
!4: Invalid BOOTMAGIC in loaded bootrecord.
|
||||||
|
!5: Jumping to payload.
|
||||||
|
|
||||||
|
\*****************************************************************/
|
||||||
|
|
||||||
|
.equ BOOTSEG, 0x07c0
|
||||||
|
.equ LOADSEG, 0x1000
|
||||||
|
.equ ENTRYPOINT, _start
|
||||||
|
|
||||||
|
.equ BOOTMAGIC, 0x0aa55
|
||||||
|
|
||||||
|
.equ partition_table, 0x1be
|
||||||
|
.equ partition_rec_size, 0x10
|
||||||
|
|
||||||
|
.equ boot_ind, 0 /* 80h=active */
|
||||||
|
.equ start_head, 1
|
||||||
|
.equ start_sector, 2 /* bits 0-5 */
|
||||||
|
.equ start_cyl, 3 /* bits 8,9 in bits 6,7 of sector */
|
||||||
|
.equ os_ind, 4 /* os indicator */
|
||||||
|
.equ end_head, 5
|
||||||
|
.equ end_sector, 6 /* bits 0-5 */
|
||||||
|
.equ end_track, 7 /* bits 8,9 in bits 6,7 of sector */
|
||||||
|
.equ nsect, 8 /* sectors preceding partition */
|
||||||
|
.equ lenght, 0x0c /* length of partition in sectors */
|
||||||
|
|
||||||
|
/-------------------------------------------------------------
|
||||||
|
|
||||||
|
.arch i386
|
||||||
|
.text
|
||||||
|
.section ".prefix", "ax", @progbits
|
||||||
|
.code16
|
||||||
|
|
||||||
|
bootstart:
|
||||||
|
jmp $BOOTSEG,$_go /* reload cs:ip */
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
/* support routines. */
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
_failed:
|
||||||
|
movw $BOOTSEG,%ax
|
||||||
|
movw %ax,%ds
|
||||||
|
movw $_failed_msg_end-_failed_msg,%cx
|
||||||
|
movw $_failed_msg,%si
|
||||||
|
call _print_str
|
||||||
|
|
||||||
|
/* stop execution - should probably have option to auto-reboot after delay. */
|
||||||
|
_failed_loop:
|
||||||
|
jmp _failed_loop
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
_print_str:
|
||||||
|
/* cx = count, ds:si = string. */
|
||||||
|
movw $0x0007,%bx
|
||||||
|
movb $0x0e,%ah
|
||||||
|
_print_loop:
|
||||||
|
lodsb
|
||||||
|
int $0x10
|
||||||
|
loop _print_loop
|
||||||
|
ret
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
_print_char:
|
||||||
|
/* al = char. */
|
||||||
|
movw $0x0007,%bx
|
||||||
|
movb $0x0e,%ah
|
||||||
|
int $0x10
|
||||||
|
ret
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
_print_nl:
|
||||||
|
/* - */
|
||||||
|
movb $0x0d,%al
|
||||||
|
call _print_char
|
||||||
|
movb $0x0a,%al
|
||||||
|
call _print_char
|
||||||
|
ret
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
_print_hex:
|
||||||
|
/* dx = value */
|
||||||
|
movb $0x0e,%ah /* write char, tty mode */
|
||||||
|
movw $0x0007,%bx /* page 0, attribute 7 (normal) */
|
||||||
|
call _print_digit
|
||||||
|
call _print_digit
|
||||||
|
call _print_digit
|
||||||
|
/* fall through */
|
||||||
|
_print_digit:
|
||||||
|
rolw $4,%dx /* rotate so that lowest 4 bits are used */
|
||||||
|
movb $0x0f,%al /* mask for nibble */
|
||||||
|
andb %dl,%al
|
||||||
|
addb $0x90,%al /* convert al to ascii hex (four instructions) */
|
||||||
|
daa
|
||||||
|
adcb $0x40,%al
|
||||||
|
daa
|
||||||
|
int $0x10
|
||||||
|
ret
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
_go:
|
||||||
|
cli
|
||||||
|
movw $BOOTSEG,%ax
|
||||||
|
movw %ax,%ds
|
||||||
|
movw %ax,%ss
|
||||||
|
movw $0x2000,%sp /* good large stack. */
|
||||||
|
sti
|
||||||
|
cld
|
||||||
|
movw $LOADSEG,%ax
|
||||||
|
movw %ax,%es
|
||||||
|
|
||||||
|
movw $_load_msg_end-_load_msg,%cx
|
||||||
|
movw $_load_msg,%si
|
||||||
|
call _print_str
|
||||||
|
|
||||||
|
/*--- load MBR so we can use its partition table. ---*/
|
||||||
|
xorw %bx,%bx
|
||||||
|
movw $0x0001,%cx /* chs: 0,0,1 */
|
||||||
|
movb %bh,%dh /* - */
|
||||||
|
movb $0x80,%dl
|
||||||
|
movw $0x0201,%ax /* read one sector (MBR) */
|
||||||
|
int $0x13
|
||||||
|
jc _failed
|
||||||
|
|
||||||
|
/*--- find the active partition ---*/
|
||||||
|
movw $_part_msg_end-_part_msg,%cx
|
||||||
|
movw $_part_msg,%si
|
||||||
|
call _print_str
|
||||||
|
|
||||||
|
movw $partition_table,%di
|
||||||
|
movw $4,%cx
|
||||||
|
_partition_loop:
|
||||||
|
cmpb $0x80,%es:(%di) /* active? */
|
||||||
|
je _partition_found
|
||||||
|
addw $partition_rec_size,%di
|
||||||
|
loop _partition_loop
|
||||||
|
|
||||||
|
/*- no partitions marked active - use 1. partition. */
|
||||||
|
movw $partition_table,%di
|
||||||
|
movw $4,%cx
|
||||||
|
|
||||||
|
_partition_found:
|
||||||
|
movb $'5',%al /* convert to ascii */
|
||||||
|
subb %cl,%al
|
||||||
|
call _print_char
|
||||||
|
call _print_nl
|
||||||
|
|
||||||
|
/*--- check for lba support ---*/
|
||||||
|
movw $0x55aa,%bx
|
||||||
|
movb $0x80,%dl
|
||||||
|
movb $0x41,%ah
|
||||||
|
int $0x13
|
||||||
|
jc __bios
|
||||||
|
cmpw $0x0aa55,%bx
|
||||||
|
jnz __bios
|
||||||
|
testb $1,%cl
|
||||||
|
jz __bios
|
||||||
|
|
||||||
|
/*--- use lba bios calls to read sectors ---*/
|
||||||
|
_lba:
|
||||||
|
movw $_extbios_msg_end-_extbios_msg,%cx
|
||||||
|
movw $_extbios_msg,%si
|
||||||
|
call _print_str
|
||||||
|
|
||||||
|
movw %es:nsect(%di),%ax
|
||||||
|
movw %ax,_bios_lba_low
|
||||||
|
movw %es:nsect+2(%di),%ax
|
||||||
|
movw %ax,_bios_lba_high
|
||||||
|
movb $0x80,%dl
|
||||||
|
movw $_disk_address_packet,%si
|
||||||
|
movw $0x4200,%ax /* read */
|
||||||
|
int $0x13
|
||||||
|
jc _failed
|
||||||
|
jmp __loaded
|
||||||
|
|
||||||
|
/*--- use standard bios calls to read sectors ---*/
|
||||||
|
__bios:
|
||||||
|
movw $_stdbios_msg_end-_stdbios_msg,%cx
|
||||||
|
movw $_stdbios_msg,%si
|
||||||
|
call _print_str
|
||||||
|
|
||||||
|
movw _disk_address_packet+2(,1),%ax /* only low byte is used. */
|
||||||
|
xorw %bx,%bx
|
||||||
|
movw %es:start_sector(%di),%cx
|
||||||
|
movb %es:start_head(%di),%dh
|
||||||
|
movb $0x80,%dl
|
||||||
|
movb $0x02,%ah
|
||||||
|
int $0x13
|
||||||
|
jc _failed
|
||||||
|
|
||||||
|
__loaded:
|
||||||
|
movw $_boot_msg_end-_boot_msg,%cx
|
||||||
|
movw $_boot_msg,%si
|
||||||
|
call _print_str
|
||||||
|
|
||||||
|
/* check if it has a valid bootrecord. */
|
||||||
|
cmpw $BOOTMAGIC,%es:510(,1)
|
||||||
|
jne _failed
|
||||||
|
call _print_nl
|
||||||
|
|
||||||
|
/* call the payload. */
|
||||||
|
pushl $0 /* No parameters to preserve for exit path */
|
||||||
|
pushw $0 /* Use prefix exit path mechanism */
|
||||||
|
jmp $LOADSEG,$ENTRYPOINT
|
||||||
|
|
||||||
|
.section ".text16", "ax", @progbits
|
||||||
|
.globl prefix_exit
|
||||||
|
prefix_exit:
|
||||||
|
int $0x19 /* should try to boot machine */
|
||||||
|
.globl prefix_exit_end
|
||||||
|
prefix_exit_end:
|
||||||
|
.previous
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
_load_msg: .ascii "Loading "
|
||||||
|
_load_msg_end:
|
||||||
|
_part_msg: .ascii "partition "
|
||||||
|
_part_msg_end:
|
||||||
|
_boot_msg: .ascii "Booting..."
|
||||||
|
_boot_msg_end:
|
||||||
|
_stdbios_msg: .ascii "Std. BIOS\r\n"
|
||||||
|
_stdbios_msg_end:
|
||||||
|
_extbios_msg: .ascii "Ext. BIOS\r\n"
|
||||||
|
_extbios_msg_end:
|
||||||
|
_failed_msg: .ascii "FAILED!!!\r\n"
|
||||||
|
_failed_msg_end:
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
_disk_address_packet:
|
||||||
|
.byte 0x10 /* size of the packet */
|
||||||
|
.byte 0 /* reserved */
|
||||||
|
.word _verbatim_size_sct /* number of sectors to read */
|
||||||
|
.word 0x0000 /* offset */
|
||||||
|
.word LOADSEG /* segment of buffer */
|
||||||
|
_bios_lba_low: .word 0
|
||||||
|
_bios_lba_high: .word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
.rept 32
|
||||||
|
.byte 0
|
||||||
|
.endr
|
||||||
|
|
||||||
|
|
||||||
|
/*--- Partition table ------------------------------------------*/
|
||||||
|
|
||||||
|
.org 446, 0
|
||||||
|
.rept 64
|
||||||
|
.byte 0
|
||||||
|
.endr
|
||||||
|
|
||||||
|
|
||||||
|
/*--- Magic code -----------------------------------------------*/
|
||||||
|
.org 510, 0
|
||||||
|
.word BOOTMAGIC
|
||||||
|
|
||||||
|
/*** END ********************************************************/
|
|
@ -898,7 +898,7 @@ struct Elf_Bhdr *prepare_boot_params(void *header)
|
||||||
notes.nf1.n_descsz = sizeof(notes.nf1_bootp_data);
|
notes.nf1.n_descsz = sizeof(notes.nf1_bootp_data);
|
||||||
notes.nf1.n_type = EB_BOOTP_DATA;
|
notes.nf1.n_type = EB_BOOTP_DATA;
|
||||||
CP(notes.nf1_name, EB_PARAM_NOTE);
|
CP(notes.nf1_name, EB_PARAM_NOTE);
|
||||||
notes.nf1_bootp_data = virt_to_phys(BOOTP_DATA_ADDR);
|
notes.nf1_bootp_data = virt_to_phys(&bootp_data);
|
||||||
|
|
||||||
notes.nf2.n_namesz = sizeof(EB_PARAM_NOTE);
|
notes.nf2.n_namesz = sizeof(EB_PARAM_NOTE);
|
||||||
notes.nf2.n_descsz = sizeof(notes.nf2_header);
|
notes.nf2.n_descsz = sizeof(notes.nf2_header);
|
||||||
|
|
|
@ -199,7 +199,6 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
printf("(ELF");
|
printf("(ELF");
|
||||||
elf_freebsd_probe();
|
elf_freebsd_probe();
|
||||||
multiboot_probe(data, len);
|
|
||||||
printf(")... ");
|
printf(")... ");
|
||||||
phdr_size = estate.e.elf32.e_phnum * estate.e.elf32.e_phentsize;
|
phdr_size = estate.e.elf32.e_phnum * estate.e.elf32.e_phentsize;
|
||||||
if (estate.e.elf32.e_phoff + phdr_size > len) {
|
if (estate.e.elf32.e_phoff + phdr_size > len) {
|
||||||
|
@ -207,7 +206,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
|
||||||
return dead_download;
|
return dead_download;
|
||||||
}
|
}
|
||||||
if (phdr_size > sizeof(estate.p.dummy)) {
|
if (phdr_size > sizeof(estate.p.dummy)) {
|
||||||
printf("Program header to big\n");
|
printf("Program header too big\n");
|
||||||
return dead_download;
|
return dead_download;
|
||||||
}
|
}
|
||||||
memcpy(&estate.p.phdr32, data + estate.e.elf32.e_phoff, phdr_size);
|
memcpy(&estate.p.phdr32, data + estate.e.elf32.e_phoff, phdr_size);
|
||||||
|
@ -251,6 +250,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
#if ELF_NOTES
|
#if ELF_NOTES
|
||||||
/* Load ELF notes from the image */
|
/* Load ELF notes from the image */
|
||||||
|
estate.check_ip_checksum = 0;
|
||||||
for(estate.segment = 0; estate.segment < estate.e.elf32.e_phnum; estate.segment++) {
|
for(estate.segment = 0; estate.segment < estate.e.elf32.e_phnum; estate.segment++) {
|
||||||
if (estate.p.phdr32[estate.segment].p_type != PT_NOTE)
|
if (estate.p.phdr32[estate.segment].p_type != PT_NOTE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -289,6 +289,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
|
||||||
estate.loc = 0;
|
estate.loc = 0;
|
||||||
estate.skip = 0;
|
estate.skip = 0;
|
||||||
estate.toread = 0;
|
estate.toread = 0;
|
||||||
|
multiboot_init();
|
||||||
return elf32_download;
|
return elf32_download;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,6 +517,7 @@ static inline os_download_t elf64_probe(unsigned char *data, unsigned int len)
|
||||||
}
|
}
|
||||||
#if ELF_NOTES
|
#if ELF_NOTES
|
||||||
/* Load ELF notes from the image */
|
/* Load ELF notes from the image */
|
||||||
|
estate.check_ip_checksum = 0;
|
||||||
for(estate.segment = 0; estate.segment < estate.e.elf64.e_phnum; estate.segment++) {
|
for(estate.segment = 0; estate.segment < estate.e.elf64.e_phnum; estate.segment++) {
|
||||||
if (estate.p.phdr64[estate.segment].p_type != PT_NOTE)
|
if (estate.p.phdr64[estate.segment].p_type != PT_NOTE)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -259,7 +259,8 @@ unsigned long pci_bar_start ( struct pci_device *pci, unsigned int index ) {
|
||||||
bar = hi;
|
bar = hi;
|
||||||
bar <<= 32;
|
bar <<= 32;
|
||||||
#else
|
#else
|
||||||
printf ( "Unhandled 64bit BAR\n" );
|
printf ( "Unhandled 64bit BAR %08x:%08x\n",
|
||||||
|
hi, lo );
|
||||||
return -1UL;
|
return -1UL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue