summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/Makefile4
-rw-r--r--src/arch/i386/prefix/hdprefix.S296
-rw-r--r--src/arch/ia64/core/efi.c2
-rw-r--r--src/core/elf_loader.c6
-rw-r--r--src/drivers/bus/pci.c9
5 files changed, 310 insertions, 7 deletions
diff --git a/src/arch/i386/Makefile b/src/arch/i386/Makefile
index 0c258ae81..94b85c807 100644
--- a/src/arch/i386/Makefile
+++ b/src/arch/i386/Makefile
@@ -82,6 +82,10 @@ MEDIA += dsk
OBJS_dskprefix = dskprefix zdskprefix
CFLAGS_zdskprefix = $(CFLAGS_ZPREFIX)
+MEDIA += hd
+OBJS_hdprefix = hdprefix zhdprefix
+CFLAGS_zhdprefix = $(CFLAGS_ZPREFIX)
+
MEDIA += raw
OBJS_rawprefix = rawprefix zrawprefix
CFLAGS_zrawprefix = $(CFLAGS_ZPREFIX)
diff --git a/src/arch/i386/prefix/hdprefix.S b/src/arch/i386/prefix/hdprefix.S
new file mode 100644
index 000000000..38e62bc3c
--- /dev/null
+++ b/src/arch/i386/prefix/hdprefix.S
@@ -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 ********************************************************/
diff --git a/src/arch/ia64/core/efi.c b/src/arch/ia64/core/efi.c
index 97e585fc8..2da768557 100644
--- a/src/arch/ia64/core/efi.c
+++ b/src/arch/ia64/core/efi.c
@@ -898,7 +898,7 @@ struct Elf_Bhdr *prepare_boot_params(void *header)
notes.nf1.n_descsz = sizeof(notes.nf1_bootp_data);
notes.nf1.n_type = EB_BOOTP_DATA;
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_descsz = sizeof(notes.nf2_header);
diff --git a/src/core/elf_loader.c b/src/core/elf_loader.c
index 88a2975ef..85b60e8a3 100644
--- a/src/core/elf_loader.c
+++ b/src/core/elf_loader.c
@@ -199,7 +199,6 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
}
printf("(ELF");
elf_freebsd_probe();
- multiboot_probe(data, len);
printf(")... ");
phdr_size = estate.e.elf32.e_phnum * estate.e.elf32.e_phentsize;
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;
}
if (phdr_size > sizeof(estate.p.dummy)) {
- printf("Program header to big\n");
+ printf("Program header too big\n");
return dead_download;
}
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
/* Load ELF notes from the image */
+ estate.check_ip_checksum = 0;
for(estate.segment = 0; estate.segment < estate.e.elf32.e_phnum; estate.segment++) {
if (estate.p.phdr32[estate.segment].p_type != PT_NOTE)
continue;
@@ -289,6 +289,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
estate.loc = 0;
estate.skip = 0;
estate.toread = 0;
+ multiboot_init();
return elf32_download;
}
@@ -516,6 +517,7 @@ static inline os_download_t elf64_probe(unsigned char *data, unsigned int len)
}
#if ELF_NOTES
/* Load ELF notes from the image */
+ estate.check_ip_checksum = 0;
for(estate.segment = 0; estate.segment < estate.e.elf64.e_phnum; estate.segment++) {
if (estate.p.phdr64[estate.segment].p_type != PT_NOTE)
continue;
diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c
index 95a76502b..02286b7cf 100644
--- a/src/drivers/bus/pci.c
+++ b/src/drivers/bus/pci.c
@@ -256,11 +256,12 @@ unsigned long pci_bar_start ( struct pci_device *pci, unsigned int index ) {
pci_read_config_dword ( pci, index + 4, &hi );
if ( hi ) {
#if ULONG_MAX > 0xffffffff
- bar = hi;
- bar <<= 32;
+ bar = hi;
+ bar <<= 32;
#else
- printf ( "Unhandled 64bit BAR\n" );
- return -1UL;
+ printf ( "Unhandled 64bit BAR %08x:%08x\n",
+ hi, lo );
+ return -1UL;
#endif
}
}