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)
MKDIRS = /bin/mkdir -p
endif
AS = as
-LD = ld
+LD = gcc
LIBS= -L$(SYMDIR) -lsa
#LIBS= -L$(SYMDIR)
$(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
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" );
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" );
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)
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
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
--- /dev/null
+/* 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
--- /dev/null
+#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
+ }
+}
static char gBootKernelCacheFile[512];
static char gCacheNameAdler[64 + 256];
char *gPlatformName = gCacheNameAdler;
+char gRootDevice[512];
char gMKextName[512];
BVRef gBootVolume;
{
printf("\nMemory allocation error (0x%x, 0x%x)\n",
(unsigned)addr, (unsigned)size);
- asm("hlt");
+ asm volatile ("hlt");
}
//==========================================================================
{
entry_t kernelEntry;
int ret;
-#ifdef APM_SUPPORT
- BOOL apm;
-#endif /* APM_SUPPORT */
BOOL bootGraphics;
bootArgs->kaddr = bootArgs->ksize = 0;
ret = DecodeKernel(binary,
&kernelEntry,
(char **) &bootArgs->kaddr,
- &bootArgs->ksize );
+ (int *)&bootArgs->ksize );
if ( ret != 0 )
return ret;
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 ) {
}
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 );
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 );
}
//==========================================================================
zeroBSS();
// Initialize malloc
-
malloc_init(0, 0, 0, malloc_error);
// Enable A20 gate before accessing memory above 1Mb.
// 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.
// Record default boot device.
gBootVolume = selectBootVolume(bvChain);
- bootArgs->kernDev = MAKEKERNDEV(gBIOSDev,
+ bootInfo->kernDev = MAKEKERNDEV(gBIOSDev,
BIOS_DEV_UNIT(gBootVolume),
gBootVolume->part_no );
int trycache;
long flags, cachetime, kerneltime, exttime;
int ret = -1;
+ void *binary = (void *)kLoadAddr;
// Initialize globals.
// 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);
// Check for cache file.
-
trycache = (((gBootMode & kBootModeSafe) == 0) &&
(gOverrideKernel == NO) &&
(gBootFileType == kBlockDeviceType) &&
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;
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();
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;
}
} else {
/* Won't return if successful. */
- ret = ExecKernel((void *)kLoadAddr);
+ ret = ExecKernel(binary);
}
} /* while(1) */
return OSSwapHostToBigInt32(result);
}
+
#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"
/*
*
*/
#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
extern BOOL gOverrideKernel;
extern char *gPlatformName;
extern char gMKextName[];
+extern char gRootDevice[];
extern BVRef gBootVolume;
// Boot Modes
unsigned char **newImageData );
extern char * decodeRLE( const void * rleData, int rleBlocks, int outBytes );
extern void drawBootGraphics(void);
+extern int getVideoMode(void);
/*
* drivers.c
if ( gBootFileType == kNetworkDeviceType )
{
- NetLoadDrivers(dirSpec);
+ if (NetLoadDrivers(dirSpec) != 0) {
+ error("Could not load drivers from the network\n");
+ return -1;
+ }
}
else if ( gBootFileType == kBlockDeviceType )
{
#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);
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;
}
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
char *fileName, segName[32];
DriverInfoPtr driver;
long length, driverAddr, driverLength;
+ void *driverModuleAddr = 0;
+
module = gModuleHead;
{
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;
unsigned short height,
unsigned char * data );
+static void setBorderColor( unsigned char colorIndex );
int
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))
// Check presence of VESA signature.
- if ( strncmp( vbeInfo.VESASignature, "VESA", 4 ) )
+ if ( strncmp( (char *)vbeInfo.VESASignature, "VESA", 4 ) )
return;
// Announce controller properties.
// 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 );
drawColorRectangle( 0, 0, VIDEO(width), VIDEO(height),
0x01 /* color index */ );
+ setBorderColor( 0x01 /* color index */ );
+
appleBootPict = decodeRLE( gAppleBootPictRLE, kAppleBootRLEBlocks,
kAppleBootWidth * kAppleBootHeight );
if ( appleBootPict )
{
convertImage(kAppleBootWidth, kAppleBootHeight,
- appleBootPict, &imageData);
+ (unsigned char *)appleBootPict, &imageData);
x = ( VIDEO(width) - kAppleBootWidth ) / 2;
y = ( VIDEO(height) - kAppleBootHeight ) / 2 + kAppleBootOffset;
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" );
}
}
+
+//==========================================================================
+// 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
// 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
}
//==========================================================================
// 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 )
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 )
}
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;
}
//==========================================================================
else
lastTickTime = currentTickTime;
- if ( getVideoMode() == TEXT_MODE )
+ if ( getVideoMode() == VGA_TEXT_MODE )
{
if (currentIndicator >= kNumIndicators) currentIndicator = 0;
string[0] = indicator[currentIndicator++];
void
clearActivityIndicator( void )
{
- if ( getVideoMode() == TEXT_MODE )
+ if ( getVideoMode() == VGA_TEXT_MODE )
{
printf(" \b");
}
//==========================================================================
-enum {
- kCursorTypeHidden = 0x0100,
- kCursorTypeUnderline = 0x0607
-};
-
typedef struct {
int x;
int y;
moveCursor( 0, row );
printf(msg);
- for ( time = time18(), timeout++; timeout; )
+ for ( time = time18(), timeout++; timeout > 0; )
{
if (ch = readKeyboardStatus())
break;
{
int line;
int i;
- MemoryRange *mp = bootArgs->memoryMap;
+ MemoryRange *mp = bootInfo->memoryMap;
// Activate and clear page 1
setActiveDisplayPage(1);
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));
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,
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();
}
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 )
{
( 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;
}
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;
int userCnt;
int cntRemaining;
char * argP;
+ char uuidStr[64];
+ BOOL uuidSet = NO;
+ char * configKernelFlags;
+ char * valueBuffer;
+
+ valueBuffer = (char *)malloc(VALUE_SIZE);
skipblanks( &cp );
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 );
}
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);
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.
%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
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)"
#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
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" );
#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" );
#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"
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"
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"
static void malloc_error(char *addr, size_t size)
{
#ifdef i386
- asm("hlt");
+ asm volatile ("hlt");
#endif
}
#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
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)
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
/*
* 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)
// halt()
//
LABEL(_halt)
- hlt
+ call _bgetc
jmp _halt
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#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 */
#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.
// 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 )
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.
// 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
#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
#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;
}
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;
+}
* @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 */
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)) {
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);
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();
}
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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 */
* 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"
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
}
}
//==========================================================================
static int readBytes( int biosdev, unsigned int blkno,
+ unsigned int byteoff,
unsigned int byteCount, void * buffer )
{
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 )
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"));
FSReadFile readFunc,
FSGetDirEntry getdirFunc,
FSGetFileBlock getBlockFunc,
+ FSGetUUID getUUIDFunc,
BVGetDescription getDescriptionFunc,
int probe, int type )
{
bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
bvr->fs_getfileblock= getBlockFunc;
+ bvr->fs_getuuid = getUUIDFunc;
bvr->description = getDescriptionFunc ?
getDescriptionFunc : getVolumeDescription;
bvr->type = type;
FSReadFile readFunc,
FSGetDirEntry getdirFunc,
FSGetFileBlock getBlockFunc,
+ FSGetUUID getUUIDFunc,
BVGetDescription getDescriptionFunc,
int probe, int type )
{
bvr->fs_readfile = readFunc;
bvr->fs_getdirentry = getdirFunc;
bvr->fs_getfileblock= getBlockFunc;
+ bvr->fs_getuuid = getUUIDFunc;
bvr->description = getDescriptionFunc ?
getDescriptionFunc : getVolumeDescription;
bvr->type = type;
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;
switch ( part->systid )
{
+#if UFS_SUPPORT
case FDISK_UFS:
bvr = newFDiskBVRef(
biosdev, partno,
UFSReadFile,
UFSGetDirEntry,
UFSGetFileBlock,
+ UFSGetUUID,
UFSGetDescription,
0,
kBIOSDevTypeHardDrive);
break;
+#endif
case FDISK_HFS:
bvr = newFDiskBVRef(
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
+ HFSGetUUID,
HFSGetDescription,
0,
kBIOSDevTypeHardDrive);
break;
+#if UFS_SUPPORT
case FDISK_BOOTER:
booterUFS = newFDiskBVRef(
biosdev, partno,
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);
biosdev, partno,
part->relsect,
part,
- 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
kBIOSDevTypeHardDrive);
break;
}
}
}
+#if UFS_SUPPORT
// Booting from a CD with an UFS filesystem embedded
// in a booter partition.
}
else free( booterUFS );
}
+#endif
}
} while (0);
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
+ HFSGetUUID,
0,
kBIOSDevTypeHardDrive);
bvr->next = map->bvr;
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;
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;
HFSReadFile,
HFSGetDirEntry,
HFSGetFileBlock,
+ HFSGetUUID,
HFSGetDescription,
0,
kBIOSDevTypeHardDrive);
bootSector = gBootSector;
}
- error = readBytes( biosdev, secno, BPS, bootSector );
+ error = readBytes( biosdev, secno, 0, BPS, bootSector );
if ( error || bootSector->signature != DISK_SIGNATURE )
return -1;
void diskSeek( BVRef bvr, long long position )
{
bvr->fs_boff = position / BPS;
+ bvr->fs_byteoff = position % BPS;
}
//==========================================================================
{
return readBytes( bvr->biosdev,
bvr->fs_boff + bvr->part_boff,
+ bvr->fs_byteoff,
length,
(void *) addr );
}
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;
}
static char *gHFSPlusHeader;
static HFSPlusVolumeHeader *gHFSPlus;
static char *gLinkTemp;
+static long long gVolID;
static char *gTempStr;
#else /* !__i386__ */
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,
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,
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);
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);
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;
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);
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);
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
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;
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;
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);
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);
//
//_______________________________________________________________________
-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;
unsigned int vmend = 0;
unsigned long cnt;
long ret = -1;
- unsigned int entry;
+ unsigned int entry = 0;
gBinaryAddress = (unsigned long)binary;
--- /dev/null
+/*
+ * 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));
+}
#include "sl.h"
#include "saio_internal.h"
#include "bootstruct.h"
+#include "device_tree.h"
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)
{
}
return 0;
}
+#endif
long
AllocateKernelMemory( long inSize )
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
+
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);
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) +
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;
}
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;
}
/* 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);
}
}
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;
return (ERROR);
}
*cfxp = *fxp;
- ((caddr_t) cfxp) += bytesPerSector;
+ cfxp = (u_int16_t *)(((caddr_t)cfxp) + bytesPerSector);
}
return (0);
}
}
static int
-memcmp(char *p1, char *p2, int len)
+memcmp(const char *p1, const char *p2, int len)
{
while (len--) {
if (*p1++ != *p2++)
/*
* Check the "NTFS " signature.
*/
- if (memcmp(boot->bf_sysid, "NTFS ", 8) != 0)
+ if (memcmp((const char *)boot->bf_sysid, "NTFS ", 8) != 0)
{
goto error;
}
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;
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);
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);
/* misc.c */
extern void enableA20(void);
+extern int checkForSupportedHardware();
+extern void getPlatformName(char *nameBuf);
/* nbp.c */
extern UInt32 nbpUnloadBaseCode();
/* 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);
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);
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;
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 {
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) */
kBIOSDevMask = 0xFF
};
+
//#define BIOS_DEV_TYPE(d) ((d) & kBIOSDevTypeMask)
#define BIOS_DEV_UNIT(bvr) ((bvr)->biosdev - (bvr)->type)
kBlockDeviceType = kBIOSDevTypeHardDrive
} gBootFileType_t;
+enum {
+ kCursorTypeHidden = 0x0100,
+ kCursorTypeUnderline = 0x0607
+};
+
#endif /* !__LIBSAIO_SAIO_TYPES_H */
{
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;
}
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;
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;
*configPtr++ = 0;
*configPtr = 0;
- bootArgs->configEnd = configPtr;
+ bootInfo->configEnd = configPtr;
return 0;
} else {
void
printSystemConfig(void)
{
- char *p1 = bootArgs->config;
+ char *p1 = bootInfo->config;
char *p2 = p1, tmp;
while (*p1 != '\0') {
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);
#include "libsaio.h"
#include "bootstruct.h"
-
+#include <sys/md5.h>
+#include <uuid/uuid.h>
+#include <Kernel/uuid/namespace.h>
struct devsw {
const char * name;
const char *filePath;
FSReadFile readFile;
BVRef bvr;
- long length, length2;
+ unsigned long length, length2;
// Resolve the boot volume from the file spec.
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.
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;
}
{
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;
if (*cp != LP) // no left paren found
{
cp = path;
- if ( lastBVR && lastKernDev == bootArgs->kernDev )
+ if ( lastBVR && lastKernDev == bootInfo->kernDev )
{
bvr = lastBVR;
goto quick_exit;
// 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.
#include "ufs.h"
#include "ufs_byteorder.h"
+#if !defined(MAXNAMLEN) && defined(UFSMAXNAMLEN)
+#define MAXNAMLEN UFSMAXNAMLEN
+#endif
+
typedef struct dinode Inode, *InodePtr;
// Private function prototypes
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.
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;
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;
long UFSInitPartition( CICell ih )
{
+#if !BOOT1
+ long ret;
+#endif
+
if (ih == gCurrentIH) {
#ifdef __i386__
CacheInit(ih, gBlockSize);
// 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);
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);
if (*p != magic_bytes[i])
return;
}
- strncpy(str, ul->ul_name, strMaxLen);
+ strncpy(str, (const char *)ul->ul_name, strMaxLen);
}
long
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;
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;
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);
#endif
void
-byte_swap_ints(int *array, int count)
+byte_swap_ints(unsigned int *array, int count)
{
register int i;
}
void
-byte_swap_shorts(short *array, int count)
+byte_swap_shorts(unsigned short *array, int count)
{
register int i;
#if UNUSED
static void
-swapBigIntsToHost(int *array, int count)
+swapBigIntsToHost(unsigned int *array, int count)
{
register int i;
}
static void
-swapBigShortToHosts(short *array, int count)
+swapBigShortToHosts(unsigned short *array, int count)
{
register int i;
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) {
#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);
unsigned char Reserved[40];
} VBECRTCInfoBlock;
-#pragma options align=reset
+#pragma pack()
/*
* Defined flags for 'Flags' field in VBECRTCInfoBlock.
INSTALLDIR = $(SYMROOT)
OPTIM = -O2
-CFLAGS = $(OPTIM) -g -Wmost -Werror
+CFLAGS = $(OPTIM) -g -Wmost -Werror -fno-builtin
DEFINES=
INC = -I.
ifneq "" "$(wildcard /bin/mkdirs)"
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=
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")
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:
install_i386:: $(INSTALLDIR)
cp $(FILES) $(INSTALLDIR)
- chown -fR root.wheel $(INSTALLDIR)
+ chown -fR root:wheel $(INSTALLDIR)
chmod -R ugo-w $(INSTALLDIR)
include ../MakeInc.dir
include ../MakePaths.dir
DEBUG = -g
-OPTIM = -Os
+OPTIM = -Os -Oz
CFLAGS = $(DEBUG) $(OPTIM) $(MORECPP) -arch i386 -Wmost -DTEST_INTERNAL_USER
DEFINES=
CONFIG = hd
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