From bba600dda0ea8a76d875db7308f372bfc43f8506 Mon Sep 17 00:00:00 2001 From: Apple <opensource@apple.com> Date: Tue, 24 Oct 2006 16:22:19 +0000 Subject: [PATCH] boot-132.tar.gz --- i386/boot1u/Makefile | 8 +- i386/boot1u/string.c | 4 +- i386/boot2/Makefile | 9 +- i386/boot2/WKdm.h | 227 +++++++++++++++ i386/boot2/WKdmDecompress.c | 285 ++++++++++++++++++ i386/boot2/boot.c | 90 +++--- i386/boot2/boot.h | 12 +- i386/boot2/drivers.c | 79 ++--- i386/boot2/graphics.c | 84 ++++-- i386/boot2/options.c | 278 +++++++++++++----- i386/cdboot/cdboot.s | 2 +- i386/libsa/Makefile | 5 +- i386/libsa/memory.h | 8 +- i386/libsa/string.c | 10 +- i386/libsa/zalloc.c | 4 +- i386/libsaio/Makefile | 12 +- i386/libsaio/asm.s | 5 +- i386/libsaio/bios.h | 24 ++ i386/libsaio/biosfn.c | 33 ++- i386/libsaio/bootstruct.c | 174 ++++++----- i386/libsaio/bootstruct.h | 85 +++++- i386/libsaio/cache.c | 4 +- i386/libsaio/console.c | 12 +- i386/libsaio/device_tree.c | 539 +++++++++++++++++++++++++++++++++++ i386/libsaio/device_tree.h | 61 ++++ i386/libsaio/disk.c | 58 ++-- i386/libsaio/hfs.c | 41 ++- i386/libsaio/hfs.h | 1 + i386/libsaio/hfs_compare.c | 2 +- i386/libsaio/load.c | 2 +- i386/libsaio/md5c.c | 344 ++++++++++++++++++++++ i386/libsaio/memory.c | 24 ++ i386/libsaio/misc.c | 44 +++ i386/libsaio/msdos.c | 12 +- i386/libsaio/nbp.c | 2 +- i386/libsaio/ntfs.c | 8 +- i386/libsaio/saio_internal.h | 10 +- i386/libsaio/saio_types.h | 55 ++++ i386/libsaio/stringTable.c | 21 +- i386/libsaio/sys.c | 90 +++++- i386/libsaio/ufs.c | 46 ++- i386/libsaio/ufs.h | 1 + i386/libsaio/ufs_byteorder.c | 18 +- i386/libsaio/ufs_byteorder.h | 5 +- i386/libsaio/vbe.h | 2 +- i386/nasm/Makefile | 2 +- i386/rcz/Makefile | 2 +- i386/strings/BootHelp.txt | 6 +- i386/strings/Makefile | 2 +- i386/testmodule/Makefile | 2 +- i386/util/Makefile | 2 +- 51 files changed, 2443 insertions(+), 413 deletions(-) create mode 100644 i386/boot2/WKdm.h create mode 100644 i386/boot2/WKdmDecompress.c create mode 100644 i386/libsaio/device_tree.c create mode 100644 i386/libsaio/device_tree.h create mode 100644 i386/libsaio/md5c.c diff --git a/i386/boot1u/Makefile b/i386/boot1u/Makefile index 0f479ca..36fcd03 100644 --- a/i386/boot1u/Makefile +++ b/i386/boot1u/Makefile @@ -1,11 +1,11 @@ DIR = boot1u include ../MakePaths.dir -OPTIM = -Os +OPTIM = -Os -Oz CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \ -fno-builtin -DSAIO_INTERNAL_USER -DBOOT1 -static \ -fomit-frame-pointer -mpreferred-stack-boundary=2 \ - -fno-align-functions + -fno-align-functions -mno-sse2 -mfpmath=387 DEFINES= CONFIG = hd SYMDIR = $(SYMROOT) @@ -19,7 +19,7 @@ else MKDIRS = /bin/mkdir -p endif AS = as -LD = ld +LD = gcc LIBS= -L$(SYMDIR) -lsa #LIBS= -L$(SYMDIR) @@ -71,7 +71,7 @@ boot1u0: boot1u0.s Makefile $(NASM) $(NASM) boot1u0.s -o $(SYMROOT)/$@ boot1u: $(SYMROOT)/machOconv boot1u0 $(OBJS) - $(LD) -static -preload -segaddr __TEXT $(BOOT1UADDR) -segalign 20 \ + $(LD) -arch i386 -fno-builtin -static -Wl,-preload -Wl,-segaddr,__TEXT,$(BOOT1UADDR) -nostdlib -Wl,-segalign,20 \ -o $(SYMROOT)/$(@F).sys $(filter %.o,$^) $(LIBS) -lcc_kext size $(SYMROOT)/$(@F).sys $(SYMROOT)/machOconv $(SYMROOT)/$(@F).sys $(SYMROOT)/$(@F).post diff --git a/i386/boot1u/string.c b/i386/boot1u/string.c index 91e1791..4abdb72 100644 --- a/i386/boot1u/string.c +++ b/i386/boot1u/string.c @@ -27,7 +27,7 @@ void * memset(void * dst, int val, size_t len) { - asm( "rep; stosb" + asm volatile ( "rep; stosb" : "=c" (len), "=D" (dst) : "0" (len), "1" (dst), "a" (val) : "memory" ); @@ -37,7 +37,7 @@ void * memset(void * dst, int val, size_t len) void * memcpy(void * dst, const void * src, size_t len) { - asm( "rep; movsb" + asm volatile ( "rep; movsb" : "=c" (len), "=D" (dst), "=S" (src) : "0" (len), "1" (dst), "2" (src) : "memory" ); diff --git a/i386/boot2/Makefile b/i386/boot2/Makefile index 4aa84de..48d3c67 100644 --- a/i386/boot2/Makefile +++ b/i386/boot2/Makefile @@ -5,11 +5,11 @@ DIR = boot2 include ../MakePaths.dir -OPTIM = -Os +OPTIM = -Os -Oz CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \ -fno-builtin -DSAIO_INTERNAL_USER -static \ -fomit-frame-pointer -mpreferred-stack-boundary=2 \ - -fno-align-functions + -fno-align-functions -mno-sse2 -mfpmath=387 DEFINES= CONFIG = hd SYMDIR = $(SYMROOT) @@ -23,7 +23,7 @@ else MKDIRS = /bin/mkdir -p endif AS = as -LD = ld +LD = gcc # LIBS= -lc_static LIBS= -L$(SYMDIR) -lsaio -lsa LIBDEP= $(SYMDIR)/libsaio.a $(SYMDIR)/libsa.a @@ -52,7 +52,8 @@ MAXBOOTSIZE = 65024 all: $(DIRS_NEEDED) boot boot: machOconv $(OBJS) $(LIBDEP) - $(LD) -static -preload -segaddr __TEXT $(BOOT2ADDR) -segalign 20 \ + $(LD) -static -Wl,-preload -Wl,-segaddr,__TEXT,$(BOOT2ADDR) \ + -nostdlib -arch i386 -Wl,-segalign,20 \ -o $(SYMROOT)/boot.sys $(filter %.o,$^) $(LIBS) -lcc_kext machOconv $(SYMROOT)/boot.sys $(SYMROOT)/boot size $(SYMROOT)/boot.sys diff --git a/i386/boot2/WKdm.h b/i386/boot2/WKdm.h new file mode 100644 index 0000000..be3ca2d --- /dev/null +++ b/i386/boot2/WKdm.h @@ -0,0 +1,227 @@ +/* direct-mapped partial matching compressor with simple 22/10 split + * + * Compresses buffers using a dictionary based match and partial match + * (high bits only or full match) scheme. + * + * Paul Wilson -- wilson@cs.utexas.edu + * Scott F. Kaplan -- sfkaplan@cs.utexas.edu + * September 1997 + */ + +/* compressed output format, in memory order + * 1. a four-word HEADER containing four one-word values: + * i. a one-word code saying what algorithm compressed the data + * ii. an integer WORD offset into the page saying + * where the queue position area starts + * iii. an integer WORD offset into the page saying where + * the low-bits area starts + * iv. an integer WORD offset into the page saying where the + * low-bits area ends + * + * 2. a 64-word TAGS AREA holding one two-bit tag for each word in + * the original (1024-word) page, packed 16 per word + * + * 3. a variable-sized FULL WORDS AREA (always word aligned and an + * integral number of words) holding full-word patterns that + * were not in the dictionary when encoded (i.e., dictionary misses) + * + * 4. a variable-sized QUEUE POSITIONS AREA (always word aligned and + * an integral number of words) holding four-bit queue positions, + * packed eight per word. + * + * 5. a variable-sized LOW BITS AREA (always word aligned and an + * integral number of words) holding ten-bit low-bit patterns + * (from partial matches), packed three per word. + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* ============================================================ */ +/* Included files */ + +//#include <stdio.h> +//#include <unistd.h> +//#include <math.h> +//#include <strings.h> + +typedef unsigned long WK_word; + +/* at the moment we have dependencies on the page size. That should + * be changed to work for any power-of-two size that's at least 16 + * words, or something like that + */ + +#define PAGE_SIZE_IN_WORDS 1024 +#define PAGE_SIZE_IN_BYTES 4096 + +#define DICTIONARY_SIZE 16 + +/* + * macros defining the basic layout of stuff in a page + */ +#define HEADER_SIZE_IN_WORDS 4 +#define TAGS_AREA_OFFSET 4 +#define TAGS_AREA_SIZE 64 + +/* the next few are used during compression to write the header */ +#define SET_QPOS_AREA_START(compr_dest_buf,qpos_start_addr) \ + (compr_dest_buf[1] = qpos_start_addr - compr_dest_buf) +#define SET_LOW_BITS_AREA_START(compr_dest_buf,lb_start_addr) \ + (compr_dest_buf[2] = lb_start_addr - compr_dest_buf) +#define SET_LOW_BITS_AREA_END(compr_dest_buf,lb_end_addr) \ + (compr_dest_buf[3] = lb_end_addr - compr_dest_buf) + +/* the next few are only use during decompression to read the header */ +#define TAGS_AREA_START(decomp_src_buf) \ + (decomp_src_buf + TAGS_AREA_OFFSET) +#define TAGS_AREA_END(decomp_src_buf) \ + (TAGS_AREA_START(decomp_src_buf) + TAGS_AREA_SIZE) +#define FULL_WORD_AREA_START(the_buf) TAGS_AREA_END(the_buf) +#define QPOS_AREA_START(decomp_src_buf) \ + (decomp_src_buf + decomp_src_buf[1]) +#define LOW_BITS_AREA_START(decomp_src_buf) \ + (decomp_src_buf + (decomp_src_buf[2])) +#define QPOS_AREA_END(the_buf) LOW_BITS_AREA_START(the_buf) +#define LOW_BITS_AREA_END(decomp_src_buf) \ + (decomp_src_buf + (decomp_src_buf[3])) + +/* ============================================================ */ +/* Types and structures */ + +/* A structure to store each element of the dictionary. */ +typedef WK_word DictionaryElement; + +/* ============================================================ */ +/* Misc constants */ + +#define BITS_PER_WORD 32 +#define BYTES_PER_WORD 4 +#define NUM_LOW_BITS 10 +#define LOW_BITS_MASK 0x3FF +#define ALL_ONES_MASK 0xFFFFFFFF + +#define TWO_BITS_PACKING_MASK 0x03030303 +#define FOUR_BITS_PACKING_MASK 0x0F0F0F0F +#define TEN_LOW_BITS_MASK 0x000003FF +#define TWENTY_TWO_HIGH_BITS_MASK 0xFFFFFC00 + +/* Tag values. NOTE THAT CODE MAY DEPEND ON THE NUMBERS USED. + * Check for conditionals doing arithmetic on these things + * before changing them + */ +#define ZERO_TAG 0x0 +#define PARTIAL_TAG 0x1 +#define MISS_TAG 0x2 +#define EXACT_TAG 0x3 + +#define BITS_PER_BYTE 8 + +/* ============================================================ */ +/* Global macros */ + +/* Shift out the low bits of a pattern to give the high bits pattern. + The stripped patterns are used for initial tests of partial + matches. */ +#define HIGH_BITS(word_pattern) (word_pattern >> NUM_LOW_BITS) + +/* String the high bits of a pattern so the low order bits can + be included in an encoding of a partial match. */ +#define LOW_BITS(word_pattern) (word_pattern & LOW_BITS_MASK) + +#if defined DEBUG_WK +#define DEBUG_PRINT_1(string) printf (string) +#define DEBUG_PRINT_2(string,value) printf(string, value) +#else +#define DEBUG_PRINT_1(string) +#define DEBUG_PRINT_2(string, value) +#endif + +/* Set up the dictionary before performing compression or + decompression. Each element is loaded with some value, the + high-bits version of that value, and a next pointer. */ +#define PRELOAD_DICTIONARY { \ + dictionary[0] = 1; \ + dictionary[1] = 1; \ + dictionary[2] = 1; \ + dictionary[3] = 1; \ + dictionary[4] = 1; \ + dictionary[5] = 1; \ + dictionary[6] = 1; \ + dictionary[7] = 1; \ + dictionary[8] = 1; \ + dictionary[9] = 1; \ + dictionary[10] = 1; \ + dictionary[11] = 1; \ + dictionary[12] = 1; \ + dictionary[13] = 1; \ + dictionary[14] = 1; \ + dictionary[15] = 1; \ +} + +/* these are the constants for the hash function lookup table. + * Only zero maps to zero. The rest of the tabale is the result + * of appending 17 randomizations of the multiples of 4 from + * 4 to 56. Generated by a Scheme script in hash.scm. + */ +#define HASH_LOOKUP_TABLE_CONTENTS { \ + 0, 52, 8, 56, 16, 12, 28, 20, 4, 36, 48, 24, 44, 40, 32, 60, \ + 8, 12, 28, 20, 4, 60, 16, 36, 24, 48, 44, 32, 52, 56, 40, 12, \ + 8, 48, 16, 52, 60, 28, 56, 32, 20, 24, 36, 40, 44, 4, 8, 40, \ + 60, 32, 20, 44, 4, 36, 52, 24, 16, 56, 48, 12, 28, 16, 8, 40, \ + 36, 28, 32, 12, 4, 44, 52, 20, 24, 48, 60, 56, 40, 48, 8, 32, \ + 28, 36, 4, 44, 20, 56, 60, 24, 52, 16, 12, 12, 4, 48, 20, 8, \ + 52, 16, 60, 24, 36, 44, 28, 56, 40, 32, 36, 20, 24, 60, 40, 44, \ + 52, 16, 32, 4, 48, 8, 28, 56, 12, 28, 32, 40, 52, 36, 16, 20, \ + 48, 8, 4, 60, 24, 56, 44, 12, 8, 36, 24, 28, 16, 60, 20, 56, \ + 32, 40, 48, 12, 4, 44, 52, 44, 40, 12, 56, 8, 36, 24, 60, 28, \ + 48, 4, 32, 20, 16, 52, 60, 12, 24, 36, 8, 4, 16, 56, 48, 44, \ + 40, 52, 32, 20, 28, 32, 12, 36, 28, 24, 56, 40, 16, 52, 44, 4, \ + 20, 60, 8, 48, 48, 52, 12, 20, 32, 44, 36, 28, 4, 40, 24, 8, \ + 56, 60, 16, 36, 32, 8, 40, 4, 52, 24, 44, 20, 12, 28, 48, 56, \ + 16, 60, 4, 52, 60, 48, 20, 16, 56, 44, 24, 8, 40, 12, 32, 28, \ + 36, 24, 32, 12, 4, 20, 16, 60, 36, 28, 8, 52, 40, 48, 44, 56 \ +} + +#define HASH_TO_DICT_BYTE_OFFSET(pattern) \ + (hashLookupTable[((pattern) >> 10) & 0xFF]) + +extern const char hashLookupTable[]; + +/* EMIT... macros emit bytes or words into the intermediate arrays + */ + +#define EMIT_BYTE(fill_ptr, byte_value) {*fill_ptr = byte_value; fill_ptr++;} +#define EMIT_WORD(fill_ptr,word_value) {*fill_ptr = word_value; fill_ptr++;} + +/* RECORD... macros record the results of modeling in the intermediate + * arrays + */ + +#define RECORD_ZERO { EMIT_BYTE(next_tag,ZERO_TAG); } + +#define RECORD_EXACT(queue_posn) EMIT_BYTE(next_tag,EXACT_TAG); \ + EMIT_BYTE(next_qp,(queue_posn)); + +#define RECORD_PARTIAL(queue_posn,low_bits_pattern) { \ + EMIT_BYTE(next_tag,PARTIAL_TAG); \ + EMIT_BYTE(next_qp,(queue_posn)); \ + EMIT_WORD(next_low_bits,(low_bits_pattern)) } + +#define RECORD_MISS(word_pattern) EMIT_BYTE(next_tag,MISS_TAG); \ + EMIT_WORD(next_full_patt,(word_pattern)); + +void +WKdm_decompress (WK_word* src_buf, + WK_word* dest_buf, + unsigned int words); +unsigned int +WKdm_compress (WK_word* src_buf, + WK_word* dest_buf, + unsigned int num_input_words); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/i386/boot2/WKdmDecompress.c b/i386/boot2/WKdmDecompress.c new file mode 100644 index 0000000..fd230ca --- /dev/null +++ b/i386/boot2/WKdmDecompress.c @@ -0,0 +1,285 @@ +#include <sys/cdefs.h> +#include "WKdm.h" + +/* Part of __HIB section */ + +/*************************************************************************** + * THE UNPACKING ROUTINES should GO HERE + */ + +const char hashLookupTable [] = HASH_LOOKUP_TABLE_CONTENTS; + +#if 0 +#define GET_NEXT_TAG tags[tagsIndex++] +#define GET_NEXT_FULL_PATTERN fullPatterns[fullPatternsIndex++] +#define GET_NEXT_LOW_BITS lowBits[lowBitsIndex++] +#define GET_NEXT_DICTIONARY_INDEX dictionaryIndices[dictionaryIndicesIndex++] +#endif + +/* WK_unpack_2bits takes any number of words containing 16 two-bit values + * and unpacks them into four times as many words containg those + * two bit values as bytes (with the low two bits of each byte holding + * the actual value. + */ +static WK_word* +WK_unpack_2bits(WK_word *input_buf, + WK_word *input_end, + WK_word *output_buf) { + + register WK_word *input_next = input_buf; + register WK_word *output_next = output_buf; + register WK_word packing_mask = TWO_BITS_PACKING_MASK; + + /* loop to repeatedly grab one input word and unpack it into + * 4 output words. This loop could be unrolled a little---it's + * designed to be easy to do that. + */ + while (input_next < input_end) { + register WK_word temp = input_next[0]; + DEBUG_PRINT_2("Unpacked tags word: %.8x\n", temp); + output_next[0] = temp & packing_mask; + output_next[1] = (temp >> 2) & packing_mask; + output_next[2] = (temp >> 4) & packing_mask; + output_next[3] = (temp >> 6) & packing_mask; + + output_next += 4; + input_next++; + } + + return output_next; + +} + +/* unpack four bits consumes any number of words (between input_buf + * and input_end) holding 8 4-bit values per word, and unpacks them + * into twice as many words, with each value in a separate byte. + * (The four-bit values occupy the low halves of the bytes in the + * result). + */ +static WK_word* +WK_unpack_4bits(WK_word *input_buf, + WK_word *input_end, + WK_word *output_buf) { + + register WK_word *input_next = input_buf; + register WK_word *output_next = output_buf; + register WK_word packing_mask = FOUR_BITS_PACKING_MASK; + + + /* loop to repeatedly grab one input word and unpack it into + * 4 output words. This loop should probably be unrolled + * a little---it's designed to be easy to do that. + */ + while (input_next < input_end) { + register WK_word temp = input_next[0]; + DEBUG_PRINT_2("Unpacked dictionary indices word: %.8x\n", temp); + output_next[0] = temp & packing_mask; + output_next[1] = (temp >> 4) & packing_mask; + + output_next += 2; + input_next++; + } + + return output_next; + +} + +/* unpack_3_tenbits unpacks three 10-bit items from (the low 30 bits of) + * a 32-bit word + */ +static WK_word* +WK_unpack_3_tenbits(WK_word *input_buf, + WK_word *input_end, + WK_word *output_buf) { + + register WK_word *input_next = input_buf; + register WK_word *output_next = output_buf; + register WK_word packing_mask = LOW_BITS_MASK; + + /* loop to fetch words of input, splitting each into three + * words of output with 10 meaningful low bits. This loop + * probably ought to be unrolled and maybe coiled + */ + while (input_next < input_end) { + register WK_word temp = input_next[0]; + + output_next[0] = temp & packing_mask; + output_next[1] = (temp >> 10) & packing_mask; + output_next[2] = temp >> 20; + + input_next++; + output_next += 3; + } + + return output_next; + +} + +/********************************************************************* + * WKdm_decompress --- THE DECOMPRESSOR + * Expects WORD pointers to the source and destination buffers + * and a page size in words. The page size had better be 1024 unless + * somebody finds the places that are dependent on the page size and + * fixes them + */ + +void +WKdm_decompress (WK_word* src_buf, + WK_word* dest_buf, + __unused unsigned int words) +{ + + DictionaryElement dictionary[DICTIONARY_SIZE]; + + /* arrays that hold output data in intermediate form during modeling */ + /* and whose contents are packed into the actual output after modeling */ + + /* sizes of these arrays should be increased if you want to compress + * pages larger than 4KB + */ + WK_word tempTagsArray[300]; /* tags for everything */ + WK_word tempQPosArray[300]; /* queue positions for matches */ + WK_word tempLowBitsArray[1200]; /* low bits for partial matches */ + + PRELOAD_DICTIONARY; + +#ifdef WK_DEBUG + printf("\nIn DECOMPRESSOR\n"); + printf("tempTagsArray is at %u\n", (unsigned long int) tempTagsArray); + printf("tempQPosArray is at %u\n", (unsigned long int) tempQPosArray); + printf("tempLowBitsArray is at %u\n", (unsigned long int) tempLowBitsArray); + + printf(" first four words of source buffer are:\n"); + printf(" %u\n %u\n %u\n %u\n", + src_buf[0], src_buf[1], src_buf[2], src_buf[3]); + + { int i; + WK_word *arr =(src_buf + TAGS_AREA_OFFSET + (PAGE_SIZE_IN_WORDS / 16)); + + printf(" first 20 full patterns are: \n"); + for (i = 0; i < 20; i++) { + printf(" %d", arr[i]); + } + printf("\n"); + } +#endif + + WK_unpack_2bits(TAGS_AREA_START(src_buf), + TAGS_AREA_END(src_buf), + tempTagsArray); + +#ifdef WK_DEBUG + { int i; + char* arr = (char *) tempTagsArray; + + printf(" first 200 tags are: \n"); + for (i = 0; i < 200; i++) { + printf(" %d", arr[i]); + } + printf("\n"); + } +#endif + + WK_unpack_4bits(QPOS_AREA_START(src_buf), + QPOS_AREA_END(src_buf), + tempQPosArray); + +#ifdef WK_DEBUG + { int i; + char* arr = (char *) tempQPosArray; + + printf(" first 200 queue positions are: \n"); + for (i = 0; i < 200; i++) { + printf(" %d", arr[i]); + } + printf("\n"); + } +#endif + + WK_unpack_3_tenbits(LOW_BITS_AREA_START(src_buf), + LOW_BITS_AREA_END(src_buf), + tempLowBitsArray); + +#ifdef WK_DEBUG + printf("AFTER UNPACKING, about to enter main block \n"); +#endif + + { + register char *next_tag = (char *) tempTagsArray; + char *tags_area_end = + ((char *) tempTagsArray) + PAGE_SIZE_IN_WORDS; + char *next_q_pos = (char *) tempQPosArray; + WK_word *next_low_bits = tempLowBitsArray; + WK_word *next_full_word = FULL_WORD_AREA_START(src_buf); + + WK_word *next_output = dest_buf; + +#ifdef WK_DEBUG + printf("next_output is %u\n", next_output); + + printf("next_tag is %u \n", next_tag); + printf("tags_area_end is %u\n", tags_area_end); + printf("next_q_pos is %u\n", next_q_pos); + printf("next_low_bits is %u\n", next_low_bits); + printf("next_full_word is %u\n", next_full_word); +#endif + + /* this loop should probably be unrolled. Maybe we should unpack + * as 4 bit values, giving two consecutive tags, and switch on + * that 16 ways to decompress 2 words at a whack + */ + while (next_tag < tags_area_end) { + + char tag = next_tag[0]; + + switch(tag) { + + case ZERO_TAG: { + *next_output = 0; + break; + } + case EXACT_TAG: { + WK_word *dict_location = dictionary + *(next_q_pos++); + /* no need to replace dict. entry if matched exactly */ + *next_output = *dict_location; + break; + } + case PARTIAL_TAG: { + WK_word *dict_location = dictionary + *(next_q_pos++); + { + WK_word temp = *dict_location; + + /* strip out low bits */ + temp = ((temp >> NUM_LOW_BITS) << NUM_LOW_BITS); + + /* add in stored low bits from temp array */ + temp = temp | *(next_low_bits++); + + *dict_location = temp; /* replace old value in dict. */ + *next_output = temp; /* and echo it to output */ + } + break; + } + case MISS_TAG: { + WK_word missed_word = *(next_full_word++); + WK_word *dict_location = + (WK_word *) + (((char *) dictionary) + HASH_TO_DICT_BYTE_OFFSET(missed_word)); + *dict_location = missed_word; + *next_output = missed_word; + break; + } + } + next_tag++; + next_output++; + } + +#ifdef WK_DEBUG + printf("AFTER DECOMPRESSING\n"); + printf("next_output is %u\n", (unsigned long int) next_output); + printf("next_tag is %u\n", (unsigned long int) next_tag); + printf("next_full_word is %u\n", (unsigned long int) next_full_word); + printf("next_q_pos is %u\n", (unsigned long int) next_q_pos); +#endif + } +} diff --git a/i386/boot2/boot.c b/i386/boot2/boot.c index 9bd0829..d935082 100644 --- a/i386/boot2/boot.c +++ b/i386/boot2/boot.c @@ -61,6 +61,7 @@ BOOL gOverrideKernel; static char gBootKernelCacheFile[512]; static char gCacheNameAdler[64 + 256]; char *gPlatformName = gCacheNameAdler; +char gRootDevice[512]; char gMKextName[512]; BVRef gBootVolume; @@ -103,7 +104,7 @@ static void malloc_error(char *addr, size_t size) { printf("\nMemory allocation error (0x%x, 0x%x)\n", (unsigned)addr, (unsigned)size); - asm("hlt"); + asm volatile ("hlt"); } //========================================================================== @@ -113,9 +114,6 @@ static int ExecKernel(void *binary) { entry_t kernelEntry; int ret; -#ifdef APM_SUPPORT - BOOL apm; -#endif /* APM_SUPPORT */ BOOL bootGraphics; bootArgs->kaddr = bootArgs->ksize = 0; @@ -123,7 +121,7 @@ static int ExecKernel(void *binary) ret = DecodeKernel(binary, &kernelEntry, (char **) &bootArgs->kaddr, - &bootArgs->ksize ); + (int *)&bootArgs->ksize ); if ( ret != 0 ) return ret; @@ -147,17 +145,6 @@ static int ExecKernel(void *binary) printf("Starting Darwin/x86"); - turnOffFloppy(); - -#ifdef APM_SUPPORT - // Connect to APM BIOS. - - if ( getBoolForKey("APM", &apm) && apm == YES ) - { - if ( APMPresent() ) APMConnect32(); - } -#endif /* APM_SUPPORT */ - // Cleanup the PXE base code. if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit ) { @@ -176,20 +163,24 @@ static int ExecKernel(void *binary) } if (bootGraphics) { - if (bootArgs->graphicsMode == TEXT_MODE) { + if (bootArgs->Video.v_display == VGA_TEXT_MODE) { // If we were in text mode, switch to graphics mode. - // This will draw the boot graphics. + // This will draw the boot graphics unless we are in + // verbose mode. setVideoMode( GRAPHICS_MODE ); } else { // If we were already in graphics mode, clear the screen. drawBootGraphics(); } } else { - if (bootArgs->graphicsMode == GRAPHICS_MODE) { - setVideoMode( TEXT_MODE ); - } + // Always set text mode to initialize video fields + // in the boot args structure. + setVideoMode( VGA_TEXT_MODE ); + setCursorType( kCursorTypeHidden ); } + finalizeBootStruct(); + // Jump to kernel's entry point. There's no going back now. startprog( kernelEntry, bootArgs ); @@ -207,13 +198,13 @@ static void scanHardware() extern int ReadPCIBusInfo(PCI_bus_info_t *); extern void PCI_Bus_Init(PCI_bus_info_t *); - ReadPCIBusInfo( &bootArgs->pciInfo ); + ReadPCIBusInfo( &bootInfo->pciInfo ); // // Initialize PCI matching support in the booter. // Not used, commented out to minimize code size. // - // PCI_Bus_Init( &bootArgs->pciInfo ); + // PCI_Bus_Init( &bootInfo->pciInfo ); } //========================================================================== @@ -242,7 +233,6 @@ void boot(int biosdev) zeroBSS(); // Initialize malloc - malloc_init(0, 0, 0, malloc_error); // Enable A20 gate before accessing memory above 1Mb. @@ -266,10 +256,21 @@ void boot(int biosdev) // Not sure if it is safe to call setVideoMode() before the // config table has been loaded. Call video_mode() instead. +#if DEBUG + printf("before video_mode\n"); +#endif video_mode( 2 ); // 80x25 mono text mode. +#if DEBUG + printf("after video_mode\n"); +#endif - // Scan hardware configuration. + // Check to see that this hardware is supported. + status = checkForSupportedHardware(); + if (status != 0) { + stop("This hardware configuration is not supported by Darwin/x86. (%d)", status); + } + // Scan hardware configuration. scanHardware(); // First get info for boot volume. @@ -277,7 +278,7 @@ void boot(int biosdev) // Record default boot device. gBootVolume = selectBootVolume(bvChain); - bootArgs->kernDev = MAKEKERNDEV(gBIOSDev, + bootInfo->kernDev = MAKEKERNDEV(gBIOSDev, BIOS_DEV_UNIT(gBootVolume), gBootVolume->part_no ); @@ -297,6 +298,7 @@ void boot(int biosdev) int trycache; long flags, cachetime, kerneltime, exttime; int ret = -1; + void *binary = (void *)kLoadAddr; // Initialize globals. @@ -315,19 +317,11 @@ void boot(int biosdev) // Reset cache name. - bzero(gCacheNameAdler, sizeof(gCacheNameAdler)); + bzero(gCacheNameAdler + 64, sizeof(gCacheNameAdler) - 64); - if ( getValueForKey( kRootDeviceKey, &val, &len ) == YES ) { - if (*val == '*') { - val++; - len--; - } - strncpy( gCacheNameAdler + 64, val, len ); - sprintf(gCacheNameAdler + 64 + len, ",%s", bootArgs->bootFile); - } else { - strcpy(gCacheNameAdler + 64, bootArgs->bootFile); - } - adler32 = Adler32(gCacheNameAdler, sizeof(gCacheNameAdler)); + sprintf(gCacheNameAdler + 64, "%s,%s", gRootDevice, bootInfo->bootFile); + + adler32 = Adler32((unsigned char *)gCacheNameAdler, sizeof(gCacheNameAdler)); if (getValueForKey(kKernelCacheKey, &val, &len) == YES) { strlcpy(gBootKernelCacheFile, val, len+1); @@ -337,7 +331,6 @@ void boot(int biosdev) // Check for cache file. - trycache = (((gBootMode & kBootModeSafe) == 0) && (gOverrideKernel == NO) && (gBootFileType == kBlockDeviceType) && @@ -349,7 +342,7 @@ void boot(int biosdev) if (trycache) do { // if we haven't found the kernel yet, don't use the cache - ret = GetFileInfo(NULL, bootArgs->bootFile, &flags, &kerneltime); + ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime); if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) { trycache = 0; break; @@ -380,13 +373,14 @@ void boot(int biosdev) bootFile = gBootKernelCacheFile; verbose("Loading kernel cache %s\n", bootFile); ret = LoadFile(bootFile); + binary = (void *)kLoadAddr; if (ret >= 0) { break; } } - bootFile = bootArgs->bootFile; + bootFile = bootInfo->bootFile; verbose("Loading kernel %s\n", bootFile); - ret = LoadFile(bootFile); + ret = LoadThinFatFile(bootFile, &binary); } while (0); clearActivityIndicator(); @@ -398,14 +392,7 @@ void boot(int biosdev) if (ret < 0) { error("Can't find %s\n", bootFile); - if ( gBootFileType == kBIOSDevTypeFloppy ) - { - // floppy in drive, but failed to load kernel. - gBIOSDev = kBIOSDevTypeHardDrive; - initKernBootStruct( gBIOSDev ); - printf("Attempting to load from hard drive..."); - } - else if ( gBootFileType == kNetworkDeviceType ) + if ( gBootFileType == kNetworkDeviceType ) { // Return control back to PXE. Don't unload PXE base code. gUnloadPXEOnExit = 0; @@ -413,7 +400,7 @@ void boot(int biosdev) } } else { /* Won't return if successful. */ - ret = ExecKernel((void *)kLoadAddr); + ret = ExecKernel(binary); } } /* while(1) */ @@ -459,3 +446,4 @@ unsigned long Adler32(unsigned char *buf, long len) return OSSwapHostToBigInt32(result); } + diff --git a/i386/boot2/boot.h b/i386/boot2/boot.h index dc7d3ab..98982f4 100644 --- a/i386/boot2/boot.h +++ b/i386/boot2/boot.h @@ -45,8 +45,12 @@ #define kBootDeviceKey "Boot Device" #define kTimeoutKey "Timeout" #define kRootDeviceKey "rd" +#define kBootUUIDKey "boot-uuid" #define kPlatformKey "platform" #define kACPIKey "acpi" +#define kCDROMPromptKey "CD-ROM Prompt" +#define kCDROMOptionKey "CD-ROM Option Key" + #define kDefaultKernel "mach_kernel" /* @@ -54,14 +58,16 @@ * */ #define kVerboseModeFlag "-v" -#define kSafeModeFlag "-f" +#define kSafeModeFlag "-x" +#define kOldSafeModeFlag "-f" #define kIgnoreBootFileFlag "-F" #define kSingleUserModeFlag "-s" /* * Booter behavior control */ -#define kBootTimeout 8 +#define kBootTimeout -1 +#define kCDBootTimeout 8 /* * A global set by boot() to record the device that the booter @@ -75,6 +81,7 @@ extern char bootPrompt[]; extern BOOL gOverrideKernel; extern char *gPlatformName; extern char gMKextName[]; +extern char gRootDevice[]; extern BVRef gBootVolume; // Boot Modes @@ -111,6 +118,7 @@ convertImage( unsigned short width, unsigned char **newImageData ); extern char * decodeRLE( const void * rleData, int rleBlocks, int outBytes ); extern void drawBootGraphics(void); +extern int getVideoMode(void); /* * drivers.c diff --git a/i386/boot2/drivers.c b/i386/boot2/drivers.c index ab7742a..aec4574 100644 --- a/i386/boot2/drivers.c +++ b/i386/boot2/drivers.c @@ -159,7 +159,10 @@ long LoadDrivers( char * dirSpec ) if ( gBootFileType == kNetworkDeviceType ) { - NetLoadDrivers(dirSpec); + if (NetLoadDrivers(dirSpec) != 0) { + error("Could not load drivers from the network\n"); + return -1; + } } else if ( gBootFileType == kBlockDeviceType ) { @@ -284,7 +287,7 @@ NetLoadDrivers( char * dirSpec ) #endif // INTEL modification - sprintf(gDriverSpec, "%s%s.mkext", dirSpec, bootArgs->bootFile); + sprintf(gDriverSpec, "%s%s.mkext", dirSpec, bootInfo->bootFile); verbose("NetLoadDrivers: Loading from [%s]\n", gDriverSpec); @@ -307,22 +310,20 @@ LoadDriverMKext( char * fileSpec ) unsigned long driversAddr, driversLength; long length; char segName[32]; - DriversPackage * package = (DriversPackage *)kLoadAddr; + DriversPackage * package; #define GetPackageElement(e) OSSwapBigToHostInt32(package->e) // Load the MKext. - length = LoadFile(fileSpec); + length = LoadThinFatFile(fileSpec, (void **)&package); if (length == -1) return -1; - ThinFatFile((void **)&package, &length); - // Verify the MKext. if (( GetPackageElement(signature1) != kDriverPackageSignature1) || ( GetPackageElement(signature2) != kDriverPackageSignature2) || ( GetPackageElement(length) > kLoadSize ) || ( GetPackageElement(alder32) != - Alder32((char *)&package->version, GetPackageElement(length) - 0x10) ) ) + Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) ) { return -1; } @@ -435,53 +436,6 @@ LoadDriverPList( char * dirSpec, char * name, long bundleType ) return ret; } -#if 0 -//========================================================================== -// ThinFatFile -// Checks the loaded file for a fat header; if present, updates -// loadAddr and length to be the portion of the fat file relevant -// to the current architecture; otherwise leaves them unchanged. - -static void -ThinFatFile(void **loadAddrP, unsigned long *lengthP) -{ - // Check for fat files. - struct fat_header *fhp = (struct fat_header *)kLoadAddr; - struct fat_arch *fap = (struct fat_arch *)((void *)kLoadAddr + - sizeof(struct fat_header)); - int nfat, swapped; - void *loadAddr = 0; - unsigned long length = 0; - - if (fhp->magic == FAT_MAGIC) { - nfat = fhp->nfat_arch; - swapped = 0; - } else if (fhp->magic == FAT_CIGAM) { - nfat = OSSwapInt32(fhp->nfat_arch); - swapped = 1; - } else { - nfat = 0; - swapped = 0; - } - - for (; nfat > 0; nfat--, fap++) { - if (swapped) { - fap->cputype = OSSwapInt32(fap->cputype); - fap->offset = OSSwapInt32(fap->offset); - fap->size = OSSwapInt32(fap->size); - } - if (fap->cputype == CPU_TYPE_I386) { - loadAddr = (void *)kLoadAddr + fap->offset; - length = fap->size; - break; - } - } - if (loadAddr) - *loadAddrP = loadAddr; - if (length) - *lengthP = length; -} -#endif //========================================================================== // LoadMatchedModules @@ -494,6 +448,8 @@ LoadMatchedModules( void ) char *fileName, segName[32]; DriverInfoPtr driver; long length, driverAddr, driverLength; + void *driverModuleAddr = 0; + module = gModuleHead; @@ -507,18 +463,21 @@ LoadMatchedModules( void ) { fileName = prop->string; sprintf(gFileSpec, "%s%s", module->driverPath, fileName); - length = LoadFile(gFileSpec); + length = LoadThinFatFile(gFileSpec, &driverModuleAddr); + //length = LoadFile(gFileSpec); + //driverModuleAddr = (void *)kLoadAddr; + //printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getc(); } else length = 0; if (length != -1) { - void *driverModuleAddr = (void *)kLoadAddr; - if (length != 0) - { - ThinFatFile(&driverModuleAddr, &length); - } + //driverModuleAddr = (void *)kLoadAddr; + //if (length != 0) + //{ + // ThinFatFile(&driverModuleAddr, &length); + //} // Make make in the image area. driverLength = sizeof(DriverInfo) + module->plistLength + length; diff --git a/i386/boot2/graphics.c b/i386/boot2/graphics.c index 89c6268..466f0ad 100644 --- a/i386/boot2/graphics.c +++ b/i386/boot2/graphics.c @@ -52,6 +52,7 @@ void drawDataRectangle( unsigned short x, unsigned short height, unsigned char * data ); +static void setBorderColor( unsigned char colorIndex ); int convertImage( unsigned short width, @@ -59,7 +60,7 @@ convertImage( unsigned short width, const unsigned char *imageData, unsigned char **newImageData ); -#define VIDEO(x) (bootArgs->video.v_ ## x) +#define VIDEO(x) (bootArgs->Video.v_ ## x) #define MIN(x, y) ((x) < (y) ? (x) : (y)) @@ -81,7 +82,7 @@ void printVBEInfo() // Check presence of VESA signature. - if ( strncmp( vbeInfo.VESASignature, "VESA", 4 ) ) + if ( strncmp( (char *)vbeInfo.VESASignature, "VESA", 4 ) ) return; // Announce controller properties. @@ -428,12 +429,12 @@ setVESAGraphicsMode( unsigned short width, // Update KernBootStruct using info provided by the selected // VESA mode. - bootArgs->graphicsMode = GRAPHICS_MODE; - bootArgs->video.v_width = minfo.XResolution; - bootArgs->video.v_height = minfo.YResolution; - bootArgs->video.v_depth = minfo.BitsPerPixel; - bootArgs->video.v_rowBytes = minfo.BytesPerScanline; - bootArgs->video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr); + bootArgs->Video.v_display = GRAPHICS_MODE; + bootArgs->Video.v_width = minfo.XResolution; + bootArgs->Video.v_height = minfo.YResolution; + bootArgs->Video.v_depth = minfo.BitsPerPixel; + bootArgs->Video.v_rowBytes = minfo.BytesPerScanline; + bootArgs->Video.v_baseAddr = VBEMakeUInt32(minfo.PhysBasePtr); } while ( 0 ); @@ -494,6 +495,8 @@ drawBootGraphics( void ) drawColorRectangle( 0, 0, VIDEO(width), VIDEO(height), 0x01 /* color index */ ); + setBorderColor( 0x01 /* color index */ ); + appleBootPict = decodeRLE( gAppleBootPictRLE, kAppleBootRLEBlocks, kAppleBootWidth * kAppleBootHeight ); @@ -502,7 +505,7 @@ drawBootGraphics( void ) if ( appleBootPict ) { convertImage(kAppleBootWidth, kAppleBootHeight, - appleBootPict, &imageData); + (unsigned char *)appleBootPict, &imageData); x = ( VIDEO(width) - kAppleBootWidth ) / 2; y = ( VIDEO(height) - kAppleBootHeight ) / 2 + kAppleBootOffset; @@ -559,7 +562,7 @@ static unsigned long lookUpCLUTIndex( unsigned char index, static void * stosl(void * dst, long val, long len) { - asm( "rep; stosl" + asm volatile ( "rep; stosl" : "=c" (len), "=D" (dst) : "0" (len), "1" (dst), "a" (val) : "memory" ); @@ -616,6 +619,29 @@ void drawDataRectangle( unsigned short x, } } + +//========================================================================== +// setBorderColor + +static void +setBorderColor( unsigned char colorIndex ) +{ + long color = lookUpCLUTIndex( colorIndex, 32 ); + VBEInfoBlock vbeInfo; + int err; + + // Get VBE controller info. + + bzero( &vbeInfo, sizeof(vbeInfo) ); + err = getVBEInfo( &vbeInfo ); + if ( err != errSuccess ) + { + return; + } + +} + + //========================================================================== // setVESATextMode @@ -646,12 +672,12 @@ setVESATextMode( unsigned short cols, // Update KernBootStruct using info provided by the selected // VESA mode. - bootArgs->graphicsMode = TEXT_MODE; - bootArgs->video.v_baseAddr = 0xb8000; - bootArgs->video.v_width = minfo.XResolution; - bootArgs->video.v_height = minfo.YResolution; - bootArgs->video.v_depth = 8; - bootArgs->video.v_rowBytes = 0x8000; + bootArgs->Video.v_display = VGA_TEXT_MODE; + bootArgs->Video.v_baseAddr = 0xb8000; + bootArgs->Video.v_width = minfo.XResolution; + bootArgs->Video.v_height = minfo.YResolution; + bootArgs->Video.v_depth = 8; + bootArgs->Video.v_rowBytes = 0x8000; return errSuccess; // always return success } @@ -696,7 +722,7 @@ getNumberArrayFromProperty( const char * propKey, //========================================================================== // setVideoMode // -// Set the video mode to TEXT_MODE or GRAPHICS_MODE. +// Set the video mode to VGA_TEXT_MODE or GRAPHICS_MODE. void setVideoMode( int mode ) @@ -725,19 +751,17 @@ setVideoMode( int mode ) err = setVESAGraphicsMode( params[0], params[1], params[2], params[3] ); if ( err == errSuccess ) { - // If this boolean is set to true, then the console driver - // in the kernel will show the animated color wheel on the - // upper left corner. - - bootArgs->video.v_display = !gVerboseMode; - - if (!gVerboseMode) { + if (gVerboseMode) { + // Tell the kernel to use text mode on a linear frame buffer display + bootArgs->Video.v_display = FB_TEXT_MODE; + } else { + bootArgs->Video.v_display = GRAPHICS_MODE; drawBootGraphics(); } } } - if ( (mode == TEXT_MODE) || (err != errSuccess) ) + if ( (mode == VGA_TEXT_MODE) || (err != errSuccess) ) { count = getNumberArrayFromProperty( kTextModeKey, params, 2 ); if ( count < 2 ) @@ -747,18 +771,18 @@ setVideoMode( int mode ) } setVESATextMode( params[0], params[1], 4 ); - bootArgs->video.v_display = 0; + bootArgs->Video.v_display = VGA_TEXT_MODE; } currentIndicator = 0; } //========================================================================== -// Return the current video mode, TEXT_MODE or GRAPHICS_MODE. +// Return the current video mode, VGA_TEXT_MODE or GRAPHICS_MODE. int getVideoMode(void) { - return bootArgs->graphicsMode; + return bootArgs->Video.v_display; } //========================================================================== @@ -783,7 +807,7 @@ spinActivityIndicator( void ) else lastTickTime = currentTickTime; - if ( getVideoMode() == TEXT_MODE ) + if ( getVideoMode() == VGA_TEXT_MODE ) { if (currentIndicator >= kNumIndicators) currentIndicator = 0; string[0] = indicator[currentIndicator++]; @@ -794,7 +818,7 @@ spinActivityIndicator( void ) void clearActivityIndicator( void ) { - if ( getVideoMode() == TEXT_MODE ) + if ( getVideoMode() == VGA_TEXT_MODE ) { printf(" \b"); } diff --git a/i386/boot2/options.c b/i386/boot2/options.c index 02000fb..4427aae 100644 --- a/i386/boot2/options.c +++ b/i386/boot2/options.c @@ -43,11 +43,6 @@ static void showHelp(); //========================================================================== -enum { - kCursorTypeHidden = 0x0100, - kCursorTypeUnderline = 0x0607 -}; - typedef struct { int x; int y; @@ -101,7 +96,7 @@ static int countdown( const char * msg, int row, int timeout ) moveCursor( 0, row ); printf(msg); - for ( time = time18(), timeout++; timeout; ) + for ( time = time18(), timeout++; timeout > 0; ) { if (ch = readKeyboardStatus()) break; @@ -395,7 +390,7 @@ printMemoryInfo(void) { int line; int i; - MemoryRange *mp = bootArgs->memoryMap; + MemoryRange *mp = bootInfo->memoryMap; // Activate and clear page 1 setActiveDisplayPage(1); @@ -404,7 +399,7 @@ printMemoryInfo(void) printf("BIOS reported memory ranges:\n"); line = 1; - for (i=0; i<bootArgs->memoryMapCount; i++) { + for (i=0; i<bootInfo->memoryMapCount; i++) { printf("Base 0x%08x%08x, ", (unsigned long)(mp->base >> 32), (unsigned long)(mp->base)); @@ -441,20 +436,29 @@ getBootOptions(BOOL firstRun) BVRef bvr; BVRef bvChain; BVRef menuBVR; - BOOL showPrompt, newShowPrompt; + BOOL showPrompt, newShowPrompt, isCDROM; MenuItem * menuItems = NULL; + if ( diskIsCDROM(gBootVolume) ) + isCDROM = TRUE; + else + isCDROM = FALSE; + // Allow user to override default timeout. if ( getIntForKey(kTimeoutKey, &timeout) == NO ) { - timeout = kBootTimeout; + if ( isCDROM ) + timeout = kCDBootTimeout; + else + timeout = kBootTimeout; } + if (timeout < 0) gBootMode |= kBootModeQuiet; - // If the user is holding down a shift key, - // abort quiet mode. + // If the user is holding down a modifier key, + // enter safe mode. if ( ( readKeyboardShiftFlags() & 0x0F ) != 0 ) { - gBootMode &= ~kBootModeQuiet; + gBootMode |= kBootModeSafe; } // If user typed F8, abort quiet mode, @@ -470,7 +474,7 @@ getBootOptions(BOOL firstRun) clearScreenRows( 0, kScreenLastRow ); if ( ! ( gBootMode & kBootModeQuiet ) ) { // Display banner and show hardware info. - printf( bootBanner, (bootArgs->convmem + bootArgs->extmem) / 1024 ); + printf( bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024 ); printVBEInfo(); } @@ -483,32 +487,61 @@ getBootOptions(BOOL firstRun) bvChain = scanBootVolumes( gBIOSDev, &bvCount ); gBootVolume = menuBVR = selectBootVolume( bvChain ); -#if 0 - // When booting from CD (via HD emulation), default to hard + // When booting from CD, default to hard // drive boot when possible. - if ( gBootVolume->part_type == FDISK_BOOTER && - gBootVolume->biosdev == 0x80 ) + if ( isCDROM ) { - // Scan the original device 0x80 that has been displaced - // by the CD-ROM. + const char *val; + char *prompt; + int cnt; + int optionKey; + + if (getValueForKey( kCDROMPromptKey, &val, &cnt )) { + cnt += 1; + prompt = malloc(cnt); + strlcpy(prompt, val, cnt); + } else { + prompt = "Press any key to start up from CD-ROM, " + "or press F8 to enter startup options."; + cnt = 0; + } - BVRef hd_bvr = selectBootVolume(scanBootVolumes(0x81, 0)); - if ( hd_bvr->flags & kBVFlagNativeBoot ) - { - int key = countdown("Press C to start up from CD-ROM.", - kMenuTopRow, 5); - - if ( (key & 0x5f) != 'c' ) - { + if (getIntForKey( kCDROMOptionKey, &optionKey )) { + // The key specified is a special key. + } else if (getValueForKey( kCDROMOptionKey, &val, &cnt) && cnt >= 1) { + optionKey = val[0]; + } else { + // Default to F8. + optionKey = 0x4200; + } + + key = countdown(prompt, kMenuTopRow, timeout); + if (cnt) + free(prompt); + + clearScreenRows( kMenuTopRow, kMenuTopRow + 2 ); + + if (key == 0) { + // Boot from hard disk. + // Scan the original device 0x80. + + BVRef hd_bvr = selectBootVolume(scanBootVolumes(0x80, 0)); + if ( hd_bvr->flags & kBVFlagNativeBoot ) { gBootVolume = hd_bvr; gBIOSDev = hd_bvr->biosdev; initKernBootStruct( gBIOSDev ); goto done; } + } else { + if (optionKey < 0x100) + key = key & 0x5F; + if (key != optionKey) + goto done; } + gBootMode &= ~kBootModeQuiet; + timeout = 0; } -#endif if ( gBootMode & kBootModeQuiet ) { @@ -520,6 +553,11 @@ getBootOptions(BOOL firstRun) ( countdown("Press any key to enter startup options.", kMenuTopRow, timeout) == 0 ) ) { + // If the user is holding down a modifier key, + // enter safe mode. + if ( ( readKeyboardShiftFlags() & 0x0F ) != 0 ) { + gBootMode |= kBootModeSafe; + } goto done; } @@ -622,7 +660,71 @@ done: extern unsigned char chainbootdev; extern unsigned char chainbootflag; -int processBootOptions() +BOOL +copyArgument(const char *argName, const char *val, int cnt, char **argP, int *cntRemainingP) +{ + int argLen = argName ? strlen(argName) : 0; + int len = argLen + cnt + 1; // +1 to account for space + + if (len > *cntRemainingP) { + error("Warning: boot arguments too long, truncating\n"); + return NO; + } + + if (argName) { + strncpy( *argP, argName, argLen ); + *argP += argLen; + *argP[0] = '='; + (*argP)++; + len++; // +1 to account for '=' + } + strncpy( *argP, val, cnt ); + *argP += cnt; + *argP[0] = ' '; + (*argP)++; + + *cntRemainingP -= len; + return YES; +} +// +// Returns TRUE if an argument was copied, FALSE otherwise + +BOOL +processBootArgument( + const char *argName, // The argument to search for + const char *userString, // Typed-in boot arguments + const char *kernelFlags, // Kernel flags from config table + const char *configTable, + char **argP, // Output value + int *cntRemainingP, // Output count + char *foundVal // found value + ) +{ + const char *val; + int cnt; + BOOL found = NO; + + if (getValueForBootKey(userString, argName, &val, &cnt)) { + // Don't copy; these values will be copied at the end of argument processing. + found = YES; + } else if (getValueForBootKey(kernelFlags, argName, &val, &cnt)) { + // Don't copy; these values will be copied at the end of argument processing. + found = YES; + } else if (getValueForConfigTableKey(configTable, argName, &val, &cnt)) { + copyArgument(argName, val, cnt, argP, cntRemainingP); + found = YES; + } + if (found && foundVal) { + strlcpy(foundVal, val, cnt+1); + } + return found; +} + +// Maximum config table value size +#define VALUE_SIZE 1024 + +int +processBootOptions() { const char * cp = gBootArgs; const char * val = 0; @@ -631,6 +733,12 @@ int processBootOptions() int userCnt; int cntRemaining; char * argP; + char uuidStr[64]; + BOOL uuidSet = NO; + char * configKernelFlags; + char * valueBuffer; + + valueBuffer = (char *)malloc(VALUE_SIZE); skipblanks( &cp ); @@ -654,10 +762,10 @@ int processBootOptions() return 1; } - bootArgs->kernDev &= ~((B_UNITMASK << B_UNITSHIFT ) | + bootInfo->kernDev &= ~((B_UNITMASK << B_UNITSHIFT ) | (B_PARTITIONMASK << B_PARTITIONSHIFT)); - bootArgs->kernDev |= MAKEKERNDEV( 0, + bootInfo->kernDev |= MAKEKERNDEV( 0, /* unit */ BIOS_DEV_UNIT(gBootVolume), /* partition */ gBootVolume->part_no ); } @@ -680,60 +788,94 @@ int processBootOptions() gOverrideKernel = NO; if (( kernel = extractKernelName((char **)&cp) )) { - strcpy( bootArgs->bootFile, kernel ); + strcpy( bootInfo->bootFile, kernel ); gOverrideKernel = YES; } else { if ( getValueForKey( kKernelNameKey, &val, &cnt ) ) { - strlcpy( bootArgs->bootFile, val, cnt+1 ); - if (strcmp( bootArgs->bootFile, kDefaultKernel ) != 0) { + strlcpy( bootInfo->bootFile, val, cnt+1 ); + if (strcmp( bootInfo->bootFile, kDefaultKernel ) != 0) { gOverrideKernel = YES; } } else { - strcpy( bootArgs->bootFile, kDefaultKernel ); + strcpy( bootInfo->bootFile, kDefaultKernel ); } } cntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space + argP = bootArgs->CommandLine; + + // Get config table kernel flags, if not ignored. + if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) == TRUE || + getValueForKey( kKernelFlagsKey, &val, &cnt ) == FALSE) { + val = ""; + cnt = 0; + } + configKernelFlags = (char *)malloc(cnt + 1); + strlcpy(configKernelFlags, val, cnt + 1); - // Check to see if we need to specify root device. - // If user types "rd=.." on the boot line, it overrides - // the boot device key in the boot arguments file. - // - argP = bootArgs->bootString; - if ( getValueForBootKey( cp, kRootDeviceKey, &val, &cnt ) == FALSE && - getValueForKey( kRootDeviceKey, &val, &cnt ) == FALSE ) { - if ( getValueForKey( kBootDeviceKey, &val, &cnt ) ) { - strcpy( argP, "rd=*" ); - argP += 4; - strlcpy( argP, val, cnt+1); - cntRemaining -= cnt; - argP += cnt; - *argP++ = ' '; + if (processBootArgument(kBootUUIDKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, 0)) { + // boot-uuid was set either on the command-line + // or in the config file. + uuidSet = YES; + } else { + if (GetFSUUID(bootInfo->bootFile, uuidStr) == 0) { + verbose("Setting boot-uuid to: %s\n", uuidStr); + copyArgument(kBootUUIDKey, uuidStr, strlen(uuidStr), &argP, &cntRemaining); + uuidSet = YES; } } - // Check to see if we should ignore saved kernel flags. - if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) == FALSE) { - if (getValueForKey( kKernelFlagsKey, &val, &cnt ) == FALSE) { - val = 0; - cnt = 0; + if (!processBootArgument(kRootDeviceKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gRootDevice)) { + cnt = 0; + if ( getValueForKey( kBootDeviceKey, &val, &cnt)) { + valueBuffer[0] = '*'; + cnt++; + strlcpy(valueBuffer + 1, val, cnt); + val = valueBuffer; + } else { + if (uuidSet) { + val = "*uuid"; + cnt = 5; + } else { + // Don't set "rd=.." if there is no boot device key + // and no UUID. + val = ""; + cnt = 0; + } + } + if (cnt > 0) { + copyArgument( kRootDeviceKey, val, cnt, &argP, &cntRemaining); } + strlcpy( gRootDevice, val, (cnt + 1)); } - // Store the merged kernel flags and boot args. + if (!processBootArgument(kPlatformKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gPlatformName)) { + getPlatformName(gPlatformName); + copyArgument(kPlatformKey, gPlatformName, strlen(gPlatformName), &argP, &cntRemaining); + } - if (cnt > cntRemaining) { - error("Warning: boot arguments too long, truncated\n"); - cnt = cntRemaining; + if (!getValueForBootKey(cp, kSafeModeFlag, &val, &cnt) && + !getValueForBootKey(configKernelFlags, kSafeModeFlag, &val, &cnt)) { + if (gBootMode & kBootModeSafe) { + copyArgument(0, kSafeModeFlag, strlen(kSafeModeFlag), &argP, &cntRemaining); + } } + + // Store the merged kernel flags and boot args. + + cnt = strlen(configKernelFlags); if (cnt) { - strncpy(argP, val, cnt); - argP[cnt++] = ' '; + if (cnt > cntRemaining) { + error("Warning: boot arguments too long, truncating\n"); + cnt = cntRemaining; + } + strncpy(argP, configKernelFlags, cnt); + argP[cnt++] = ' '; + cntRemaining -= cnt; } - cntRemaining = cntRemaining - cnt; userCnt = strlen(cp); if (userCnt > cntRemaining) { - error("Warning: boot arguments too long, truncated\n"); + error("Warning: boot arguments too long, truncating\n"); userCnt = cntRemaining; } strncpy(&argP[cnt], cp, userCnt); @@ -745,19 +887,21 @@ int processBootOptions() gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt ) ) ? kBootModeSafe : kBootModeNormal; - if ( getValueForKey( kPlatformKey, &val, &cnt ) ) { - strlcpy(gPlatformName, val, cnt + 1); - } else { - strcpy(gPlatformName, "ACPI"); + if ( getValueForKey( kOldSafeModeFlag, &val, &cnt ) ) { + gBootMode = kBootModeSafe; } if ( getValueForKey( kMKextCacheKey, &val, &cnt ) ) { strlcpy(gMKextName, val, cnt + 1); } + free(configKernelFlags); + free(valueBuffer); + return 0; } + //========================================================================== // Load the help file and display the file contents on the screen. diff --git a/i386/cdboot/cdboot.s b/i386/cdboot/cdboot.s index c286b9e..deed6d8 100644 --- a/i386/cdboot/cdboot.s +++ b/i386/cdboot/cdboot.s @@ -42,7 +42,7 @@ DEBUG EQU 0 %define DebugPause(x) %endif -kBoot2Sectors EQU 112 ; sectors to load for boot2 +kBoot2Sectors EQU 126 ; sectors to load for boot2 kBoot2Address EQU 0x0200 ; boot2 load address kBoot2Segment EQU 0x2000 ; boot2 load segment diff --git a/i386/libsa/Makefile b/i386/libsa/Makefile index 211b28a..7b7d680 100644 --- a/i386/libsa/Makefile +++ b/i386/libsa/Makefile @@ -6,10 +6,11 @@ UTILDIR = ../util INSTALL_SA_DIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone INSTALL_MD_DIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/machdep/i386 -OPTIM = -Os +OPTIM = -Os -Oz CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \ -fno-builtin -static -fomit-frame-pointer \ - -mpreferred-stack-boundary=2 -fno-align-functions + -mpreferred-stack-boundary=2 -fno-align-functions \ + -mno-sse2 -mfpmath=387 INC = -I. -I$(SYMROOT) -I$(UTILDIR) ifneq "" "$(wildcard /bin/mkdirs)" diff --git a/i386/libsa/memory.h b/i386/libsa/memory.h index a5dbece..bb473dc 100644 --- a/i386/libsa/memory.h +++ b/i386/libsa/memory.h @@ -67,11 +67,11 @@ #define KERNEL_ADDR 0x00100000 // 64M kernel + drivers #define KERNEL_LEN 0x04000000 -#define ZALLOC_ADDR 0x04100000 // 47M zalloc area -#define ZALLOC_LEN 0x02F00000 +#define ZALLOC_ADDR 0x04100000 // 39M zalloc area +#define ZALLOC_LEN 0x02700000 -#define LOAD_ADDR 0x07000000 // 16M File load buffer -#define LOAD_LEN 0x01000000 +#define LOAD_ADDR 0x06800000 // 24M File load buffer +#define LOAD_LEN 0x01800000 #define TFTP_ADDR LOAD_ADDR // tftp download buffer #define TFTP_LEN LOAD_LEN diff --git a/i386/libsa/string.c b/i386/libsa/string.c index 682abfe..a65a6e4 100644 --- a/i386/libsa/string.c +++ b/i386/libsa/string.c @@ -27,7 +27,7 @@ void * memset(void * dst, int val, size_t len) { - asm( "rep; stosb" + asm volatile ( "rep; stosb" : "=c" (len), "=D" (dst) : "0" (len), "1" (dst), "a" (val) : "memory" ); @@ -38,7 +38,7 @@ void * memset(void * dst, int val, size_t len) #if 0 void * memcpy(void * dst, const void * src, size_t len) { - asm( "rep; movsb" + asm volatile ( "rep; movsb" : "=c" (len), "=D" (dst), "=S" (src) : "0" (len), "1" (dst), "2" (src) : "memory" ); @@ -59,7 +59,7 @@ void bzero(void * dst, size_t len) #else void * memcpy(void * dst, const void * src, size_t len) { - asm( "cld \n\t" + asm volatile ( "cld \n\t" "movl %%ecx, %%edx \n\t" "shrl $2, %%ecx \n\t" "rep; movsl \n\t" @@ -75,7 +75,7 @@ void * memcpy(void * dst, const void * src, size_t len) void bcopy(const void * src, void * dst, size_t len) { - asm( "cld \n\t" + asm volatile ( "cld \n\t" "movl %%ecx, %%edx \n\t" "shrl $2, %%ecx \n\t" "rep; movsl \n\t" @@ -89,7 +89,7 @@ void bcopy(const void * src, void * dst, size_t len) void bzero(void * dst, size_t len) { - asm( "xorl %%eax, %%eax \n\t" + asm volatile ( "xorl %%eax, %%eax \n\t" "cld \n\t" "movl %%ecx, %%edx \n\t" "shrl $2, %%ecx \n\t" diff --git a/i386/libsa/zalloc.c b/i386/libsa/zalloc.c index 51162eb..8005a01 100644 --- a/i386/libsa/zalloc.c +++ b/i386/libsa/zalloc.c @@ -64,7 +64,7 @@ size_t zalloced_size; static void malloc_error(char *addr, size_t size) { #ifdef i386 - asm("hlt"); + asm volatile ("hlt"); #endif } @@ -177,7 +177,7 @@ void free(void * pointer) #if i386 // Get return address of our caller, // in case we have to report an error below. - asm("movl %%esp, %%eax\n\t" + asm volatile ("movl %%esp, %%eax\n\t" "subl $4, %%eax\n\t" "movl 0(%%eax), %%eax" : "=a" (rp) ); #else diff --git a/i386/libsaio/Makefile b/i386/libsaio/Makefile index 273cad7..517f141 100644 --- a/i386/libsaio/Makefile +++ b/i386/libsaio/Makefile @@ -7,12 +7,13 @@ LIBSADIR = ../libsa INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone #SYMROOT= -OPTIM = -Os -CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \ +OPTIM = -Os -Oz +CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost \ -D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER \ -DRCZ_COMPRESSED_FILE_SUPPORT \ -fno-builtin -static -fomit-frame-pointer \ - -mpreferred-stack-boundary=2 -fno-align-functions + -mpreferred-stack-boundary=2 -fno-align-functions \ + -mno-sse2 -mfpmath=387 DEFINES= CONFIG = hd INC = -I../rcz -I. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR) @@ -30,10 +31,11 @@ VPATH = $(OBJROOT):$(SYMROOT) SAIO_OBJS = table.o asm.o bios.o biosfn.o \ disk.o sys.o cache.o bootstruct.o \ - ufs.o ufs_byteorder.o \ stringTable.o load.o memory.o misc.o \ + ufs.o ufs_byteorder.o \ vbe.o nbp.o hfs.o hfs_compare.o \ - xml.o ntfs.o msdos.o + xml.o ntfs.o msdos.o md5c.o device_tree.o + SAIO_EXTERN_OBJS = console.o diff --git a/i386/libsaio/asm.s b/i386/libsaio/asm.s index 367a9ea..a9bbe9d 100644 --- a/i386/libsaio/asm.s +++ b/i386/libsaio/asm.s @@ -31,6 +31,9 @@ /* * HISTORY * $Log: asm.s,v $ + * Revision 1.8 2005/06/24 22:47:12 curtisg + * Merging changes for 4159531 to pass data to the kernel in EFI format. + * * Revision 1.7 2004/05/13 17:58:38 curtisg * Integrating: * <rdar://problem/3094680>: (Silent boot) @@ -293,7 +296,7 @@ xreal: // halt() // LABEL(_halt) - hlt + call _bgetc jmp _halt // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/i386/libsaio/bios.h b/i386/libsaio/bios.h index a29708c..f75cc8f 100644 --- a/i386/libsaio/bios.h +++ b/i386/libsaio/bios.h @@ -78,4 +78,28 @@ typedef struct { #define BASE_HD_DRIVE 0x80 +#if 0 +/* + * ACPI defined memory range types. + */ +enum { + kMemoryRangeUsable = 1, // RAM usable by the OS. + kMemoryRangeReserved = 2, // Reserved. (Do not use) + kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed. + kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use) + + /* Undefined types should be treated as kMemoryRangeReserved */ +}; +#endif + +/* + * Memory range descriptor. + */ +typedef struct MemoryRange { + unsigned long long base; // 64-bit base address + unsigned long long length; // 64-bit length in bytes + unsigned long type; // type of memory range + unsigned long reserved; +} MemoryRange; + #endif /* !__LIBSAIO_BIOS_H */ diff --git a/i386/libsaio/biosfn.c b/i386/libsaio/biosfn.c index 2c9ab4f..7c0a3f2 100644 --- a/i386/libsaio/biosfn.c +++ b/i386/libsaio/biosfn.c @@ -87,14 +87,11 @@ unsigned long getMemoryMap( MemoryRange * rangeArray, #define kMemoryMapSignature 'SMAP' #define kDescriptorSizeMin 20 - MemoryRange * range = rangeArray; + MemoryRange * range = (MemoryRange *)BIOS_ADDR; unsigned long count = 0; unsigned long long conMemSize = 0; unsigned long long extMemSize = 0; - // The memory pointed by the rangeArray must reside within the - // first megabyte. - // // Prepare for the INT15 E820h call. Each call returns a single // memory range. A continuation value is returned that must be // provided on a subsequent call to fetch the next range. @@ -106,6 +103,10 @@ unsigned long getMemoryMap( MemoryRange * rangeArray, // Some BIOSes will simply ignore the value of ECX on entry. // Probably best to keep its value at 20 to avoid surprises. + //printf("Get memory map 0x%x, %d\n", rangeArray);getc(); + if (maxRangeCount > (BIOS_LEN / sizeof(MemoryRange))) { + maxRangeCount = (BIOS_LEN / sizeof(MemoryRange)); + } bb.ebx.rx = 0; // Initial continuation value must be zero. while ( count < maxRangeCount ) @@ -122,7 +123,11 @@ unsigned long getMemoryMap( MemoryRange * rangeArray, if ( bb.flags.cf || bb.eax.rx != kMemoryMapSignature - || bb.ecx.rx != kDescriptorSizeMin ) break; + || bb.ecx.rx != kDescriptorSizeMin ) { + //printf("Got an error %x %x %x\n", bb.flags.cf, + // bb.eax.rx, bb.ecx.rx); + break; + } // Tally up the conventional/extended memory sizes. @@ -146,17 +151,24 @@ unsigned long getMemoryMap( MemoryRange * rangeArray, // Is this the last address range? - if ( bb.ebx.rx == 0 ) break; + if ( bb.ebx.rx == 0 ) { + //printf("last range\n"); + break; + } } *conMemSizePtr = conMemSize / 1024; // size in KB *extMemSizePtr = extMemSize / 1024; // size in KB + // Copy out data + bcopy((char *)BIOS_ADDR, rangeArray, ((char *)range - (char *)BIOS_ADDR)); + #if DEBUG { - for (range = rangeArray; range->length != 0; range++) { - printf("range: type %d, base 0x%x, length 0x%x\n", - range->type, (unsigned int)range->base, (unsigned int)range->length); getc(); - + int i; + printf("%d total ranges\n", count);getc(); + for (i=0, range = rangeArray; i<count; i++, range++) { + printf("range: type %d, base 0x%x, length 0x%x\n", + range->type, (unsigned int)range->base, (unsigned int)range->length); getc(); } } #endif @@ -554,6 +566,7 @@ int get_drive_info(int drive, struct driveInfo *dp) #if DEBUG print_drive_info(di); printf("uses_ebios = 0x%x\n", dp->uses_ebios); + printf("result %d\n", ret); printf("press a key->\n");getc(); #endif diff --git a/i386/libsaio/bootstruct.c b/i386/libsaio/bootstruct.c index 18c9ccd..e42b912 100644 --- a/i386/libsaio/bootstruct.c +++ b/i386/libsaio/bootstruct.c @@ -29,104 +29,76 @@ #include "libsaio.h" #include "bootstruct.h" -// CMOS access ports in I/O space. -// -#define CMOSADDR 0x70 -#define CMOSDATA 0x71 -#define HDTYPE 0x12 - /*========================================================================== - * Returns the number of active ATA drives since these will increment the - * bios device numbers of SCSI drives. - */ -static int countIDEDisks() -{ - int count = 0; - unsigned short hdtype; - -#if DEBUG - struct driveParameters param; - - printf("Reading drive parameters...\n"); - readDriveParameters(0x80, ¶m); - printf("%d fixed disk drive(s) installed\n", param.totalDrives); - for (count = 0; count < 256; count++) - { - if (readDriveParameters(count + 0x80, ¶m)) - break; - else - { - printf("Drive %d: %d cyls, %d heads, %d sectors\n", - count, param.cylinders, param.heads, param.sectors); - } - } - outb(CMOSADDR, 0x11); - printf("CMOS addr 0x11 = %x\n",inb(CMOSDATA)); - outb(CMOSADDR, 0x12); - printf("CMOS addr 0x12 = %x\n",inb(CMOSDATA)); - return count; -#endif - - outb( CMOSADDR, HDTYPE ); - hdtype = (unsigned short) inb( CMOSDATA ); - - if (hdtype & 0xF0) count++; - if (hdtype & 0x0F) count++; - return count; -} - -/*========================================================================== - * Initialize the 'kernBootStruct'. A structure of parameters passed to + * Initialize the structure of parameters passed to * the kernel by the booter. */ -KernelBootArgs_t *bootArgs; +boot_args *bootArgs; +PrivateBootInfo_t *bootInfo; +Node *gMemoryMapNode; + +static char platformName[64]; void initKernBootStruct( int biosdev ) { + Node *node; + int nameLen; static int init_done = 0; - bootArgs = (KernelBootArgs_t *)KERNSTRUCT_ADDR; - if ( !init_done ) { - bzero(bootArgs, sizeof(KernelBootArgs_t)); + bootArgs = (boot_args *)malloc(sizeof(boot_args)); + bootInfo = (PrivateBootInfo_t *)malloc(sizeof(PrivateBootInfo_t)); + if (bootArgs == 0 || bootInfo == 0) + stop("Couldn't allocate boot info\n"); + + bzero(bootArgs, sizeof(boot_args)); + bzero(bootInfo, sizeof(PrivateBootInfo_t)); // Get system memory map. Also update the size of the // conventional/extended memory for backwards compatibility. - bootArgs->memoryMapCount = - getMemoryMap( bootArgs->memoryMap, kMemoryMapCountMax, - (unsigned long *) &bootArgs->convmem, - (unsigned long *) &bootArgs->extmem ); + bootInfo->memoryMapCount = + getMemoryMap( bootInfo->memoryMap, kMemoryMapCountMax, + (unsigned long *) &bootInfo->convmem, + (unsigned long *) &bootInfo->extmem ); - if ( bootArgs->memoryMapCount == 0 ) + if ( bootInfo->memoryMapCount == 0 ) { // BIOS did not provide a memory map, systems with // discontiguous memory or unusual memory hole locations // may have problems. - bootArgs->convmem = getConventionalMemorySize(); - bootArgs->extmem = getExtendedMemorySize(); + bootInfo->convmem = getConventionalMemorySize(); + bootInfo->extmem = getExtendedMemorySize(); } - bootArgs->magicCookie = KERNBOOTMAGIC; - bootArgs->configEnd = bootArgs->config; - bootArgs->graphicsMode = TEXT_MODE; + bootInfo->configEnd = bootInfo->config; + bootArgs->Video.v_display = VGA_TEXT_MODE; - /* New style */ - /* XXX initialize bootArgs here */ + DT__Initialize(); - init_done = 1; - } + node = DT__FindNode("/", true); + if (node == 0) { + stop("Couldn't create root node"); + } + getPlatformName(platformName); + nameLen = strlen(platformName) + 1; + DT__AddProperty(node, "compatible", nameLen, platformName); + DT__AddProperty(node, "model", nameLen, platformName); - // Get number of ATA devices. + gMemoryMapNode = DT__FindNode("/chosen/memory-map", true); - bootArgs->numDrives = countIDEDisks(); + bootArgs->Version = kBootArgsVersion; + bootArgs->Revision = kBootArgsRevision; + + init_done = 1; + } // Update kernDev from biosdev. - bootArgs->kernDev = biosdev; + bootInfo->kernDev = biosdev; } @@ -136,7 +108,69 @@ void reserveKernBootStruct(void) { void *oldAddr = bootArgs; - bootArgs = (KernelBootArgs_t *)AllocateKernelMemory(sizeof(KERNBOOTSTRUCT)); - bcopy(oldAddr, bootArgs, sizeof(KernelBootArgs_t)); + bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args)); + bcopy(oldAddr, bootArgs, sizeof(boot_args)); } +void +finalizeBootStruct(void) +{ + uint32_t size; + void *addr; + int i; + EfiMemoryRange *memoryMap; + MemoryRange *range; + int memoryMapCount = bootInfo->memoryMapCount; + + if (memoryMapCount == 0) { + // XXX could make a two-part map here + stop("Unable to convert memory map into proper format\n"); + } + + // convert memory map to boot_args memory map + memoryMap = (EfiMemoryRange *)AllocateKernelMemory(sizeof(EfiMemoryRange) * memoryMapCount); + bootArgs->MemoryMap = memoryMap; + bootArgs->MemoryMapSize = sizeof(EfiMemoryRange) * memoryMapCount; + bootArgs->MemoryMapDescriptorSize = sizeof(EfiMemoryRange); + bootArgs->MemoryMapDescriptorVersion = 0; + + for (i=0; i<memoryMapCount; i++, memoryMap++) { + range = &bootInfo->memoryMap[i]; + switch(range->type) { + case kMemoryRangeACPI: + memoryMap->Type = kEfiACPIReclaimMemory; + break; + case kMemoryRangeNVS: + memoryMap->Type = kEfiACPIMemoryNVS; + break; + case kMemoryRangeUsable: + memoryMap->Type = kEfiConventionalMemory; + break; + case kMemoryRangeReserved: + default: + memoryMap->Type = kEfiReservedMemoryType; + break; + } + memoryMap->PhysicalStart = range->base; + memoryMap->VirtualStart = range->base; + memoryMap->NumberOfPages = range->length >> I386_PGSHIFT; + memoryMap->Attribute = 0; + } + + // copy bootFile into device tree + // XXX + + // add PCI info somehow into device tree + // XXX + + // Flatten device tree + DT__FlattenDeviceTree(0, &size); + addr = (void *)AllocateKernelMemory(size); + if (addr == 0) { + stop("Couldn't allocate device tree\n"); + } + + DT__FlattenDeviceTree((void **)&addr, &size); + bootArgs->deviceTreeP = (void *)addr; + bootArgs->deviceTreeLength = size; +} diff --git a/i386/libsaio/bootstruct.h b/i386/libsaio/bootstruct.h index e67002a..32711a6 100644 --- a/i386/libsaio/bootstruct.h +++ b/i386/libsaio/bootstruct.h @@ -22,6 +22,89 @@ * @APPLE_LICENSE_HEADER_END@ */ +#ifndef __BOOTSTRUCT_H +#define __BOOTSTRUCT_H + #include <pexpert/i386/boot.h> -extern KernelBootArgs_t *bootArgs; +#include "bios.h" +#include "device_tree.h" + +extern boot_args *bootArgs; +extern Node *gMemoryMapNode; + +/* + * Maximum number of boot drivers that can be loaded. + */ +#define NDRIVERS 500 + +#define CONFIG_SIZE (12 * 4096) + +#define kMemoryMapCountMax 40 + +/* + * PCI bus information. + */ +typedef struct _PCI_bus_info_t { + union { + struct { + unsigned char configMethod1 :1; + unsigned char configMethod2 :1; + unsigned char :2; + unsigned char specialCycle1 :1; + unsigned char specialCycle2 :1; + } s; + unsigned char d; + } u_bus; + unsigned char maxBusNum; + unsigned char majorVersion; + unsigned char minorVersion; + unsigned char BIOSPresent; +} PCI_bus_info_t; + +typedef struct { + unsigned long address; // address where driver was loaded + unsigned long size; // number of bytes + unsigned long type; // driver type +} driver_config_t; + +/* + * INT15, E820h - Query System Address Map. + * + * Documented in ACPI Specification Rev 2.0, + * Chapter 15 (System Address Map Interfaces). + */ + +/* + * ACPI defined memory range types. + */ +enum { + kMemoryRangeUsable = 1, // RAM usable by the OS. + kMemoryRangeReserved = 2, // Reserved. (Do not use) + kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed. + kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use) + + /* Undefined types should be treated as kMemoryRangeReserved */ +}; + +typedef struct PrivateBootInfo { + int kernDev; // device kernel was fetched from + + int convmem; // conventional memory + int extmem; // extended memory + int numBootDrivers; // number of drivers loaded + char bootFile[128]; // kernel file name + + unsigned long memoryMapCount; + MemoryRange memoryMap[kMemoryMapCountMax]; + + PCI_bus_info_t pciInfo; + + driver_config_t driverConfig[NDRIVERS]; + char * configEnd; // pointer to end of config files + char config[CONFIG_SIZE]; +} PrivateBootInfo_t; + +extern PrivateBootInfo_t *bootInfo; + +#endif /* __BOOTSTRUCT_H */ diff --git a/i386/libsaio/cache.c b/i386/libsaio/cache.c index 52a32e4..8b79dbc 100644 --- a/i386/libsaio/cache.c +++ b/i386/libsaio/cache.c @@ -100,8 +100,8 @@ void CacheInit( CICell ih, long blockSize ) long CacheRead( CICell ih, char * buffer, long long offset, long length, long cache ) { - long cnt, oldestEntry = 0, oldestTime, loadCache = 0; - CacheEntry *entry; + long cnt, oldestEntry = 0, oldestTime, loadCache = 0; + CacheEntry *entry; // See if the data can be cached. if (cache && (gCacheIH == ih) && (length == gCacheBlockSize)) { diff --git a/i386/libsaio/console.c b/i386/libsaio/console.c index 3922373..d6bdfac 100644 --- a/i386/libsaio/console.c +++ b/i386/libsaio/console.c @@ -96,7 +96,7 @@ int getchar() int printf(const char * fmt, ...) { va_list ap; - if (bootArgs->graphicsMode != TEXT_MODE) return -1; + if (bootArgs->Video.v_display != VGA_TEXT_MODE) return -1; va_start(ap, fmt); prf(fmt, ap, putchar, 0); va_end(ap); @@ -126,8 +126,14 @@ int error(const char * fmt, ...) return(0); } -void stop(const char * msg) +void stop(const char * fmt, ...) { - error("\n%s\n", msg); + va_list ap; + + printf("\n"); + va_start(ap, fmt); + prf(fmt, ap, putchar, 0); + va_end(ap); + printf("\n"); halt(); } diff --git a/i386/libsaio/device_tree.c b/i386/libsaio/device_tree.c new file mode 100644 index 0000000..067dea0 --- /dev/null +++ b/i386/libsaio/device_tree.c @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved. + */ + +#if 1 +/* + + Structures for a Flattened Device Tree + */ + +#define kPropNameLength 32 + +typedef struct DeviceTreeNodeProperty { + char name[kPropNameLength]; // NUL terminated property name + unsigned long length; // Length (bytes) of folloing prop value + // unsigned long value[1]; // Variable length value of property + // Padded to a multiple of a longword? +} DeviceTreeNodeProperty; + +typedef struct OpaqueDTEntry { + unsigned long nProperties; // Number of props[] elements (0 => end) + unsigned long nChildren; // Number of children[] elements + // DeviceTreeNodeProperty props[];// array size == nProperties + // DeviceTreeNode children[]; // array size == nChildren +} DeviceTreeNode; + +typedef char DTPropertyNameBuf[32]; +/* Entry Name Definitions (Entry Names are C-Strings)*/ +enum { + kDTMaxEntryNameLength = 31 /* Max length of a C-String Entry Name (terminator not included) */ +}; + +/* length of DTEntryNameBuf = kDTMaxEntryNameLength +1*/ +typedef char DTEntryNameBuf[32]; +#endif + +#include "libsaio.h" +#include "device_tree.h" + +#if DEBUG +#define DPRINTF(args...) printf(args) +#else +#define DPRINTF(args...) +#endif + + +void +DT__PrintTree(Node *node); + +#define RoundToLong(x) (((x) + 3) & ~3) + +static struct _DTSizeInfo { + uint32_t numNodes; + uint32_t numProperties; + uint32_t totalPropertySize; +} DTInfo; + +#define kAllocSize 4096 + +static Node *rootNode; + +static Node *freeNodes, *allocedNodes; +static Property *freeProperties, *allocedProperties; + +Property * +DT__AddProperty(Node *node, char *name, uint32_t length, void *value) +{ + Property *prop; + + DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value); + if (freeProperties == NULL) { + void *buf = malloc(kAllocSize); + int i; + + DPRINTF("Allocating more free properties\n"); + if (buf == 0) return 0; + bzero(buf, kAllocSize); + // Use the first property to record the allocated buffer + // for later freeing. + prop = (Property *)buf; + prop->next = allocedProperties; + allocedProperties = prop; + prop->value = buf; + prop++; + for (i=1; i<(kAllocSize / sizeof(Property)); i++) { + prop->next = freeProperties; + freeProperties = prop; + prop++; + } + } + prop = freeProperties; + freeProperties = prop->next; + + prop->name = name; + prop->length = length; + prop->value = value; + + // Always add to end of list + if (node->properties == 0) { + node->properties = prop; + } else { + node->last_prop->next = prop; + } + node->last_prop = prop; + prop->next = 0; + + DPRINTF("Done [0x%x]\n", prop); + + DTInfo.numProperties++; + DTInfo.totalPropertySize += RoundToLong(length); + + return prop; +} + +Node * +DT__AddChild(Node *parent, char *name) +{ + Node *node; + + if (freeNodes == NULL) { + void *buf = malloc(kAllocSize); + int i; + + DPRINTF("Allocating more free nodes\n"); + if (buf == 0) return 0; + bzero(buf, kAllocSize); + node = (Node *)buf; + // Use the first node to record the allocated buffer + // for later freeing. + node->next = allocedNodes; + allocedNodes = node; + node->children = (Node *)buf; + node++; + for (i=1; i<(kAllocSize / sizeof(Node)); i++) { + node->next = freeNodes; + freeNodes = node; + node++; + } + } + DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name); + node = freeNodes; + freeNodes = node->next; + DPRINTF("Got free node 0x%x\n", node); + DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next); + + if (parent == NULL) { + rootNode = node; + node->next = 0; + } else { + node->next = parent->children; + parent->children = node; + } + DTInfo.numNodes++; + DT__AddProperty(node, "name", strlen(name) + 1, name); + return node; +} + +void +DT__FreeProperty(Property *prop) +{ + prop->next = freeProperties; + freeProperties = prop; +} +void +DT__FreeNode(Node *node) +{ + node->next = freeNodes; + freeNodes = node; +} + +void +DT__Initialize(void) +{ + DPRINTF("DT__Initialize\n"); + + freeNodes = 0; + allocedNodes = 0; + freeProperties = 0; + allocedProperties = 0; + + DTInfo.numNodes = 0; + DTInfo.numProperties = 0; + DTInfo.totalPropertySize = 0; + + rootNode = DT__AddChild(NULL, "/"); + DPRINTF("DT__Initialize done\n"); +} + +/* + * Free up memory used by in-memory representation + * of device tree. + */ +void +DT__Finalize(void) +{ + Node *node; + Property *prop; + + DPRINTF("DT__Finalize\n"); + for (prop = allocedProperties; prop != NULL; prop = prop->next) { + free(prop->value); + } + allocedProperties = NULL; + freeProperties = NULL; + + for (node = allocedNodes; node != NULL; node = node->next) { + free((void *)node->children); + } + allocedNodes = NULL; + freeNodes = NULL; + rootNode = NULL; + + // XXX leaks any created strings + + DTInfo.numNodes = 0; + DTInfo.numProperties = 0; + DTInfo.totalPropertySize = 0; +} + +static void * +FlattenNodes(Node *node, void *buffer) +{ + Property *prop; + DeviceTreeNode *flatNode; + DeviceTreeNodeProperty *flatProp; + int count; + + if (node == 0) return buffer; + + flatNode = (DeviceTreeNode *)buffer; + buffer += sizeof(DeviceTreeNode); + + for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next) { + flatProp = (DeviceTreeNodeProperty *)buffer; + strcpy(flatProp->name, prop->name); + flatProp->length = prop->length; + buffer += sizeof(DeviceTreeNodeProperty); + bcopy(prop->value, buffer, prop->length); + buffer += RoundToLong(prop->length); + } + flatNode->nProperties = count; + + for (count = 0, node = node->children; node != 0; count++, node = node->next) { + buffer = FlattenNodes(node, buffer); + } + flatNode->nChildren = count; + + return buffer; +} + +/* + * Flatten the in-memory representation of the device tree + * into a binary DT block. + * To get the buffer size needed, call with result = 0. + * To have a buffer allocated for you, call with *result = 0. + * To use your own buffer, call with *result = &buffer. + */ + +void +DT__FlattenDeviceTree(void **buffer_p, uint32_t *length) +{ + uint32_t totalSize; + void *buf; + + DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length); + if (buffer_p) DT__PrintTree(rootNode); + + totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) + + DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) + + DTInfo.totalPropertySize; + + DPRINTF("Total size 0x%x\n", totalSize); + if (buffer_p != 0) { + if (totalSize == 0) { + buf = 0; + } else { + if (*buffer_p == 0) { + buf = malloc(totalSize); + } else { + buf = *buffer_p; + } + bzero(buf, totalSize); + + FlattenNodes(rootNode, buf); + } + *buffer_p = buf; + } + if (length) + *length = totalSize; +} + +char * +DT__GetName(Node *node) +{ + Property *prop; + + //DPRINTF("DT__GetName(0x%x)\n", node); + //DPRINTF("Node properties = 0x%x\n", node->properties); + for (prop = node->properties; prop; prop = prop->next) { + //DPRINTF("Prop '%s'\n", prop->name); + if (strcmp(prop->name, "name") == 0) { + return prop->value; + } + } + //DPRINTF("DT__GetName returns 0\n"); + return "(null)"; +} + +Node * +DT__FindNode(char *path, bool createIfMissing) +{ + Node *node, *child; + DTPropertyNameBuf nameBuf; + char *bp; + int i; + + DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing); + + // Start at root + node = rootNode; + DPRINTF("root = 0x%x\n", rootNode); + + while (node) { + // Skip leading slash + while (*path == '/') path++; + + for (i=0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++) *bp = *path; + *bp = '\0'; + + if (nameBuf[0] == '\0') { + // last path entry + break; + } + DPRINTF("Node '%s'\n", nameBuf); + + for (child = node->children; child != 0; child = child->next) { + DPRINTF("Child 0x%x\n", child); + if (strcmp(DT__GetName(child), nameBuf) == 0) { + break; + } + } + if (child == 0 && createIfMissing) { + DPRINTF("Creating node\n"); + char *str = malloc(strlen(nameBuf) + 1); + // XXX this will leak + strcpy(str, nameBuf); + + child = DT__AddChild(node, str); + } + node = child; + } + return node; +} + +void +DT__PrintNode(Node *node, int level) +{ + char spaces[10], *cp = spaces; + Property *prop; + + if (level > 9) level = 9; + while (level--) *cp++ = ' '; + *cp = '\0'; + + printf("%s===Node===\n", spaces); + for (prop = node->properties; prop; prop = prop->next) { + char c = *((char *)prop->value); + if (prop->length < 64 && ( + strcmp(prop->name, "name") == 0 || + (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || c == '_')) { + printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value); + } else { + printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length); + } + } + printf("%s==========\n", spaces); +} + +static void +_PrintTree(Node *node, int level) +{ + DT__PrintNode(node, level); + level++; + for (node = node->children; node; node = node->next) + _PrintTree(node, level); +} + +void +DT__PrintTree(Node *node) +{ + if (node == 0) node = rootNode; + _PrintTree(node, 0); +} + +#if DEBUG + +void +DT__PrintFlattenedNode(DTEntry entry, int level) +{ + char spaces[10], *cp = spaces; + DTPropertyIterator propIter; + char *name; + void *prop; + int propSize; + + if (level > 9) level = 9; + while (level--) *cp++ = ' '; + *cp = '\0'; + + printf("%s===Entry %p===\n", spaces, entry); + if (kSuccess != DTCreatePropertyIterator(entry, &propIter)) { + printf("Couldn't create property iterator\n"); + return; + } + while( kSuccess == DTIterateProperties( propIter, &name)) { + if( kSuccess != DTGetProperty( entry, name, &prop, &propSize )) + continue; + printf("%s Property %s = %s\n", spaces, name, prop); + } + DTDisposePropertyIterator(propIter); + + printf("%s==========\n", spaces); +} + +static void +_PrintFlattenedTree(DTEntry entry, int level) +{ + DTEntryIterator entryIter; + + PrintFlattenedNode(entry, level); + + if (kSuccess != DTCreateEntryIterator(entry, &entryIter)) { + printf("Couldn't create entry iterator\n"); + return; + } + level++; + while (kSuccess == DTIterateEntries( entryIter, &entry )) { + _PrintFlattenedTree(entry, level); + } + DTDisposeEntryIterator(entryIter); +} + +void +DT__PrintFlattenedTree(DTEntry entry) +{ + _PrintFlattenedTree(entry, 0); +} + + +int +main(int argc, char **argv) +{ + DTEntry dtEntry; + DTPropertyIterator propIter; + DTEntryIterator entryIter; + void *prop; + int propSize; + char *name; + void *flatTree; + uint32_t flatSize; + + Node *node; + + node = AddChild(NULL, "device-tree"); + AddProperty(node, "potato", 4, "foo"); + AddProperty(node, "chemistry", 4, "bar"); + AddProperty(node, "physics", 4, "baz"); + + node = AddChild(node, "dev"); + AddProperty(node, "one", 4, "one"); + AddProperty(node, "two", 4, "two"); + AddProperty(node, "three", 6, "three"); + + node = AddChild(rootNode, "foo"); + AddProperty(node, "aaa", 4, "aab"); + AddProperty(node, "bbb", 4, "bbc"); + AddProperty(node, "cccc", 6, "ccccd"); + + node = FindNode("/this/is/a/test", 1); + AddProperty(node, "dddd", 12, "abcdefghijk"); + + printf("In-memory tree:\n\n"); + + PrintTree(rootNode); + + FlattenDeviceTree(&flatTree, &flatSize); + + printf("Flat tree = %p, size %d\n", flatTree, flatSize); + + dtEntry = (DTEntry)flatTree; + + printf("\n\nPrinting flat tree\n\n"); + + DTInit(dtEntry); + + PrintFlattenedTree((DTEntry)flatTree); +#if 0 + printf("=== Entry %p ===\n", dtEntry); + if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) { + printf("Couldn't create property iterator\n"); + return 1; + } + while( kSuccess == DTIterateProperties( propIter, &name)) { + if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize )) + continue; + printf(" Property %s = %s\n", name, prop); + } + DTDisposePropertyIterator(propIter); + printf("========\n"); + + if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter)) { + printf("Couldn't create entry iterator\n"); + return 1; + } + while (kSuccess == DTIterateEntries( entryIter, &dtEntry )) { + printf("=== Entry %p ===\n", dtEntry); + + if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) { + printf("Couldn't create property iterator\n"); + return 1; + } + while( kSuccess == DTIterateProperties( propIter, &name)) { + if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize )) + continue; + printf(" Property %s = %s\n", name, prop); + } + DTDisposePropertyIterator(propIter); + printf("========\n"); + } + DTDisposeEntryIterator(entryIter); +#endif + + return 0; +} + +#endif + diff --git a/i386/libsaio/device_tree.h b/i386/libsaio/device_tree.h new file mode 100644 index 0000000..530cfaa --- /dev/null +++ b/i386/libsaio/device_tree.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved. + */ + +#ifndef __DEVICE_TREE_H +#define __DEVICE_TREE_H + +#include <stdbool.h> +#include <stdint.h> + +typedef struct _Property { + char * name; + uint32_t length; + void * value; + + struct _Property * next; +} Property; + +typedef struct _Node { + struct _Property * properties; + struct _Property * last_prop; + + struct _Node * children; + + struct _Node * next; +} Node; + + +extern Property * +DT__AddProperty(Node *node, char *name, uint32_t length, void *value); + +extern Node * +DT__AddChild(Node *parent, char *name); + +Node * +DT__FindNode(char *path, bool createIfMissing); + +extern void +DT__FreeProperty(Property *prop); + +extern void +DT__FreeNode(Node *node); + +extern char * +DT__GetName(Node *node); + +void +DT__Initialize(void); + +/* + * Free up memory used by in-memory representation + * of device tree. + */ +extern void +DT__Finalize(void); + +void +DT__FlattenDeviceTree(void **result, uint32_t *length); + + +#endif /* __DEVICE_TREE_H */ diff --git a/i386/libsaio/disk.c b/i386/libsaio/disk.c index aae0501..afb1057 100644 --- a/i386/libsaio/disk.c +++ b/i386/libsaio/disk.c @@ -44,10 +44,14 @@ * All rights reserved. */ +#define UFS_SUPPORT 1 + #include "bootstruct.h" #include "libsaio.h" #include "fdisk.h" +#if UFS_SUPPORT #include "ufs.h" +#endif #include "hfs.h" #include "ntfs.h" #include "msdos.h" @@ -101,6 +105,7 @@ static int getDriveInfo( int biosdev, struct driveInfo *dip ) cc = get_drive_info(biosdev, &cached_di); if (cc < 0) { cached_di.valid = 0; + DEBUG_DISK(("get_drive_info returned error\n")); return (-1); // BIOS call error } } @@ -282,6 +287,7 @@ static int Biosread( int biosdev, unsigned int secno ) //========================================================================== static int readBytes( int biosdev, unsigned int blkno, + unsigned int byteoff, unsigned int byteCount, void * buffer ) { @@ -292,7 +298,7 @@ static int readBytes( int biosdev, unsigned int blkno, DEBUG_DISK(("%s: dev %x block %x [%d] -> 0x%x...", __FUNCTION__, biosdev, blkno, byteCount, (unsigned)cbuf)); - for ( ; byteCount; cbuf += BPS, blkno++ ) + for ( ; byteCount; cbuf += copy_len, blkno++ ) { error = Biosread( biosdev, blkno ); if ( error ) @@ -301,9 +307,10 @@ static int readBytes( int biosdev, unsigned int blkno, return (-1); } - copy_len = (byteCount > BPS) ? BPS : byteCount; - bcopy( biosbuf, cbuf, copy_len ); + copy_len = ((byteCount + byteoff) > BPS) ? (BPS - byteoff) : byteCount; + bcopy( biosbuf + byteoff, cbuf, copy_len ); byteCount -= copy_len; + byteoff = 0; } DEBUG_DISK(("done\n")); @@ -427,6 +434,7 @@ static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff, FSReadFile readFunc, FSGetDirEntry getdirFunc, FSGetFileBlock getBlockFunc, + FSGetUUID getUUIDFunc, BVGetDescription getDescriptionFunc, int probe, int type ) { @@ -443,6 +451,7 @@ static BVRef newFDiskBVRef( int biosdev, int partno, unsigned int blkoff, bvr->fs_readfile = readFunc; bvr->fs_getdirentry = getdirFunc; bvr->fs_getfileblock= getBlockFunc; + bvr->fs_getuuid = getUUIDFunc; bvr->description = getDescriptionFunc ? getDescriptionFunc : getVolumeDescription; bvr->type = type; @@ -488,6 +497,7 @@ BVRef newAPMBVRef( int biosdev, int partno, unsigned int blkoff, FSReadFile readFunc, FSGetDirEntry getdirFunc, FSGetFileBlock getBlockFunc, + FSGetUUID getUUIDFunc, BVGetDescription getDescriptionFunc, int probe, int type ) { @@ -503,6 +513,7 @@ BVRef newAPMBVRef( int biosdev, int partno, unsigned int blkoff, bvr->fs_readfile = readFunc; bvr->fs_getdirentry = getdirFunc; bvr->fs_getfileblock= getBlockFunc; + bvr->fs_getuuid = getUUIDFunc; bvr->description = getDescriptionFunc ? getDescriptionFunc : getVolumeDescription; bvr->type = type; @@ -561,7 +572,9 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) struct DiskBVMap * map; int partno = -1; BVRef bvr; +#if UFS_SUPPORT BVRef booterUFS = NULL; +#endif int spc; struct driveInfo di; boot_drive_info_t *dp; @@ -599,6 +612,7 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) switch ( part->systid ) { +#if UFS_SUPPORT case FDISK_UFS: bvr = newFDiskBVRef( biosdev, partno, @@ -609,10 +623,12 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) UFSReadFile, UFSGetDirEntry, UFSGetFileBlock, + UFSGetUUID, UFSGetDescription, 0, kBIOSDevTypeHardDrive); break; +#endif case FDISK_HFS: bvr = newFDiskBVRef( @@ -624,11 +640,13 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) HFSReadFile, HFSGetDirEntry, HFSGetFileBlock, + HFSGetUUID, HFSGetDescription, 0, kBIOSDevTypeHardDrive); break; +#if UFS_SUPPORT case FDISK_BOOTER: booterUFS = newFDiskBVRef( biosdev, partno, @@ -639,17 +657,19 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) UFSReadFile, UFSGetDirEntry, UFSGetFileBlock, + UFSGetUUID, UFSGetDescription, 0, kBIOSDevTypeHardDrive); break; +#endif case FDISK_NTFS: bvr = newFDiskBVRef( biosdev, partno, part->relsect, part, - 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, NTFSGetDescription, 0, kBIOSDevTypeHardDrive); @@ -660,7 +680,7 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) biosdev, partno, part->relsect, part, - 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, kBIOSDevTypeHardDrive); break; } @@ -673,6 +693,7 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) } } +#if UFS_SUPPORT // Booting from a CD with an UFS filesystem embedded // in a booter partition. @@ -685,6 +706,7 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) } else free( booterUFS ); } +#endif } } while (0); @@ -707,6 +729,7 @@ static BVRef diskScanFDiskBootVolumes( int biosdev, int * countPtr ) HFSReadFile, HFSGetDirEntry, HFSGetFileBlock, + HFSGetUUID, 0, kBIOSDevTypeHardDrive); bvr->next = map->bvr; @@ -731,7 +754,7 @@ static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr ) void *buffer = malloc(BPS); /* Check for alternate block size */ - if (readBytes( biosdev, 0, BPS, buffer ) != 0) { + if (readBytes( biosdev, 0, 0, BPS, buffer ) != 0) { return NULL; } block0_p = buffer; @@ -765,7 +788,7 @@ static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr ) gDiskBVMap = map; for (i=0; i<npart; i++) { - error = readBytes( biosdev, (kAPMSector + i) * factor, blksize, buffer ); + error = readBytes( biosdev, (kAPMSector + i) * factor, 0, blksize, buffer ); if (error || OSSwapBigToHostInt16(dpme_p->dpme_signature) != DPME_SIGNATURE) { break; @@ -792,6 +815,7 @@ static BVRef diskScanAPMBootVolumes( int biosdev, int * countPtr ) HFSReadFile, HFSGetDirEntry, HFSGetFileBlock, + HFSGetUUID, HFSGetDescription, 0, kBIOSDevTypeHardDrive); @@ -978,7 +1002,7 @@ int readBootSector( int biosdev, unsigned int secno, void * buffer ) bootSector = gBootSector; } - error = readBytes( biosdev, secno, BPS, bootSector ); + error = readBytes( biosdev, secno, 0, BPS, bootSector ); if ( error || bootSector->signature != DISK_SIGNATURE ) return -1; @@ -991,6 +1015,7 @@ int readBootSector( int biosdev, unsigned int secno, void * buffer ) void diskSeek( BVRef bvr, long long position ) { bvr->fs_boff = position / BPS; + bvr->fs_byteoff = position % BPS; } //========================================================================== @@ -1000,6 +1025,7 @@ int diskRead( BVRef bvr, long addr, long length ) { return readBytes( bvr->biosdev, bvr->fs_boff + bvr->part_boff, + bvr->fs_byteoff, length, (void *) addr ); } @@ -1079,13 +1105,13 @@ int rawDiskWrite( BVRef bvr, unsigned int secno, void *buffer, unsigned int len return 0; } -void turnOffFloppy(void) + +int diskIsCDROM(BVRef bvr) { - /* - * Disable floppy: - * Hold controller in reset, - * disable DMA and IRQ, - * turn off floppy motors. - */ - outb(0x3F2, 0x00); + struct driveInfo di; + + if (getDriveInfo(bvr->biosdev, &di) == 0 && di.no_emulation) { + return 1; + } + return 0; } diff --git a/i386/libsaio/hfs.c b/i386/libsaio/hfs.c index 5f1c48f..468843d 100644 --- a/i386/libsaio/hfs.c +++ b/i386/libsaio/hfs.c @@ -54,6 +54,7 @@ static HFSMasterDirectoryBlock *gHFSMDB; static char *gHFSPlusHeader; static HFSPlusVolumeHeader *gHFSPlus; static char *gLinkTemp; +static long long gVolID; static char *gTempStr; #else /* !__i386__ */ @@ -71,10 +72,11 @@ static HFSMasterDirectoryBlock *gHFSMDB =(HFSMasterDirectoryBlock*)gHFSMdbVib; static char gHFSPlusHeader[kBlockSize]; static HFSPlusVolumeHeader *gHFSPlus =(HFSPlusVolumeHeader*)gHFSPlusHeader; static char gLinkTemp[64]; +static long long gVolID; #endif /* !__i386__ */ -static long ReadFile(void *file, long *length, void *base, long offset); +static long ReadFile(void *file, unsigned long *length, void *base, long offset); static long GetCatalogEntryInfo(void *entry, long *flags, long *time, FinderInfo *finderInfo, long *infoValid); static long ResolvePathToCatalogEntry(char *filePath, long *flags, @@ -102,7 +104,7 @@ static long CompareHFSPlusCatalogKeys(void *key, void *testKey); static long CompareHFSExtentsKeys(void *key, void *testKey); static long CompareHFSPlusExtentsKeys(void *key, void *testKey); -extern long FastRelString(char *str1, char *str2); +extern long FastRelString(u_int8_t *str1, u_int8_t *str2); extern long FastUnicodeCompare(u_int16_t *uniStr1, u_int32_t len1, u_int16_t *uniStr2, u_int32_t len2); extern long BinaryUnicodeCompare(u_int16_t *uniStr1, u_int32_t len1, @@ -166,6 +168,9 @@ long HFSInitPartition(CICell ih) CacheInit(ih, gCacheBlockSize); gCurrentIH = ih; + // grab the 64 bit volume ID + bcopy(&gHFSMDB->drFndrInfo[6], &gVolID, 8); + // Get the Catalog BTree node size. extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec; extentSize = SWAP_BE32(gHFSMDB->drCTFlSize); @@ -207,6 +212,9 @@ long HFSInitPartition(CICell ih) CacheInit(ih, gCacheBlockSize); gCurrentIH = ih; + // grab the 64 bit volume ID + bcopy(&gHFSPlus->finderInfo[24], &gVolID, 8); + // Get the Catalog BTree node size. extent = &gHFSPlus->catalogFile.extents; extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize); @@ -386,10 +394,17 @@ HFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock) return 0; } +long HFSGetUUID(CICell ih, char *uuidStr) +{ + if (HFSInitPartition(ih) == -1) return -1; + if (gVolID == 0LL) return -1; + + return CreateUUIDString((uint8_t*)(&gVolID), sizeof(gVolID), uuidStr); +} // Private Functions -static long ReadFile(void * file, long * length, void * base, long offset) +static long ReadFile(void * file, unsigned long * length, void * base, long offset) { void *extents; long fileID; @@ -399,7 +414,7 @@ static long ReadFile(void * file, long * length, void * base, long offset) if (gIsHFSPlus) { fileID = SWAP_BE32(hfsPlusFile->fileID); - fileLength = SWAP_BE64(hfsPlusFile->dataFork.logicalSize); + fileLength = (long)SWAP_BE64(hfsPlusFile->dataFork.logicalSize); extents = &hfsPlusFile->dataFork.extents; } else { fileID = SWAP_BE32(hfsFile->fileID); @@ -412,17 +427,14 @@ static long ReadFile(void * file, long * length, void * base, long offset) return -1; } - if (*length == 0 || (offset + *length) > fileLength) { + if ((*length == 0) || ((offset + *length) > fileLength)) { *length = fileLength - offset; } - // XXX -#if 0 if (*length > kLoadSize) { printf("File is too large.\n"); return -1; } -#endif *length = ReadExtent((char *)extents, fileLength, fileID, offset, *length, (char *)base, 0); @@ -496,7 +508,7 @@ static long ResolvePathToCatalogEntry(char * filePath, long * flags, void * entry, long dirID, long * dirIndex) { char *restPath; - long result, cnt, subFolderID, tmpDirIndex; + long result, cnt, subFolderID = 0, tmpDirIndex; HFSPlusCatalogFile *hfsPlusFile; // Copy the file name to gTempStr @@ -523,10 +535,11 @@ static long ResolvePathToCatalogEntry(char * filePath, long * flags, subFolderID = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->folderID); else subFolderID = SWAP_BE32(((HFSCatalogFolder *)entry)->folderID); + } + if ((*flags & kFileTypeMask) == kFileTypeDirectory) result = ResolvePathToCatalogEntry(restPath, flags, entry, subFolderID, dirIndex); - } if (gIsHFSPlus && ((*flags & kFileTypeMask) == kFileTypeFlat)) { hfsPlusFile = (HFSPlusCatalogFile *)entry; @@ -577,10 +590,10 @@ static long GetCatalogEntry(long * dirIndex, char ** name, if (gIsHFSPlus) { utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode, SWAP_BE16(((HFSPlusCatalogKey *)testKey)->nodeName.length), - gTempStr, 256, OSBigEndian); + (u_int8_t *)gTempStr, 256, OSBigEndian); } else { strncpy(gTempStr, - &((HFSCatalogKey *)testKey)->nodeName[1], + (const char *)&((HFSCatalogKey *)testKey)->nodeName[1], ((HFSCatalogKey *)testKey)->nodeName[0]); } *name = gTempStr; @@ -612,14 +625,14 @@ static long ReadCatalogEntry(char * fileName, long dirID, hfsPlusKey->parentID = SWAP_BE32(dirID); length = strlen(fileName); if (length > 255) length = 255; - utf_decodestr(fileName, hfsPlusKey->nodeName.unicode, + utf_decodestr((u_int8_t *)fileName, hfsPlusKey->nodeName.unicode, &(hfsPlusKey->nodeName.length), 512, OSBigEndian); } else { hfsKey->parentID = SWAP_BE32(dirID); length = strlen(fileName); if (length > 31) length = 31; hfsKey->nodeName[0] = length; - strncpy(hfsKey->nodeName + 1, fileName, length); + strncpy((char *)(hfsKey->nodeName + 1), fileName, length); } return ReadBTreeEntry(kBTreeCatalog, &key, entry, dirIndex); diff --git a/i386/libsaio/hfs.h b/i386/libsaio/hfs.h index 765106e..eba6fd6 100644 --- a/i386/libsaio/hfs.h +++ b/i386/libsaio/hfs.h @@ -28,3 +28,4 @@ extern long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, FinderInfo * finderInfo, long * infoValid); extern void HFSGetDescription(CICell ih, char *str, long strMaxLen); extern long HFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock); +extern long HFSGetUUID(CICell ih, char *uuidStr); diff --git a/i386/libsaio/hfs_compare.c b/i386/libsaio/hfs_compare.c index 7a365f6..ec126a9 100644 --- a/i386/libsaio/hfs_compare.c +++ b/i386/libsaio/hfs_compare.c @@ -74,7 +74,7 @@ InitCompareTables(void) // //_______________________________________________________________________ -int32_t FastRelString(char * str1, char * str2) +int32_t FastRelString(u_int8_t * str1, u_int8_t * str2) { int32_t bestGuess; u_int8_t length, length2; diff --git a/i386/libsaio/load.c b/i386/libsaio/load.c index 77f9f8d..30e549d 100644 --- a/i386/libsaio/load.c +++ b/i386/libsaio/load.c @@ -86,7 +86,7 @@ long DecodeMachO(void *binary, entry_t *rentry, char **raddr, int *rsize) unsigned int vmend = 0; unsigned long cnt; long ret = -1; - unsigned int entry; + unsigned int entry = 0; gBinaryAddress = (unsigned long)binary; diff --git a/i386/libsaio/md5c.c b/i386/libsaio/md5c.c new file mode 100644 index 0000000..a78d0e5 --- /dev/null +++ b/i386/libsaio/md5c.c @@ -0,0 +1,344 @@ +/* + * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + * + * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + * rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD5 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD5 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software for any particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this + * documentation and/or software. + * + * $Id: md5c.c,v 1.1 2005/06/24 22:47:12 curtisg Exp $ + * + * This code is the same as the code published by RSA Inc. It has been + * edited for clarity and style only. + */ + +#include <sys/types.h> + +#ifdef KERNEL +#include <sys/systm.h> +#else +#include <string.h> +#endif + +#include <sys/md5.h> + + +#ifdef KERNEL +#define memset(x,y,z) bzero(x,z); +#define memcpy(x,y,z) bcopy(y, x, z) +#endif + +#if defined(__i386__) || defined(__alpha__) +#define Encode memcpy +#define Decode memcpy +#else /* __i386__ */ + +/* + * Encodes input (u_int32_t) into output (unsigned char). Assumes len is + * a multiple of 4. + */ + +/* XXX not prototyped, and not compatible with memcpy(). */ +static void +Encode (output, input, len) + unsigned char *output; + u_int32_t *input; + unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* + * Decodes input (unsigned char) into output (u_int32_t). Assumes len is + * a multiple of 4. + */ + +static void +Decode (output, input, len) + u_int32_t *output; + const unsigned char *input; + unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) | + (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24); +} +#endif /* i386 */ + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* + * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + * Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +static void MD5Transform (u_int32_t state[4], const unsigned char block[64]); + +/* MD5 initialization. Begins an MD5 operation, writing a new context. */ + +void +MD5Init (context) + MD5_CTX *context; +{ + + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* + * MD5 block update operation. Continues an MD5 message-digest + * operation, processing another message block, and updating the + * context. + */ + +void +MD5Update (context, input, inputLen) + MD5_CTX *context; + const unsigned char *input; + unsigned int inputLen; +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((u_int32_t)inputLen << 3)) + < ((u_int32_t)inputLen << 3)) + context->count[1]++; + context->count[1] += ((u_int32_t)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. */ + if (inputLen >= partLen) { + memcpy((void *)&context->buffer[index], (const void *)input, + partLen); + MD5Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy ((void *)&context->buffer[index], (const void *)&input[i], + inputLen-i); +} + +/* + * MD5 padding. Adds padding followed by original length. + */ + +void +MD5Pad (context) + MD5_CTX *context; +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. */ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); +} + +/* + * MD5 finalization. Ends an MD5 message-digest operation, writing the + * the message digest and zeroizing the context. + */ + +void +MD5Final (digest, context) + unsigned char digest[16]; + MD5_CTX *context; +{ + /* Do padding. */ + MD5Pad (context); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. */ + memset ((void *)context, 0, sizeof (*context)); +} + +/* MD5 basic transformation. Transforms state based on block. */ + +static void +MD5Transform (state, block) + u_int32_t state[4]; + const unsigned char block[64]; +{ + u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. */ + memset ((void *)x, 0, sizeof (x)); +} diff --git a/i386/libsaio/memory.c b/i386/libsaio/memory.c index a06026f..a7980eb 100644 --- a/i386/libsaio/memory.c +++ b/i386/libsaio/memory.c @@ -25,6 +25,7 @@ #include "sl.h" #include "saio_internal.h" #include "bootstruct.h" +#include "device_tree.h" static long gImageLastKernelAddr; @@ -32,6 +33,28 @@ static long gImageLastKernelAddr; #define RoundPage(x) ((((unsigned)(x)) + kPageSize - 1) & ~(kPageSize - 1)) +long +AllocateMemoryRange(char * rangeName, long start, long length, long type) +{ + char *nameBuf; + uint32_t *buffer; + + nameBuf = malloc(strlen(rangeName) + 1); + if (nameBuf == 0) return -1; + strcpy(nameBuf, rangeName); + + buffer = malloc(2 * sizeof(uint32_t)); + if (buffer == 0) return -1; + + buffer[0] = start; + buffer[1] = length; + + DT__AddProperty(gMemoryMapNode, nameBuf, 2 * sizeof(uint32_t), (char *)buffer); + + return 0; +} + +#if 0 long AllocateMemoryRange(char * rangeName, long start, long length, long type) { @@ -50,6 +73,7 @@ AllocateMemoryRange(char * rangeName, long start, long length, long type) } return 0; } +#endif long AllocateKernelMemory( long inSize ) diff --git a/i386/libsaio/misc.c b/i386/libsaio/misc.c index 43d624a..64a6221 100644 --- a/i386/libsaio/misc.c +++ b/i386/libsaio/misc.c @@ -96,3 +96,47 @@ void enableA20() while (inb(PORT_B) & KB_INFULL); /* wait until done */ } +static inline void +do_cpuid(uint32_t selector, uint32_t *data) +{ + asm volatile ("cpuid" + : "=a" (data[0]), + "=b" (data[1]), + "=c" (data[2]), + "=d" (data[3]) + : "a"(selector)); +} + + +//========================================================================== +// Check to see that this is a supported hardware configuration. +// If this hardware is supported, return 0. +// If this hardware is not supported, return an error code. + +int +checkForSupportedHardware() +{ + uint32_t cpuid_result[4]; + + do_cpuid(1, cpuid_result); + if ((cpuid_result[3] & 0x04000000) == 0) { + // Missing SSE2 + return 2; + } + return 0; +} + +#ifndef BOOT1 + +//========================================================================== +// Return the platform name for this hardware. +// + +void +getPlatformName(char *nameBuf) +{ + strcpy(nameBuf, "ACPI"); +} + +#endif + diff --git a/i386/libsaio/msdos.c b/i386/libsaio/msdos.c index 1797d49..be9574c 100644 --- a/i386/libsaio/msdos.c +++ b/i386/libsaio/msdos.c @@ -129,7 +129,7 @@ MSDOSGetDescription(CICell ih, char *str, long strMaxLen) int rootDirSectors; int i, finished; char *buf; - unsigned char label[LABEL_LENGTH+1]; + char label[LABEL_LENGTH+1]; DLOG(0); buf = (char *)malloc(MAX_DOS_BLOCKSIZE); @@ -197,7 +197,7 @@ MSDOSGetDescription(CICell ih, char *str, long strMaxLen) u_int8_t *rootDirBuffer; int j; - rootDirBuffer = (char *)malloc(MAX_DOS_BLOCKSIZE); + rootDirBuffer = (u_int8_t *)malloc(MAX_DOS_BLOCKSIZE); DLOG(8); firstRootDirSecNum = OSSwapLittleToHostInt16(b33->bpbResSectors) + @@ -216,7 +216,7 @@ MSDOSGetDescription(CICell ih, char *str, long strMaxLen) else if (dirp->deAttributes == ATTR_WIN95) continue; else if (dirp->deAttributes & ATTR_VOLUME) { - strncpy(label, dirp->deName, LABEL_LENGTH); + strncpy(label, (char *)dirp->deName, LABEL_LENGTH); finished = true; break; } @@ -273,7 +273,7 @@ MSDOSGetDescription(CICell ih, char *str, long strMaxLen) continue; else if (dirp->deAttributes & ATTR_VOLUME) { DLOG(0x31); - strncpy(label, dirp->deName, LABEL_LENGTH); + strncpy(label, (char *)dirp->deName, LABEL_LENGTH); finished = true; break; } @@ -310,10 +310,10 @@ MSDOSGetDescription(CICell ih, char *str, long strMaxLen) /* else look in the boot blocks */ if (str[0] == '\0') { if (OSSwapLittleToHostInt16(b50->bpbRootDirEnts) == 0) { /* It's FAT32 */ - strncpy(label, ((struct extboot *)bsp->bs710.bsExt)->exVolumeLabel, LABEL_LENGTH); + strncpy(label, (char *)((struct extboot *)bsp->bs710.bsExt)->exVolumeLabel, LABEL_LENGTH); } else if (((struct extboot *)bsp->bs50.bsExt)->exBootSignature == EXBOOTSIG) { - strncpy(label, ((struct extboot *)bsp->bs50.bsExt)->exVolumeLabel, LABEL_LENGTH); + strncpy(label, (char *)((struct extboot *)bsp->bs50.bsExt)->exVolumeLabel, LABEL_LENGTH); } } diff --git a/i386/libsaio/nbp.c b/i386/libsaio/nbp.c index a2b176c..552aa67 100644 --- a/i386/libsaio/nbp.c +++ b/i386/libsaio/nbp.c @@ -64,7 +64,7 @@ static long NBPLoadFile(CICell ih, char * filePath) nbpCommandTFTPReadFile_s cmd; UInt32 ret; - strcpy(cmd.filename, filePath); + strcpy((char *)cmd.filename, filePath); cmd.status = nbpStatusFailed; cmd.bufferSize = TFTP_LEN; cmd.buffer = TFTP_ADDR; diff --git a/i386/libsaio/ntfs.c b/i386/libsaio/ntfs.c index b3fbbc7..d4226f2 100644 --- a/i386/libsaio/ntfs.c +++ b/i386/libsaio/ntfs.c @@ -92,7 +92,7 @@ ntfs_fixup( return (ERROR); } *cfxp = *fxp; - ((caddr_t) cfxp) += bytesPerSector; + cfxp = (u_int16_t *)(((caddr_t)cfxp) + bytesPerSector); } return (0); } @@ -141,7 +141,7 @@ ntfs_find_attr( } static int -memcmp(char *p1, char *p2, int len) +memcmp(const char *p1, const char *p2, int len) { while (len--) { if (*p1++ != *p2++) @@ -199,7 +199,7 @@ NTFSGetDescription(CICell ih, char *str, long strMaxLen) /* * Check the "NTFS " signature. */ - if (memcmp(boot->bf_sysid, "NTFS ", 8) != 0) + if (memcmp((const char *)boot->bf_sysid, "NTFS ", 8) != 0) { goto error; } @@ -295,7 +295,7 @@ NTFSGetDescription(CICell ih, char *str, long strMaxLen) str[0] = '\0'; - utf_encodestr( nameAttr, nameSize / 2, str, strMaxLen, OSLittleEndian ); + utf_encodestr( nameAttr, nameSize / 2, (u_int8_t *)str, strMaxLen, OSLittleEndian ); free(buf); return; diff --git a/i386/libsaio/saio_internal.h b/i386/libsaio/saio_internal.h index a0d2d77..4923263 100644 --- a/i386/libsaio/saio_internal.h +++ b/i386/libsaio/saio_internal.h @@ -76,6 +76,7 @@ extern void sleep(int n); extern void initKernBootStruct(int biosdev); extern void reserveKernBootStruct(void); extern void copyKernBootStruct(void); +extern void finalizeBootStruct(void); /* cache.c */ extern void CacheInit(CICell ih, long blockSize); @@ -90,12 +91,13 @@ extern int getchar(void); extern int printf(const char *format, ...); extern int error(const char *format, ...); extern int verbose(const char *format, ...); -extern void stop(const char *message); +extern void stop(const char *format, ...); /* disk.c */ extern BVRef diskScanBootVolumes(int biosdev, int *count); extern void diskSeek(BVRef bvr, long long position); extern int diskRead(BVRef bvr, long addr, long length); +extern int diskIsCDROM(BVRef bvr); extern int rawDiskRead(BVRef bvr, unsigned int secno, void *buffer, unsigned int len); extern int rawDiskWrite(BVRef bvr, unsigned int secno, void *buffer, unsigned int len); extern int readBootSector(int biosdev, unsigned int secno, void *buffer); @@ -118,6 +120,8 @@ long AllocateMemoryRange(char * rangeName, long start, long length, long type); /* misc.c */ extern void enableA20(void); +extern int checkForSupportedHardware(); +extern void getPlatformName(char *nameBuf); /* nbp.c */ extern UInt32 nbpUnloadBaseCode(); @@ -126,7 +130,7 @@ extern BVRef nbpScanBootVolumes(int biosdev, int *count); /* stringTable.c */ extern char * newStringFromList(char **list, int *size); extern int stringLength(const char *table, int compress); -extern BOOL getValueForStringTableKey(const char *table, const char *key, const char **val, int *size); +extern BOOL getValueForConfigTableKey(const char *table, const char *key, const char **val, int *size); extern BOOL removeKeyFromTable(const char *key, char *table); extern char * newStringForStringTableKey(char *table, char *key); extern char * newStringForKey(char *key); @@ -149,6 +153,8 @@ extern long GetDirEntry(const char *dirSpec, long *dirIndex, const char **name extern long GetFileInfo(const char *dirSpec, const char *name, long *flags, long *time); extern long GetFileBlock(const char *fileSpec, unsigned long long *firstBlock); +extern long GetFSUUID(char *spec, char *uuidStr); +extern long CreateUUIDString(uint8_t uubytes[], int nbytes, char *uuidStr); extern int openmem(char *buf, int len); extern int open(const char *str, int how); extern int close(int fdesc); diff --git a/i386/libsaio/saio_types.h b/i386/libsaio/saio_types.h index e7b6338..0d03099 100644 --- a/i386/libsaio/saio_types.h +++ b/i386/libsaio/saio_types.h @@ -57,6 +57,52 @@ struct driveParameters { int totalDrives; }; + +/* + * BIOS drive information. + */ +struct boot_drive_info { + struct drive_params { + unsigned short buf_size; + unsigned short info_flags; + unsigned long phys_cyls; + unsigned long phys_heads; + unsigned long phys_spt; + unsigned long long phys_sectors; + unsigned short phys_nbps; + unsigned short dpte_offset; + unsigned short dpte_segment; + unsigned short key; + unsigned char path_len; + unsigned char reserved1; + unsigned short reserved2; + unsigned char bus_type[4]; + unsigned char interface_type[8]; + unsigned char interface_path[8]; + unsigned char dev_path[8]; + unsigned char reserved3; + unsigned char checksum; + } params __attribute__((packed)); + struct drive_dpte { + unsigned short io_port_base; + unsigned short control_port_base; + unsigned char head_flags; + unsigned char vendor_info; + unsigned char irq : 4; + unsigned char irq_unused : 4; + unsigned char block_count; + unsigned char dma_channel : 4; + unsigned char dma_type : 4; + unsigned char pio_type : 4; + unsigned char pio_unused : 4; + unsigned short option_flags; + unsigned short reserved; + unsigned char revision; + unsigned char checksum; + } dpte __attribute__((packed)); +} __attribute__((packed)); +typedef struct boot_drive_info boot_drive_info_t; + struct driveInfo { boot_drive_info_t di; int uses_ebios; @@ -80,6 +126,7 @@ typedef long (*FSGetFileBlock)(CICell ih, char *filePath, unsigned long long *fi typedef long (*FSGetDirEntry)(CICell ih, char * dirPath, long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid); +typedef long (* FSGetUUID)(CICell ih, char *uuidStr); typedef void (*BVGetDescription)(CICell ih, char * str, long strMaxLen); struct iob { @@ -115,10 +162,12 @@ struct BootVolume { unsigned int part_boff; /* partition block offset */ unsigned int part_type; /* partition type */ unsigned int fs_boff; /* 1st block # of next read */ + unsigned int fs_byteoff; /* Byte offset for read within block */ FSLoadFile fs_loadfile; /* FSLoadFile function */ FSReadFile fs_readfile; /* FSReadFile function */ FSGetDirEntry fs_getdirentry; /* FSGetDirEntry function */ FSGetFileBlock fs_getfileblock; /* FSGetFileBlock function */ + FSGetUUID fs_getuuid; /* FSGetUUID function */ unsigned int bps; /* bytes per sector for this device */ char name[BVSTRLEN]; /* (name of partition) */ char type_name[BVSTRLEN]; /* (type of partition, eg. Apple_HFS) */ @@ -140,6 +189,7 @@ enum { kBIOSDevMask = 0xFF }; + //#define BIOS_DEV_TYPE(d) ((d) & kBIOSDevTypeMask) #define BIOS_DEV_UNIT(bvr) ((bvr)->biosdev - (bvr)->type) @@ -168,4 +218,9 @@ enum { kBlockDeviceType = kBIOSDevTypeHardDrive } gBootFileType_t; +enum { + kCursorTypeHidden = 0x0100, + kCursorTypeUnderline = 0x0607 +}; + #endif /* !__LIBSAIO_SAIO_TYPES_H */ diff --git a/i386/libsaio/stringTable.c b/i386/libsaio/stringTable.c index 65ef09e..b726688 100644 --- a/i386/libsaio/stringTable.c +++ b/i386/libsaio/stringTable.c @@ -404,11 +404,18 @@ BOOL getIntForKey( { const char *val; int size, sum; + BOOL negative = NO; if (getValueForKey(key, &val, &size)) { + if (*val == '-') { + negative = YES; + val++; + } for (sum = 0; size > 0; size--) { + if (*val < '0' || *val > '9') return NO; sum = (sum * 10) + (*val++ - '0'); } + if (negative) sum = -sum; *value = sum; return YES; } @@ -421,9 +428,9 @@ BOOL getValueForKey( int *size ) { - if (getValueForBootKey(bootArgs->bootString, key, val, size)) + if (getValueForBootKey(bootArgs->CommandLine, key, val, size)) return YES; - else if (getValueForConfigTableKey(bootArgs->config, key, val, size)) + else if (getValueForConfigTableKey(bootInfo->config, key, val, size)) return YES; return NO; @@ -443,13 +450,13 @@ int sysConfigValid; int loadConfigFile(const char *configFile) { - char *configPtr = bootArgs->config; + char *configPtr = bootInfo->config; int fd, count; /* Read config file into memory */ if ((fd = open(configFile, 0)) >= 0) { - if ((configPtr - bootArgs->config) > CONFIG_SIZE) { + if ((configPtr - bootInfo->config) > CONFIG_SIZE) { error("No room in memory for config files\n"); close(fd); return -1; @@ -463,7 +470,7 @@ loadConfigFile(const char *configFile) *configPtr++ = 0; *configPtr = 0; - bootArgs->configEnd = configPtr; + bootInfo->configEnd = configPtr; return 0; } else { @@ -484,7 +491,7 @@ loadConfigFile(const char *configFile) void printSystemConfig(void) { - char *p1 = bootArgs->config; + char *p1 = bootInfo->config; char *p2 = p1, tmp; while (*p1 != '\0') { @@ -602,7 +609,7 @@ loadSystemConfig( sysConfigValid = 1; // Check for XML file; // if not XML, gConfigDict will remain 0. - ParseXMLFile(bootArgs->config, &gConfigDict); + ParseXMLFile(bootInfo->config, &gConfigDict); } free(buf); return (ret < 0 ? ret : doDefault); diff --git a/i386/libsaio/sys.c b/i386/libsaio/sys.c index 01b6f15..1fa09cd 100644 --- a/i386/libsaio/sys.c +++ b/i386/libsaio/sys.c @@ -56,7 +56,9 @@ #include "libsaio.h" #include "bootstruct.h" - +#include <sys/md5.h> +#include <uuid/uuid.h> +#include <Kernel/uuid/namespace.h> struct devsw { const char * name; @@ -144,7 +146,7 @@ long LoadThinFatFile(const char *fileSpec, void **binary) const char *filePath; FSReadFile readFile; BVRef bvr; - long length, length2; + unsigned long length, length2; // Resolve the boot volume from the file spec. @@ -186,6 +188,73 @@ long LoadThinFatFile(const char *fileSpec, void **binary) return length; } +long GetFSUUID(char *spec, char *uuidStr) +{ + BVRef bvr; + long rval = -1; + const char *devSpec; + + if ((bvr = getBootVolumeRef(spec, &devSpec)) == NULL) + return -1; + + if(bvr->fs_getuuid) + rval = bvr->fs_getuuid(bvr, uuidStr); + + return rval; +} + + +// filesystem-specific getUUID functions call this shared string generator +long CreateUUIDString(uint8_t uubytes[], int nbytes, char *uuidStr) +{ + unsigned fmtbase, fmtidx, i; + uint8_t uuidfmt[] = { 4, 2, 2, 2, 6 }; + char *p = uuidStr; + MD5_CTX md5c; + uint8_t mdresult[16]; + + bzero(mdresult, sizeof(mdresult)); + + // just like AppleFileSystemDriver + MD5Init(&md5c); + MD5Update(&md5c, kFSUUIDNamespaceSHA1, sizeof(kFSUUIDNamespaceSHA1)); + MD5Update(&md5c, uubytes, nbytes); + MD5Final(mdresult, &md5c); + + // this UUID has been made version 3 style (i.e. via namespace) + // see "-uuid-urn-" IETF draft (which otherwise copies byte for byte) + mdresult[6] = 0x30 | ( mdresult[6] & 0x0F ); + mdresult[8] = 0x80 | ( mdresult[8] & 0x3F ); + + + // generate the text: e.g. 5EB1869F-C4FA-3502-BDEB-3B8ED5D87292 + i = 0; fmtbase = 0; + for(fmtidx = 0; fmtidx < sizeof(uuidfmt); fmtidx++) { + for(i=0; i < uuidfmt[fmtidx]; i++) { + uint8_t byte = mdresult[fmtbase+i]; + char nib; + + nib = byte >> 4; + *p = nib + '0'; // 0x4 -> '4' + if(*p > '9') *p = (nib - 9 + ('A'-1)); // 0xB -> 'B' + p++; + + nib = byte & 0xf; + *p = nib + '0'; // 0x4 -> '4' + if(*p > '9') *p = (nib - 9 + ('A'-1)); // 0xB -> 'B' + p++; + + } + fmtbase += i; + if(fmtidx < sizeof(uuidfmt)-1) + *(p++) = '-'; + else + *p = '\0'; + } + + return 0; +} + //========================================================================== // GetDirEntry - LOW-LEVEL FILESYSTEM FUNCTION. @@ -543,14 +612,15 @@ int readdir_ext(struct dirstuff * dirp, const char ** name, long * flags, int currentdev() { - return bootArgs->kernDev; + printf("currentdev = %d\n", bootInfo->kernDev); + return bootInfo->kernDev; } //========================================================================== int switchdev(int dev) { - bootArgs->kernDev = dev; + bootInfo->kernDev = dev; return dev; } @@ -620,9 +690,9 @@ BVRef getBootVolumeRef( const char * path, const char ** outPath ) { const char * cp; BVRef bvr; - int type = B_TYPE( bootArgs->kernDev ); - int unit = B_UNIT( bootArgs->kernDev ); - int part = B_PARTITION( bootArgs->kernDev ); + int type = B_TYPE( bootInfo->kernDev ); + int unit = B_UNIT( bootInfo->kernDev ); + int part = B_PARTITION( bootInfo->kernDev ); int biosdev = gBIOSDev; static BVRef lastBVR = 0; static int lastKernDev; @@ -636,7 +706,7 @@ BVRef getBootVolumeRef( const char * path, const char ** outPath ) if (*cp != LP) // no left paren found { cp = path; - if ( lastBVR && lastKernDev == bootArgs->kernDev ) + if ( lastBVR && lastKernDev == bootInfo->kernDev ) { bvr = lastBVR; goto quick_exit; @@ -703,10 +773,10 @@ BVRef getBootVolumeRef( const char * path, const char ** outPath ) // Record the most recent device parameters in the // KernBootStruct. - bootArgs->kernDev = biosdev; + bootInfo->kernDev = biosdev; lastBVR = bvr; - lastKernDev = bootArgs->kernDev; + lastKernDev = bootInfo->kernDev; quick_exit: // Returns the file path following the device spec. diff --git a/i386/libsaio/ufs.c b/i386/libsaio/ufs.c index 797eb4c..ec8c060 100644 --- a/i386/libsaio/ufs.c +++ b/i386/libsaio/ufs.c @@ -32,6 +32,10 @@ #include "ufs.h" #include "ufs_byteorder.h" +#if !defined(MAXNAMLEN) && defined(UFSMAXNAMLEN) +#define MAXNAMLEN UFSMAXNAMLEN +#endif + typedef struct dinode Inode, *InodePtr; // Private function prototypes @@ -47,7 +51,7 @@ static long FindFileInDir(char *fileName, long *flags, InodePtr fileInode, InodePtr dirInode); static char *ReadFileBlock(InodePtr fileInode, long fragNum, long blockOffset, long length, char *buffer, long cache); -static long ReadFile(InodePtr fileInode, long *length, void *base, long offset); +static long ReadFile(InodePtr fileInode, unsigned long *length, void *base, long offset); #define kDevBlockSize (0x200) // Size of each disk block. #define kDiskLabelBlock (15) // Block the DL is in. @@ -59,6 +63,9 @@ static long long gPartitionBase; static char *gULBuf; static char *gFSBuf; static struct fs *gFS; +#if !BOOT1 +static struct ufslabel gUFSLabel; // for UUID +#endif static long gBlockSize; static long gFragSize; static long gFragsPerBlock; @@ -75,6 +82,9 @@ static long long gPartitionBase; static char gDLBuf[8192]; static char gFSBuf[SBSIZE]; static struct fs *gFS; +#if !BOOT1 +static struct ufslabel gUFSLabel; // for UUID +#endif static long gBlockSize; static long gFragSize; static long gFragsPerBlock; @@ -92,6 +102,10 @@ static InodePtr gFileInodePtr = &_gFileInode; long UFSInitPartition( CICell ih ) { +#if !BOOT1 + long ret; +#endif + if (ih == gCurrentIH) { #ifdef __i386__ CacheInit(ih, gBlockSize); @@ -119,6 +133,16 @@ long UFSInitPartition( CICell ih ) // Assume there is no Disk Label gPartitionBase = 0; +#if !BOOT1 + // read the disk label to get the UUID + // (rumor has it that UFS headers can be either-endian on disk; hopefully + // that isn't true for this UUID field). + Seek(ih, gPartitionBase + UFS_LABEL_OFFSET); + ret = Read(ih, (long)&gUFSLabel, UFS_LABEL_SIZE); + if(ret != 0) + bzero(&gUFSLabel, UFS_LABEL_SIZE); +#endif /* !BOOT1 */ + // Look for the Super Block Seek(ih, gPartitionBase + SBOFF); Read(ih, (long)gFSBuf, SBSIZE); @@ -146,6 +170,20 @@ long UFSInitPartition( CICell ih ) return 0; } +#if !BOOT1 + +long UFSGetUUID(CICell ih, char *uuidStr) +{ + long long uuid = gUFSLabel.ul_uuid; + + if (UFSInitPartition(ih) == -1) return -1; + if (uuid == 0LL) return -1; + + return CreateUUIDString((uint8_t*)(&uuid), sizeof(uuid), uuidStr); +} + +#endif /* !BOOT1 */ + long UFSLoadFile( CICell ih, char * filePath ) { return UFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0); @@ -224,7 +262,7 @@ UFSGetDescription(CICell ih, char *str, long strMaxLen) if (*p != magic_bytes[i]) return; } - strncpy(str, ul->ul_name, strMaxLen); + strncpy(str, (const char *)ul->ul_name, strMaxLen); } long @@ -443,7 +481,7 @@ static char * ReadFileBlock( InodePtr fileInode, long fragNum, long blockOffset, return buffer; } -static long ReadFile( InodePtr fileInode, long * length, void * base, long offset ) +static long ReadFile( InodePtr fileInode, unsigned long * length, void * base, long offset ) { long bytesLeft, curSize, curFrag; char *buffer, *curAddr = (char *)base; @@ -471,7 +509,7 @@ static long ReadFile( InodePtr fileInode, long * length, void * base, long offse while (bytesLeft) { curSize = gBlockSize; if (curSize > bytesLeft) curSize = bytesLeft; - if (offset != 0) curSize -= offset; + if ((offset + curSize) > gBlockSize) curSize = (gBlockSize - offset); buffer = ReadFileBlock(fileInode, curFrag, offset, curSize, curAddr, 0); if (buffer == 0) break; diff --git a/i386/libsaio/ufs.h b/i386/libsaio/ufs.h index 9d7743d..5de2365 100644 --- a/i386/libsaio/ufs.h +++ b/i386/libsaio/ufs.h @@ -28,4 +28,5 @@ extern long UFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex, FinderInfo * finderInfo, long * infoValid); extern void UFSGetDescription(CICell ih, char *str, long strMaxLen); extern long UFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock); +extern long UFSGetUUID(CICell ih, char *uuidStr); diff --git a/i386/libsaio/ufs_byteorder.c b/i386/libsaio/ufs_byteorder.c index 838f107..a1c3f71 100644 --- a/i386/libsaio/ufs_byteorder.c +++ b/i386/libsaio/ufs_byteorder.c @@ -52,7 +52,7 @@ byte_swap_longlongs(unsigned long long *array, int count) #endif void -byte_swap_ints(int *array, int count) +byte_swap_ints(unsigned int *array, int count) { register int i; @@ -61,7 +61,7 @@ byte_swap_ints(int *array, int count) } void -byte_swap_shorts(short *array, int count) +byte_swap_shorts(unsigned short *array, int count) { register int i; @@ -71,7 +71,7 @@ byte_swap_shorts(short *array, int count) #if UNUSED static void -swapBigIntsToHost(int *array, int count) +swapBigIntsToHost(unsigned int *array, int count) { register int i; @@ -80,7 +80,7 @@ swapBigIntsToHost(int *array, int count) } static void -swapBigShortToHosts(short *array, int count) +swapBigShortToHosts(unsigned short *array, int count) { register int i; @@ -95,16 +95,16 @@ byte_swap_superblock(struct fs *sb) u_int16_t * usptr; unsigned long size; - byte_swap_ints(((int32_t *)&sb->fs_firstfield), 52); + byte_swap_ints(((u_int32_t *)&sb->fs_firstfield), 52); byte_swap_int(sb->fs_cgrotor); byte_swap_int(sb->fs_cpc); - byte_swap_shorts((int16_t *)sb->fs_opostbl, 16 * 8); - byte_swap_ints((int32_t *)sb->fs_sparecon, 50); - byte_swap_ints((int32_t *)&sb->fs_contigsumsize, 3); + byte_swap_shorts((u_int16_t *)sb->fs_opostbl, 16 * 8); + byte_swap_ints((u_int32_t *)sb->fs_sparecon, 50); + byte_swap_ints((u_int32_t *)&sb->fs_contigsumsize, 3); #if UNUSED byte_swap_longlongs((u_int64_t *)&sb->fs_maxfilesize,3); #endif - byte_swap_ints((int32_t *)&sb->fs_state, 6); + byte_swap_ints((u_int32_t *)&sb->fs_state, 6); /* Got these magic numbers from mkfs.c in newfs */ if (sb->fs_nrpos != 8 || sb->fs_cpc > 16) { diff --git a/i386/libsaio/ufs_byteorder.h b/i386/libsaio/ufs_byteorder.h index dde46e4..f4861a2 100644 --- a/i386/libsaio/ufs_byteorder.h +++ b/i386/libsaio/ufs_byteorder.h @@ -44,12 +44,11 @@ #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> -void byte_swap_ints(int *array, int count); -void byte_swap_shorts(short *array, int count); +void byte_swap_ints(unsigned int *array, int count); +void byte_swap_shorts(unsigned short *array, int count); void byte_swap_longlongs(unsigned long long *array, int count); void byte_swap_superblock(struct fs *sb); -void byte_swap_partition(struct partition *part); void byte_swap_dinode_in(struct dinode *di); void byte_swap_dir_block_in(char *addr, int count); void byte_swap_inode_in(struct dinode *dc, struct dinode *ic); diff --git a/i386/libsaio/vbe.h b/i386/libsaio/vbe.h index 295b889..1c59af5 100644 --- a/i386/libsaio/vbe.h +++ b/i386/libsaio/vbe.h @@ -242,7 +242,7 @@ typedef struct { unsigned char Reserved[40]; } VBECRTCInfoBlock; -#pragma options align=reset +#pragma pack() /* * Defined flags for 'Flags' field in VBECRTCInfoBlock. diff --git a/i386/nasm/Makefile b/i386/nasm/Makefile index 570169f..5dc06e4 100644 --- a/i386/nasm/Makefile +++ b/i386/nasm/Makefile @@ -10,7 +10,7 @@ MANINSTALLDIR = $(SYMROOT) INSTALLDIR = $(SYMROOT) OPTIM = -O2 -CFLAGS = $(OPTIM) -g -Wmost -Werror +CFLAGS = $(OPTIM) -g -Wmost -Werror -fno-builtin DEFINES= INC = -I. ifneq "" "$(wildcard /bin/mkdirs)" diff --git a/i386/rcz/Makefile b/i386/rcz/Makefile index 58b517b..5fdf893 100644 --- a/i386/rcz/Makefile +++ b/i386/rcz/Makefile @@ -6,7 +6,7 @@ UTILDIR = ../util LIBSADIR = ../libsa INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone -OPTIM = -Os +OPTIM = -Os -Oz CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \ -fno-builtin -static DEFINES= diff --git a/i386/strings/BootHelp.txt b/i386/strings/BootHelp.txt index e76bfda..9db0982 100644 --- a/i386/strings/BootHelp.txt +++ b/i386/strings/BootHelp.txt @@ -7,8 +7,8 @@ Example arguments include device: rd=<BSD device name> (e.g. rd=disk0s2) rd=*<IODeviceTree path> (e.g. rd=*/PCI0@0/CHN0@0/@0:1) kernel: kernel name (e.g. "mach_kernel" - must be in "/" ) - flags: -v (verbose) -s (single user), - -f (safe) -F (ignore boot file) + flags: -v (verbose) -s (single user mode), + -x (safe mode) -F (ignore boot configuration file) "Graphics Mode"="WIDTHxHEIGHTxDEPTH" (e.g. "1024x768x32") For VESA 3.0 graphics, you may append a refresh rate after an "@" character (e.g. "1280x1024x32@75") @@ -18,7 +18,7 @@ Example arguments include Example: mach_kernel rd=disk0s1 -v "Graphics Mode"="4096x4096x32@85" If the computer won't start up properly, you may be able to start it up using -safe mode. Type -f to start up in safe mode, which ignores all cached +safe mode. Type -x to start up in safe mode, which ignores all cached driver files. Special booter commands: diff --git a/i386/strings/Makefile b/i386/strings/Makefile index cb04324..42c01fe 100644 --- a/i386/strings/Makefile +++ b/i386/strings/Makefile @@ -13,7 +13,7 @@ all: install_i386:: $(INSTALLDIR) cp $(FILES) $(INSTALLDIR) - chown -fR root.wheel $(INSTALLDIR) + chown -fR root:wheel $(INSTALLDIR) chmod -R ugo-w $(INSTALLDIR) include ../MakeInc.dir diff --git a/i386/testmodule/Makefile b/i386/testmodule/Makefile index 3baf106..fce5e07 100644 --- a/i386/testmodule/Makefile +++ b/i386/testmodule/Makefile @@ -6,7 +6,7 @@ DIR = testmodule include ../MakePaths.dir DEBUG = -g -OPTIM = -Os +OPTIM = -Os -Oz CFLAGS = $(DEBUG) $(OPTIM) $(MORECPP) -arch i386 -Wmost -DTEST_INTERNAL_USER DEFINES= CONFIG = hd diff --git a/i386/util/Makefile b/i386/util/Makefile index 1fd68e5..2dfda04 100644 --- a/i386/util/Makefile +++ b/i386/util/Makefile @@ -12,7 +12,7 @@ VPATH = $(OBJROOT):$(SYMROOT) INSTALLDIR = $(DSTROOT)/usr/standalone/i386 LOCALBIN = $(DSTROOT)/usr/local/bin -OPTIM = -Os +OPTIM = -Os -Oz CFLAGS = $(RC_CFLAGS) $(OPTIM) -Wmost -Werror -g LDFLAGS = CFILES = machOconv.c -- 2.45.2