2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright 1993 NeXT Computer, Inc.
26 * All rights reserved.
31 #include "kernBootStruct.h"
32 #include "rcz_common.h"
33 #include <ufs/ufs/dir.h>
34 #include <mach-o/fat.h>
36 static int devMajor
[3] = { 6, 3, 1 }; // sd, hd, fd major dev #'s
38 //==========================================================================
39 // Open a file for reading. If the file doesn't exist,
40 // try opening the compressed version.
42 #ifdef RCZ_COMPRESSED_FILE_SUPPORT
44 openfile(char *filename
, int ignored
)
50 if ((fd
= open(filename
, 0)) < 0) {
52 sprintf(buf
, "%s%s", filename
, RCZ_EXTENSION
);
53 if ((fd
= open(buf
, 0)) >= 0) {
54 size
= rcz_file_size(fd
);
55 addr
= (unsigned char *)((KERNEL_ADDR
+ KERNEL_LEN
) - size
);
56 ret
= rcz_decompress_file(fd
, addr
);
61 fd
= openmem(addr
, size
);
69 openfile(char *filename
, int ignored
)
71 return open(filename
, 0);
75 //==========================================================================
81 struct mach_header
* headOut
,
82 entry_t
* entry
, /* entry point */
83 char ** addr
, /* load address */
84 int * size
) /* size of loaded program */
86 struct mach_header head
;
92 read(fd
, (char *) &head
, sizeof(head
));
95 bcopy((char *) &head
, (char *) headOut
, sizeof(head
));
97 if ( head
.magic
== MH_MAGIC
)
100 printf("oneway fat binary found\n"); sleep(1);
102 return loadmacho(&head
, dev
, fd
, entry
, addr
, size
, file_offset
);
104 else if ( file_offset
== 0 &&
105 ((head
.magic
== FAT_CIGAM
) || (head
.magic
== FAT_MAGIC
)) )
107 int swap
= (head
.magic
== FAT_CIGAM
) ? 1 : 0;
108 struct fat_header
* fhp
= (struct fat_header
*) &head
;
109 struct fat_arch
* fap
;
110 int i
, narch
= swap
? NXSwapLong(fhp
->nfat_arch
) : fhp
->nfat_arch
;
114 size
= sizeof(struct fat_arch
) * narch
;
119 for ( i
= 0, fap
= (struct fat_arch
*)(buf
+sizeof(struct fat_header
));
123 cpu
= swap
? NXSwapLong(fap
->cputype
) : fap
->cputype
;
124 if (cpu
== CPU_TYPE_I386
)
126 /* that's specific enough */
128 file_offset
= swap
? NXSwapLong(fap
->offset
) : fap
->offset
;
129 b_lseek(fd
, file_offset
, 0);
134 error("Fat binary file doesn't contain i386 code\n");
137 error("Unrecognized binary format: %08x\n", head
.magic
);
141 //==========================================================================
144 // Read from file descriptor. addr is a physical address.
150 char * orgaddr
= addr
;
156 int bufsize
= BUFSIZ
;
159 printf("xread: addr=%x, size=%x\n", addr
, size
);
163 buf
= malloc(BUFSIZ
);
165 // align your read to increase speed
166 offset
= tell(fd
) & 4095;
174 if ( size
> max
) count
= max
;
177 printf("xread: loop size=%x, count=%x\n", size
, count
);
181 if ( read(fd
, buf
, count
) != count
) break;
183 bcopy(buf
, ptov(addr
), count
);
191 if ( tick
> (50*1024) )
203 //==========================================================================
208 struct mach_header
* head
,
219 struct xxx_thread_command
{
221 unsigned long cmdsize
;
222 unsigned long flavor
;
224 i386_thread_state_t state
;
226 unsigned int entry
= 0;
228 unsigned int vmaddr
= ~0;
230 // XXX should check cputype
231 cmds
= (unsigned int) malloc(head
->sizeofcmds
);
232 b_lseek(io
, sizeof (struct mach_header
) + file_offset
, 0);
234 if ( read(io
, (char *) cmds
, head
->sizeofcmds
) != head
->sizeofcmds
)
236 error("loadmacho: error reading commands\n");
240 for ( ncmds
= head
->ncmds
, cp
= cmds
; ncmds
> 0; ncmds
-- )
244 #define lcp ((struct load_command *) cp)
245 #define scp ((struct segment_command *) cp)
250 addr
= (scp
->vmaddr
& 0x3fffffff) + (int)*raddr
;
253 // Is this an OK assumption?
254 // if the filesize is zero, it doesn't
255 // take up any virtual space...
256 // (Hopefully this only excludes PAGEZERO.)
257 // Also, ignore linkedit segment when
258 // computing size, because we will erase
259 // the linkedit segment later.
261 if ( strncmp(scp
->segname
, SEG_LINKEDIT
,
262 sizeof(scp
->segname
)) != 0)
263 vmsize
+= scp
->vmsize
;
265 vmaddr
= min(vmaddr
, addr
);
267 // Zero any space at the end of the segment.
268 bzero((char *)(addr
+ scp
->filesize
),
269 scp
->vmsize
- scp
->filesize
);
271 // FIXME: check to see if we overflow
272 // the available space (should be passed in
273 // as the size argument).
276 printf("LC_SEGMENT\n");
277 printf("LS;file_off %x; fos %x; fsize %x ; addr %x \n",
278 scp
->fileoff
, file_offset
,scp
->filesize
, addr
);
282 b_lseek(io
, scp
->fileoff
+ file_offset
, 0);
283 if ( xread(io
, (char *)addr
, scp
->filesize
)
286 error("loadmacho: error loading section\n");
294 th
= (struct xxx_thread_command
*) cp
;
295 entry
= th
->state
.eip
;
301 kernBootStruct
->rootdev
= (dev
& 0xffffff00) | devMajor
[Dev(dev
)];
304 *rentry
= (entry_t
)( (int) entry
& 0x3fffffff );
306 *raddr
= (char *)vmaddr
;
309 printf("suceesful load;vmaddr=%x; vmsize=%x;entry=%x\n", vmaddr
, vmsize
,entry
);
317 error("loadmacho: read error\n");