[comp.os.minix] New Bootstrapper Part 1 of 3

ncoverby@ndsuvax.UUCP (Glen Overby) (05/11/89)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	MANIFEST
#	b1/bootblok.asm3
#	b1/bootblok.uu
#	b2b/Makefile
#	b2b/bsu.s
#	b2b/hdparam.h
#	b2b/main.c
#	b2b/partition.h
#	b2b/stack.c
#	b2b/standalone.c
#	b2b/type.h
#	kernel/main.c.diff
#	fs/cache.c.diff
# This archive created: Tue May  9 12:01:09 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(10220 characters)'
if test -f 'README'
then
    echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
X                  A New Bootstrapper for Minix
X
X                           Glen Overby
X                  North Dakota State University
X                       Fargo, North Dakota
X
X
X
X                         April 30, 1989
X
X
X
XThe objective of this project is to improve the verasility of the
XMinix  boot-up  process by reading the major pieces of the system
Xfrom files on a filesystem, rather than from an image diskette.
X
XTo achieve this, I have developed a two-stage process to load the
Xsystem.   The  first  stage  resides in the boot block of a Minix
Xfilesystem and is loaded by the PC's ROM.   When  stage  1  takes
Xover,  it  reads  the  root  directory  of /dev/fd0 looking for a
Xstripped file (no "a.out" header) named "boot"  to  load.   After
Xcontrol  is  passed  to stage 2, it loads four "a.out" files con-
Xtaining the Kernel, Memory Manager, File System and Init,  build-
Xing a normal process stacks with process arguments for each.
X
XThe first stage is written entirely in assembler by an  associate
Xof  mine,  Dan  Thureen.   Dan used the MicroSoft Macro Assembler
X(version 4.0 works OK; I've  had  trouble  with  5.0  complaining
Xabout  not  having a stack segment and such).  Microsoft's assem-
Xbler was used because we did  not  know  all  of  the  syntax  of
XMinix's  asld,  and  there  were  a few required addressing modes
X(such as jump indirect) that we did not know how to code.
X
XStage 2 is written primarily in C, with  some  assembler  support
Xroutines.   It  loads  "a.out"  format  files  from  Minix format
Xfilesystems on any disk or partition; it knows about  partitioned
Xhard  disks as well as floppy diskettes.  After all processes are
Xloaded, stacks are built for each of the processes.  The kernel's
Xstack  contains  "struct  proc" entries for kernel memory, MM, FS
Xand Init.  These are used by the proc table  initialization  rou-
Xtines as a replacement for the sizes[] array.
X
XFile loader.c contains the code that does all of  the  filesystem
Xreading.   Routines  with double sides are the only ones intended
Xfor use outside this module.
X
X
X                                =================
X                                ||  Open_File  ||
X                                =================
X                         _______/       |       \_______
X                        /               |               \
X                ---------------         |               --------------
X                | Follow_Path |         |               | Device_Map |
X                ---------------         |               --------------
X         _______/      /    \           |
X        /            /        \         |
X-------------      /    --------------  |
X| Next_Name |    /      | Search_Dir |  |
X-------------  /        --------------  |
X             /            /             |
X           /            /               |
X         /      ===============         |               ===============
X        |       || Read_File ||         |               || Load_File ||
X        |       ===============          \              ===============
X        |               |   \_________     \               /     |
X        |               |             |      \           /       |
X--------------  -----------------     |   ____ \  _____/    -----------------
X| Read_Inode |  | L_Load_Blocks |     |  |       \          | F_Load_Blocks |
X--------------  -----------------     |  |         \        -----------------
X        \                    \        |  |   _______ \  _________/    |
X          \                   \       |  |  |          \              |
X            \                  \      |  |  |    --------------  -------------
X              \                 \     |  |  |    | Read_Super |  | Phys_Copy |
X                \                \    |  |  |    --------------  -------------
X                  \_____________  \   |  |  |   _____/      \
X                                \  \  |  |  |  /              \
X                                 --------------         -------------
X                                 | Block_Read |         | Read_Part |
X                                 --------------         -------------
X                                        |     ________________/
X                                        |    /
X                                -----------------
X                                | LL_Block_Read |
X                                -----------------
X                                        |
X                                   ----------
X                                   | diskio |
X                                   ----------
X
X
XThe filenames used by the loader  have  been  extended  to  allow
Xspecification  of  what device to load the file from, in the for-
Xmat:
X                  device[.partition]:path
X
XThe devices that loader knows about are:
X     fd0, fd1, fd2, fd3          floppy diskettes
X     hd0.1, hd0.2, hd0.3, hd0.4  hard disk 0 parititons 1-4
X     hd1.1, hd1.2, hd1.3, hd1.4  hard disk 1 parititons 1-4
X
X
XCHANGES TO  MINIX
X
XI attempted to keep the number of changes to the Minix  internals
Xto a minimum.  I think I have succeeded fairly well with this.
X
XThe Kernel start-up in mpx88 was changed to expect  arguments  on
Xthe  stack  for main.  This is passed along in the same manner as
Xfor a normal process.  The kernel's "proc"  table  initialization
Xsection copies from the arguments rather than calculating it from
Xthe "sizes" array, which no longer  exists.   The  first  element
X(argv[0])  contains  information about the kernel; the next three
Xelements (argv[1,2,3]) are for MM,  FS  and  Init,  respectively.
XWith  the  removal  of  the sizes array, changes to the interrupt
Xvector  initialization  and  memory  driver  initialization  (for
X/dev/kmem) were requred.  Set_Vec was changed to use the physical
Xdata segment of the "Hardware" process rather than calculating it
Xfrom  "base_click+sizes[0]".   The  memory  driver was similarily
Xmodified, but using the virtual address of the stack segment  for
Xthe size of the kmem driver.
X
XThe Memory Manager no longer waits for the file system to tell it
Xthe  top  of  the  ram disk; instead, it uses a call added to the
XSYSTEM process, GET_MAP, to get a  process'  segment  maps.   The
X"BRK2"  call has now been changed to allocate any size out of the
Xglobal memory pool, rather than within a process' 64K  data  seg-
Xment.   This  call is used by the file system to allocate the ram
Xdisk's memory.
X
XThe File System uses it's parameters to determine which device to
Xmount  as the root filesystem, and if it is necessary to pre-load
Xthat device from another device (i.e. if it's a ram disk).   This
Xchange  wasn't  necessary to to the bootstrap process, but it was
Xat the top of my list of change I wanted to make  and  I  did  it
Xwhile giving the bootstrapper some time to "break in".
X
XFUTURE ENHACNEMENTS
X
XThe block-read makes two ROM calls to read  each  sector  of  the
Xblock.   This  should  be changed to one call, with logic for the
Xerrors returned when a track or cylinder is crossed.
X
XMemory size should be acquired from the ROM  and  passed  on  the
XMemory  Manager's stack rather than using the current memory size
Xcalculation which twiddles with the segment registers  and  pokes
Xthru all existing memory to find out how much there is there.
X
XAll RAM disk types should be separate minor devices in the Memory
Xdriver.   This  would  theoretically  allow  three  RAM disks: PC
X(under 640K), AT (Extended memory) and EMS.  Currently, it is ei-
Xther  PC  or  AT type RAM disk, determined by the size of the RAM
Xdisk.
X
XConfiguration of some device driver parameters (such as  keyboard
Xtype,  primary  printer  port,  video adapter type, and CPU type)
Xcould be done in the second stage and passed in on  the  Kernel's
Xstack.
X
XMore server processes could be configured into the system.   This
Xwould require the constant "LOW_USER" to become a variable passed
Xto the kernel.
X
XA Hard-Disk stage 1 bootstrapper needs to be written so Minix can
Xboot  fully  off  the  hard  drive.   One that might work, called
X"BOOTCODE.ASM" by W.D. Caglewas posted in Oct. 87.
X
XINSTALLING THE CHANGES
X
XMy changes add two directories to the Minix hierarchy,  "b1"  and
X"b2b".   The directory "b2b" was origionally named "b2", but what
XI'm sending out is the third major revision and  I  put  each  in
Xseparate directories.  Directory "b1" contains the first stage of
Xthe bootsrapper in source and binary.  If you wish to  reassemble
Xthe  sources,  write bootblok.asm to a dos disk and reassemble it
Xfrom dos.  Follow the instructions at the beginning of  the  code
Xfor  writing it directly to a Minix filesystem disk's boot block;
Xotherwise, run uudecode on the ".uu" file in the "b1"  directory,
Xand use
X        dd if=bootblok of=/dev/fd0
Xto write it to the boot block of a Minix filesystem.
X
XCompiling the second stage, in "b2b" simply requires a "make"  in
Xthat directory.  Before compiling you may want to change the dev-
Xice and file names of the system files in main.c.  It would real-
Xly  be  nice  to  have a configuration file to tell what files to
Xload for each piece of the system, but  I  haven't  written  that
Xyet.
X
XNext, patch all the diffs into your Kernel, FS,  MM,  header  and
Xlibrary  files,  and copy in the new mpx88.s file.  All diffs are
Xcontext diffs and require "patch" to install them.   If  you  are
Xpatching  into  a full set of Minix sources, you will not be able
Xto use the makefiles.  The way I do most  of  my  development  is
Xwith  a  parallel  copy  of  the  sources, only copying necessary
Xfiles.  My work  source  directory  is  /usr/src/minix,  and  the
Xparallel  directory is /usr/src/minix/newboot.  If you do not use
Xthe makefiles, you will need to merge some changes I have made to
Xthem  into  the generic Minix ones; first, I use "crtso.s" rather
Xthan "head.s" for FS, MM and Init.  This allows me to  link  with
X"cc"  rather  than "asld".  I have added the changed library file
X"syslib.s" to the end of my link commands so that I don't have to
Xrebuild my entire library with the changed file.  This was simply
Xeasier for testing.  Lastly, I "chmem" all  executables  down  to
X2000 bytes of stack space.
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
SHAR_EOF
if test 10220 -ne "`wc -c < 'README'`"
then
    echo shar: error transmitting "'README'" '(should have been 10220 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'MANIFEST'" '(1004 characters)'
if test -f 'MANIFEST'
then
    echo shar: will not over-write existing file "'MANIFEST'"
else
sed 's/^X//' << \SHAR_EOF > 'MANIFEST'
XFile Name                 Kit Number
X--------------            ----------
XMANIFEST                     1
XMANIFEST                     3
XREADME                       1
Xb1/bootblok.asm3             1
Xb1/bootblok.uu               1
Xb2b/Makefile                 1
Xb2b/bsu.s                    1
Xb2b/hdparam.h                1
Xb2b/loader.c                 2
Xb2b/main.c                   1
Xb2b/partition.h              1
Xb2b/stack.c                  1
Xb2b/standalone.c             1
Xb2b/type.h                   1
Xfs/cache.c.diff              1
Xfs/glo.h.diff                2
Xfs/inode.c.diff              2
Xfs/main.c.diff               3
Xfs/makefile                  2
Xfs/misc.c.diff               3
Xfs/super.c.diff              3
Xfs/utility.c.diff            3
Xh/com.diff                   3
Xkernel/main.c.diff           1
Xkernel/makefile              2
Xkernel/memory.c.diff         2
Xkernel/mpx88.s               2
Xkernel/system.c.diff         2
Xlib/syslib.diff              3
Xmm/main.diff                 3
SHAR_EOF
if test 1004 -ne "`wc -c < 'MANIFEST'`"
then
    echo shar: error transmitting "'MANIFEST'" '(should have been 1004 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b1/bootblok.asm3'" '(16625 characters)'
if test -f 'b1/bootblok.asm3'
then
    echo shar: will not over-write existing file "'b1/bootblok.asm3'"
else
sed 's/^X//' << \SHAR_EOF > 'b1/bootblok.asm3'
X;-----------------------------------------------------------------------------
X;
X;			MINIX primary bootstrap loader
X;			Dan Thureen
X;			CS548
X;			Jan. 10, 1988
X;
X;		Modified for inteligent second-stage loader
X;		Glen Overby
X;		March 1, 1988
X;									
X;	1) ROM monitor loads bootstrap sector from floppy (512 bytes)
X;	   to address 0000:7C00 and executes starting at 7C00.
X;
X;	2) Bootstrap program relocates itself to address 3000:7C00 to
X;	   get out of the way of the MINIX kernel area by reloading
X;	   the first block (1024 bytes) of the floppy to this address
X;	   and restarting.
X;	   (REMOVED 3/1/88GlenOverby)
X;
X;	3) Loader reads superblock,  loads root directory (inode #1)
X;	   into memory and searches for file named "boot".
X;
X;	4) The file "boot" is loaded into memory at address 0060:0000
X;	   and executed.
X;
X;	   (Load Address changed to 7C00:0, and a more intelligent 2nd stage
X;	   is now used, so ignore the "build" stuff.
X;	   3/1/88 GlenOverby)
X;
X;	   The file boot is currently the entire MINIX kernel image as
X;	   constructed by "build", with the initial boot sector stripped
X;	   off.
X;			dd if=image of=boot bs=512 skip=1
X;
X;	   The normal fsck startup utility is bypassed and can also be
X;	   omitted from the image if desired.
X;
X;	   The file "boot" can be replaced by a more intelligent 2nd stage
X;	   boot program which is driven by a configuration table to
X;	   permit more flexibility in loading selected modules, configuring
X;	   system parameters, etc.  A subroutine "gets" is provided for
X;	   string input if the user should want to select a different boot
X;	   file during system initialization.  The current version does not
X;	   call this but uses the hard coded file "boot".
X;
X;	   A small library of character and string I/O routines is provided
X;	   for future expansion. Also some small debugging routines for
X;	   doing memory dumps, etc.
X;
X;	   Note: All of the code below will not fit into the 1K block
X;	   allocated by the MINIX file system for the boot block.  The
X;	   optional sections are placed at the very end and the executable
X;	   image truncated to the 1K size limit.  An expanded ( 1K+ )
X;	   version can be run on a ZENITH clone by the following steps:
X;
X;		Load it into memory with the DOS DEBUG program
X;		Move it to 3000:7C00
X;		Trap to the ROM monitor <ctrl><alt><del>
X;		Use the monitor routines to execute, single-step, etc.
X;
X;	Because the .EXE file starting address is not CS:0100 the EXE2BIN
X;	utility cannot be used to convert to a straight binary image. This
X;	can, however, be done with DEBUG.
X;
X;		DEBUG BOOTBLOK.EXE  - loads at CS:7C00
X;		-WCS:7C00 0 0 2     - writes 2 sectors to block 0,1 of drive A.
X;				      MINIX file system disk must be in drive A
X;				      for this step
X;
X;	If a DOS file image is desired use DEBUG again:
X;
X;		DEBUG BOOTBLOK.EXE  - loads at CS:7C00, sets BX:CS to file size
X;		-NBOOTBLOK	    - select name for image file
X;		-RBX
X;		BX xxxx
X;		:0000		    - set image file size to 1024 bytes (400h)	
X;		-RCX
X;               CX xxxx
X;		:0400
X;		-WCS:7C00	    - write 1024 bytes to file from CS:7C00
X;
X;	This can be transferred to MINIX using dosread and patched in with
X;	dd.
X;
X; Additional Changes by:
X;	Glen Overby	<ncoverby@plains.nodak.edu>
X;			{uunet,umn-cs}!ndsuvax!ncoverby, 
X;			ncoverby@ndsuvax (bitnet)
X;
X; 03/01/88 GPO	Leave 1st stage at 0:7C00 and load second stage to 3200:0
X;		change segment stuff, remove boot sector reload
X; 04/29/88 GPO	Reduce the ammount of chatter
X;-----------------------------------------------------------------------------
X
X
X
X_text	segment	para public 'code'
X	assume	cs:_text, ds:_text	; Tiny data model with CS=DS=SS	
X
XDEBUG			EQU	0	; Set non-0 if debug code to be
X					; included
X
XS_IMAP_BLOCKS_OFF	equ	4
XS_ZMAP_BLOCKS_OFF	equ	6
XNR_DZONE_NUM		equ	7
XI_ZONE_OFF		equ	14
XI_SIZE_OFF		equ	4
XIND_ZONE_OFF		equ	28	
XBOOT_2_SEG		equ	3200h	;gpo 3/1/88
XBOOT_2_OFF		equ	0000h	;gpo 3/1/88
X
X
X;MINIX	segment	at 60h			; Define starting segment address
X;kernel	label	byte			; for minix kernel. Entry point at
X;MINIX	ends				; at offset 0000.
X
X
XHIGH_BOOT	segment at BOOT_2_SEG	; Define segment for relocated boot
X	org	BOOT_2_OFF              ; program at (3200:0000)
Xhstart2	label	byte			; Relocated program must have same
X					; relative location within segment
X					; as the original, otherwise there
X					; are problems accessing static
X					; variables
XHIGH_BOOT	ends
X
X
X	org	7C00h
Xstart1:
X	mov	ax, cs			; set up segment registers
X	mov	ds, ax                  ; tiny memory model CS=DS=SS
X	mov	ss, ax
X	mov	sp, offset estack       ; CS=AX=BOOT_2_SEG?
X;
X; Re-load entire boot block on top of executing code.  Looks gross, but
X; the second 512 bytes has to be loaded somewhere, somehow.
X; Only real problem is possibly the stack; just make sure it's out of
X; the 1K block range.
X
X;	cmp	ax, BOOT_2_SEG		; check if primary or secondary boot
X;       je	start2			; if secondary (relocated) skip the
X;	       				; next relocations step
X
X
X	call	reset			; reset drive
X
X	mov	lbn, 0                  ; read boot block into relocation
X	mov	bseg_no, 0		; area, so MINIX kernel will not
X	mov	boff_no, 7C00h		; overlay it when it loads (3000:7C00)
X	call	read_block
X      	jnc	cont_1
X
X      	call	read_error              ; error reading boot block - debug
X      	mov	bx, offset boot_err	; only (read_error notin 1st sector)
X      	jmp	terminate
X
Xcont_1:
Xif	DEBUG
X	mov	ax, offset block_buf    ; hex dump of boot block
X	push	ax
X	call	_print_block
X	pop	ax
X        call	getchar                 ; wait for key pressed
Xendif
X
X;	jmp	far ptr hstart2		; restart at relocated boot program
X
Xstart2:
X	mov	inode_no, 1             ; load root directory (inode=1)
X	mov	fseg, ds
X	mov	foff, offset dir_buf
X	call	load_file
X
X;	call	_newline
X;	mov	ax, n_blocks		; show file size	
X;	call	put4x
X;	call	_newline
X
X	mov	ax, n_blocks            ; loop to search for file "boot"
X	mov	cl, 10
X	shl	ax, cl			; ax = # of bytes in directory
X	mov	bx, 0
Xsearch_loop:
X	cmp	bx, ax                  ; bx = byte offset within directory
X	jge	no_match
X	cmp	word ptr dir_buf[bx], 0 ; ignore files with inode# 0
X	je	next_name
X	lea	si, dir_buf+2[bx]	; compare filename with boot_file_name
X	lea	di, boot_file_name
X	call	strcmp
X	je	found_file
Xnext_name:
X	add	bx, 16			; next directory entry
X	jmp	search_loop
Xno_match:
X	mov	bx, offset not_found_err	; file not found
X	jmp	terminate
Xfound_file:
X	mov	ax, word ptr dir_buf[bx]	; get inode #
X	mov	inode_no, ax
X
X	mov	fseg, BOOT_2_SEG	; 3/1/88gpo
X		;60h			; load file at 0060:0000
X	mov	foff, 0
X;	mov	fseg, ds			; test load into data segment
X;	mov	foff, offset    fil_buf
X
X	call	load_file
X
Xif	DEBUG
X	mov	bx, offset file_loaded
X	call	puts
X	mov	ax, n_blocks
X	call	put4x
X	call	_newline
X	call	getchar
Xendif
X
Xget_equals:
X; remove '=' key stuff 3/1/88gpo
X	mov	bx, offset ram_load		; MINIX uses scan code from
X	call	puts				; '=' key to select keyboard
X;	call	getchar				; type and initialize console
X;	cmp	al, '='				; driver
X;	jne	get_equals
X;
X;	mov	bx, ax				; scan code for '='
X;	jmp	far ptr kernel			; Jump to MINIX starting point
X;                              			; 0060:0000
X	jmp	far ptr hstart2
X
Xreset:	xor	ah, ah
X	mov	dl, drive
X	int	13h
X	ret
X
Xread_block:				; lbn = logical block #
X					; bseg_no = segment#
X					; boff_no = offset
X	mov	ax, lbn
X	add	ax, ax			; sector #  =  2 * block #	
X	mov	lsn, ax
X
X	mov	bx, ds                  ; es:bx = block load address
X	mov	es, bx                  ; use double buffering to avoid
X	mov	bx, offset block_buf	; DMA across 64K boundary problems
X
X	call	read_sector
X        jc	done_read_block		; read error
X	inc	lsn
X
X	mov	bx, offset block_buf + 512	; load 2nd sector of block
X	call	read_sector		
X	jc	done_read_block		; read error
X
Xmovit:	lea	si, block_buf           ; move block form buffer
X	mov	di, bseg_no		; to desired address (bseg_no:boff_no)
X	mov	es, di
X	mov	di, boff_no
X	mov	cx, 512
X	cld				
X	rep	movsw
X	
Xdone_read_block:
X	ret
X
Xread_sector:				; lsn = logical sector #
X					; sseg_no = segment#
X					; soff_no = offset
X	mov	retry, 10
Xread_again:
X	dec	retry			; retry 9 more times on error
X	js	done_read_sector		; abort
X
X	mov	ax, lsn
X
X	xor	dx, dx			; dx:ax / cylinder size
X	div	cylsize
X	mov	cl, ah			; high bits of cl get bits 8,9 of
X	ror	cl, 1			; cylinder #
X	ror	cl, 1
X	mov	ch, al			; low byte of cylinder #
X	mov	ax, dx
X	xor	dx, dx
X	div	tracksize
X	mov	dh, al			; dh = head #
X	or	cl, dl			; or in sector # bits
X	inc	cl 			; start sector # at 1 rather than 0
X	mov	dl, drive		; drive #
X	mov	ax, 0201h		; read 1 sector
X	int	13h
X
X	jc	read_again		; try again on error
Xdone_read_sector:
X	ret
X
X
Xcylsize		dw	12h		; The following variables  must
Xtracksize	dw	09h		; be located in the first 512 bytes
Xdrive		db	0		; because they are used in the primary
Xblock_size	dw	1024		; stage running at 0000:7C00 and the
Xinodes_per_block dw	32		; BIOS ROM only loads 1 sector
X
Xget_inode:				; input: inode_no
X					; returns pointer to corresponding
X					; inode in inode_p
X
X	mov	lbn, 1			; fetch super_block
X	mov	bseg_no, ds
X	mov	boff_no, offset super_buf
X	call	read_block
X	jnc	okay_super
X      	call	read_error
X      	mov	bx, offset super_err
X      	jmp	terminate
X
Xokay_super:
X
Xif	DEBUG
X	mov	ax, offset super_buf
X	push	ax
X	call	_print_block
X	pop	ax
X        call	getchar
Xendif
X
X	mov	ax, inode_no
X	dec	ax
X	xor	dx, dx
X	div	inodes_per_block
X	mov	i_offset, dx
X	add	ax, super_buf + S_IMAP_BLOCKS_OFF
X	add	ax, super_buf + S_ZMAP_BLOCKS_OFF
X	add	ax, 2
X	mov	i_block, ax
X	mov	lbn, ax
X	mov	bseg_no, ds
X	mov	boff_no, offset inode_buf
X	call	read_block
X	jnc	okay_inode
X
X      	call	read_error
X      	mov	bx, offset inode_err
X      	jmp	terminate
X
Xokay_inode:
X
Xif	DEBUG
X	mov	ax, offset inode_buf
X	push	ax
X	call	_print_block
X	pop	ax
X        call	getchar
Xendif
X
X	mov	bx, i_offset
X	mov	cx, 5
X	shl	bx, cl
X	add	bx, offset inode_buf
X	mov	inode_p, bx
X	ret
X
Xload_file:			; load file at fseg:foff given inode_no
X				; returns file size in n_blocks
X	call	get_inode
X	mov	bx, inode_p
X	mov	ax, I_SIZE_OFF[bx]	
X        mov	dx, I_SIZE_OFF+2[bx]
X        div	block_size
X        mov	n_blocks, ax    ; calculate # of blocks to load
X        test	dx, dx
X        jz	no_spill
X        inc	n_blocks	; partial block
Xno_spill:
X	cmp	n_blocks, NR_DZONE_NUM	; are there indirect blocks?
X	jle	no_indirect
X	mov	ax, IND_ZONE_OFF[bx]	; if so, read indirect block first
X	mov	lbn, ax
X	mov	bseg_no, ds
X	mov	boff_no, offset ind_buf
X	call	read_block
X	jnc	no_indirect
X
X      	call	read_error
X      	mov	bx, offset ind_err
X      	jmp	terminate
X
Xno_indirect:    		; set up loop to read all blocks in file
X	mov	ax, fseg
X	mov	bseg_no, ax
X	mov	ax, foff
X	mov	boff_no, ax
X	mov	load_i, 0
Xload_loop:
X	mov	bx, load_i      	; for load_i := 0 to n_blocks-1 do
X	cmp	bx, n_blocks
X	jge	done_load
X	add	bx, bx                  ; calculate block#
X	cmp	bx, NR_DZONE_NUM*2
X	jge	indirect_block
X	add	bx, inode_p
X	mov	ax, I_ZONE_OFF[bx]
X	jmp	cont_load
Xindirect_block:
X	mov	ax, ind_buf-14[bx]
Xcont_load:				; read the block
X	mov	lbn, ax
X	call	read_block
X	jnc	next_block
X
X      	call	read_error
X      	mov	bx, offset file_err
X      	jmp	terminate
X
Xnext_block:
X
X;	mov	ax, bseg_no		; reduce chatter 4/28/88GPO
X;	call	put4x
X;	mov	al, ':'
X;	call	putchar
X;	mov	ax, 0
X;	call	put4x
X;	call	_newline
X
X	add	bseg_no, 40h		; increment seg for next block
X	inc	load_i
X	jmp	load_loop
Xdone_load:
X	ret
X
Xram_load	db	'Second boot stage loaded, Starting ...', 13, 10, 0
X			;'Type "=" to load RAM disk ->  ', 0
Xboot_err	db	'Error reading Boot block', 13, 10, 0
Xsuper_err	db	'Error reading Super_block', 13, 10, 0
Xinode_err	db	'Error reading Inode', 13, 10, 0
Xind_err		db	'Error reading Indirect Block', 13, 10, 0
Xfile_err	db	'Error reading file', 13, 10, 0
Xnot_found_err	db	'Boot file not found', 13, 10, 0
Xfile_loaded	db	'File loaded - blocks = ', 0
Xboot_file_name	db	'boot', 12 dup (0)
X
X
X;-----------------------------------------------------------------------------
X;
X;	All routines which follow are optional, mostly character I/O
X;	procedures for debugging purposes, which can be stripped out
X;	if necessary.  Total code and initialized data must come first
X;	and must fit into 1K.
X;
X;-----------------------------------------------------------------------------
X
Xterminate:
X	call	puts
Xexit:	jmp	exit			; hang in harmless loop on error
X	
X
Xputchar:				; char in AL, return code in AX
X	mov	ah, 0Eh
X	xor	bl, bl
X	int	10h
X	ret
X
Xputs: 					; print string, address in BX
X	mov	al, byte ptr [bx]
X	test	al, al
X	je	doneputs
X	push	bx
X	call	putchar
X	pop	bx
X	inc	bx
X	jmp	puts
Xdoneputs:
X	ret
X
X_newline:
X	mov	al, 13
X	call	putchar
X        mov	al, 10
X        call	putchar
X        ret
X
Xgetchar:				; char returned in AL
X	xor	ah, ah
X	int	16h
X	cmp	al, 03h
X	je	exit
X	push	ax
X	push	bx
X	call	putchar
X	pop	bx
X	pop	ax
X	ret			
X
Xgets:					; read string into buffer
X	call	getchar			; address in bx
X	cmp	al, 0Dh
X	je	done_gets
X	mov	byte ptr [bx], al
X	inc	bx
X	jmp	gets
Xdone_gets:
X	mov	byte ptr [bx], 0
X	ret
X
Xput2x:					; print hex byte in AL
X	push 	ax
X	shr     ax, 1
X	shr     ax, 1
X	shr     ax, 1
X	shr     ax, 1
X	call	put_byte
X	pop	ax
Xput_byte:
X	and	al, 0Fh	
X	add	al, 30h
X	cmp	al, 39h
X	jle	nothex
X	add	al, 07h
Xnothex: call	putchar
X	ret
X
Xput4x:					; print hex word in AX
X	push	ax
X	xchg	al, ah
X	call	put2x
X	pop	ax
X	call	put2x
X	ret
X
Xstrcmp:					; string compare
X	push	ds
X	pop	es			; addresses in SI & DI
X	cld
X	mov	cx, 0Eh
X	repe	cmpsb
X	ret				; returns with flags set based
X					; upon compare result	
X
Xread_error:
X	push	ax
X	push	bx
X	push	es
X	push	cx
X	push	dx
X	push	cx
X	push	dx
X	call	_newline
X
X	pop	ax		; print drive#
X	call	put2x
X	mov	al, ' '
X	call	putchar
X	
X	pop	ax		; print cylinder#
X	xchg	ah, al
X	call	put2x
X	mov	al, ' '
X	call	putchar
X
X	pop	ax		; print head#
X	xchg	ah, al
X	call	put2x
X	mov	al, ' '
X	call	putchar
X
X	pop	ax		; print sector#
X	call	put2x
X	mov	al, ' '
X	call	putchar
X
X	pop	ax		; print segment
X	call	put4x
X	mov	al, ':'
X	call	putchar
X
X	pop	ax		; print offset
X	call	put4x
X	call	_newline
X
X        pop	ax
X	mov	al, ah
X	call	put2x
X	mov	al, ' '
X	call	putchar
X	ret
X
X
X_print_block	proc	near
X	push	bp
X	mov	bp,sp
X	push	word ptr [bp+4]
X	call	near ptr _print_sector
X	pop	cx
X	mov	ax,word ptr [bp+4]
X	add	ax,512
X	push	ax
X	call	near ptr _print_sector
X	pop	cx
X@1:
X	pop	bp
X	ret	
X_print_block	endp
X
X
X_print_sector	proc	near
X	push	si
X	push	di
X	push	bp
X	mov	bp,sp
X	dec	sp
X	dec	sp
X	xor	si,si
X	call	near ptr _newline
X	xor	di,di
X	jmp	short @6
X@5:
X	mov	ax, si
X	call	put4x
X	mov	bx, offset _s@
X	mov	word ptr [bp-2],0
X	jmp	short @10
X@9:
X	mov	ax,si
X	inc	si
X	mov	bx,ax
X	add	bx,word ptr [bp+8]
X	mov	al,byte ptr [bx]
X	call	put2x
X	mov	al,' '
X	call	putchar
X@8:
X	inc	word ptr [bp-2]
X@10:
X	cmp	word ptr [bp-2],16
X	jb	@9
X@7:
X	mov	ax,16
X	push	ax
X	mov	ax,word ptr [bp+8]
X	add	ax,si
X	add	ax,-16
X	push	ax
X	call	near ptr _prints
X	pop	cx
X	pop	cx
X@4:
X	inc	di
X@6:
X	cmp	di,32
X	jb	@5
X@3:
X	call	near ptr _newline
X@2:
X	mov	sp,bp
X	pop	bp
X	pop	di
X	pop	si
X	ret	
X_print_sector	endp
X
X
X_prints	proc	near
X	push	si
X	push	di
X	push	bp
X	mov	bp,sp
X	mov	si,word ptr [bp+8]
X	mov	bx,offset _s@+3
X	call	puts
X	xor	di,di
X	jmp	short @15
X@14:
X	cmp	byte ptr [si],32
X	jl	@16
X	cmp	byte ptr [si],126
X	jg	@16
X	mov	al,byte ptr [si]
X	call 	putchar
X	jmp	short @17
X@16:
X	mov	al, '.'
X	call	putchar
X@17:
X@13:
X	inc	di
X	inc	si
X@15:
X	cmp	di,word ptr [bp+10]
X	jl	@14
X@12:
X	call	near ptr _newline
X@11:
X	pop	bp
X	pop	di
X	pop	si
X	ret	
X_prints	endp
X
X_s@	label	byte
X	db	32
X	db	32
X	db	0
X	db	32
X	db	32
X	db	32
X	db	32
X	db	0
X
X
X;-----------------------------------------------------------------------------
X;
X;	Most of the following declarations are necessary but are all
X;	uninitialized data areas so they can go anywhere after the
X;	necessary code. Declarations which are followed by * are for
X;	debug purposes only.
X;
X;-----------------------------------------------------------------------------
X
X
Xretry		db	?	; dist read retry counter
Xlbn		dw	?	; logical block #
Xbseg_no		dw	?	; block load segment #
Xboff_no		dw	?	; block load offset  #
Xlsn		dw	?	; logical sector #
X
Xi_block		dw	?	; inode block #
Xi_offset	dw	?	; inode block offset
Xinode_no	dw	?	; inode number
Xinode_p		dw	?	; pointer to inode structure
X
Xload_i		dw	?	; loop counter for file load
Xfseg		dw	?       ; segment for file load
Xfoff		dw	?	; offset for file load
Xn_blocks	dw	?       ; file size in blocks
X
Xblock_buf	db	1024 dup (?)	; I/O buffer for all disk reads
X;boot_buf	db	1024 dup (?)    ; Boot block copied here
Xsuper_buf	dw	512  dup (?)    ; Super block loaded here
Xinode_buf	dw	512  dup (?)    ; Inode block loaded here
Xind_buf		dw	512  dup (?)    ; Indirect block loaded here (sometimes)
Xdir_buf		dw	512  dup (?)	; root file directory loaded here
X;fil_buf		db	20 dup (1024 dup (?))	; temporary file load area
X
Xstack		dw	100 dup (?)     ; small stack area for boot only
Xestack 		label	word            ; init SP here
X
X
X_text	ends
X
X	end start1
SHAR_EOF
if test 16625 -ne "`wc -c < 'b1/bootblok.asm3'`"
then
    echo shar: error transmitting "'b1/bootblok.asm3'" '(should have been 16625 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b1/bootblok.uu'" '(1439 characters)'
if test -f 'b1/bootblok.uu'
then
    echo shar: will not over-write existing file "'b1/bootblok.uu'"
else
sed 's/^X//' << \SHAR_EOF > 'b1/bootblok.uu'
Xbegin 644 bootblok
XMC,B.V([0O#V5Z($ QP9=@   QP9?@   QP9A@ !\Z'4 <PGH. .[*G[IO0+'
XM!FF  0",'F^ QP9Q@'60Z#,!H7. L0K3X+L  #O8?1F#OW60 '0-C;=WD(T^
XMV7[H]@)T"X/#$.OCNZM^Z7T"BX=UD*-I@,<&;X  ,L<&<8   .CP +L!?NAM
XM NH    R,N2*%@9]S1/#H5V  \"C8X",VX[#NW6 Z", <B#_!F. NW6"Z!< 
XM<A2--G6 BSY?@(['BSYA@+D  OSSI</&!ER "I#^#ER >"JA8X STO<V GV*
XMS-#)T,F*Z(O",]+W-@1]BO *RO[!BA8&?;@! LT3<M##$@ )    !"  QP9=
XM@ $ C!Y?@,<&88!UA.AX_W,)Z#L"NT5^Z< !H6F 2#/2]S8)?8D69X #!GF$
XM P9[A 4" *-E@*-=@(P>7X#'!F& =8CH0?]S">@$ KMA?NF) 8L>9X"Y!0#3
XMXX'#=8B)'FN P^B6_XL>:X"+1P2+5P;W-@=]HW. A=)T!/\&<X"#/G. !WX>
XMBT<<HUV C!Y?@,<&88!UC.CN_G,)Z+$!NW=^Z38!H6^ HU^ H7& HV& QP9M
XM@   BQYM@#L><X!],0/;@_L.?0H#'FN BT<.ZP60BX=GC*-=@.BL_G,)Z&\!
XMNY9^Z?0 @P9?@$#_!FV Z\7#4V5C;VYD(&)O;W0@<W1A9V4@;&]A9&5D+"!3
XM=&%R=&EN9R N+BX-"@!%<G)O<B!R96%D:6YG($)O;W0@8FQO8VL-"@!%<G)O
XM<B!R96%D:6YG(%-U<&5R7V)L;V-K#0H 17)R;W(@<F5A9&EN9R!);F]D90T*
XM $5R<F]R(')E861I;F<@26YD:7)E8W0@0FQO8VL-"@!%<G)O<B!R96%D:6YG
XM(&9I;&4-"@!";V]T(&9I;&4@;F]T(&9O=6YD#0H 1FEL92!L;V%D960@+2!B
XM;&]C:W,@/2  8F]O=                .@) .O^M XRV\T0PXH'A,!T"%/H
XM[_];0^ORP[ -Z.7_L KHX/_#,N3-%CP#=-504^C2_UM8P^CM_SP-= 6(!T/K
XM],8' ,-0T>C1Z-'HT>CH 0!8) \$,#PY?@($!^BE_\-0AL3HW_]8Z-O_PQX'
XM_+D. /.FPU!3!E%245+HG/]8Z,/_L"#H??]8AN#HN/^P(.AR_UB&X.BM_[ @
XMZ&?_6.BD_[ @Z%[_6.BV_[ ZZ%7_6.BM_^AD_UB*Q.B)_[ @Z$/_PU6+[/]V
XM!.@. %F+1@0%  )0Z , 65W#5E=5B^Q,3#/VZ#7_,__K/8O&Z'+_NU2 QT;^
XB  #K%8O&1HO8 UX(B@?H0/^P(.CZ_O]&_H-^_A!RY;@0 (O&
X 
Xend
SHAR_EOF
if test 1439 -ne "`wc -c < 'b1/bootblok.uu'`"
then
    echo shar: error transmitting "'b1/bootblok.uu'" '(should have been 1439 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b2b/Makefile'" '(235 characters)'
if test -f 'b2b/Makefile'
then
    echo shar: will not over-write existing file "'b2b/Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'b2b/Makefile'
XCFLAGS=-I/usr/src/minix -Di8088
X
X#.c.s:
X#	cc $(CFLAGS) -c $*.c
X
Xall:	loader.s stack.s standalone.s main.s
X	asld -s -o b2 bsu.s main.s loader.s stack.s standalone.s /usr/lib/libc.a /usr/lib/end.s > b2.sym
X	dd if=b2 of=boot bs=32 skip=1
SHAR_EOF
if test 235 -ne "`wc -c < 'b2b/Makefile'`"
then
    echo shar: error transmitting "'b2b/Makefile'" '(should have been 235 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b2b/bsu.s'" '(5153 characters)'
if test -f 'b2b/bsu.s'
then
    echo shar: will not over-write existing file "'b2b/bsu.s'"
else
sed 's/^X//' << \SHAR_EOF > 'b2b/bsu.s'
X|
X| Second-Stage Bootstrap assembly level run-time support
X| Derrived from "tools/fsck1.s" and "kernel/klib88.s"
X|
XSTACKSIZE = 16384
X
X.globl _main, endtext, enddata, endbss
X.globl __putc, __getc, _reset_diskette, _diskio
X.globl csv, cret, begtext, begdata, begbss
X.globl _cylsiz, _tracksiz
X|, _drive
X.globl _ds, _lcopy, _sp
X
X.text
Xbegtext:
Xstart:
X	mov	ax,cs		| ds=es=ss=cs 
X	mov	es,ax
X	mov	ds,ax
X	mov	ss,ax
X|	mov	dx,bx		| bootblok puts # sectors/track in bx
X	xor	ax,ax
X	mov	bx,#enddata	| prepare to clear bss
X	mov	cx,#endbss
X	sub	cx,bx
X	shr	cx,*1
Xst.1:	mov	(bx),ax		| clear bss
X	add	bx,#2
X	loop	st.1
X
X|	mov	_tracksiz,dx	| dx (was bx) is # sectors/track
X|	add	dx,dx
X|	mov	_cylsiz,dx	| # sectors/cylinder
X	mov	sp,#kerstack+STACKSIZE
X	call	_main
Xst.2:	mov	bx,ax		| put scan code for '=' in bx
X|	mov	bp,#_sizes	| bp points to 'sizes' array
X	mov	sp,_ksp		| sp first 'cause we'll destroy ds
X	mov	dx,_kds
X	mov	ds,dx
X	mov	ss,dx
X	nop
X	cli
X|	mov	dx,#0x60
X|leave ES where it is so kernel can find the a.out table...
X|	mov	es,dx
X	nop
X	jmpi	0,0x60		| jmp to kernel
X
X|_exit:
X|	mov	bx,_tracksiz
X	jmp	start
X
X
X__putc:
X	xor	ax,ax
X	call	csv
X	movb	al,4(bp)	| al contains char to be printed
X	movb	ah,#14		| 14 = print char
X	movb	bl,*1		| foreground color
X	push	bp		| not preserved
X	int	0x10		| call BIOS VIDEO_IO
X	pop	bp
X	jmp	cret
X
X__getc:
X	xorb	ah,ah
X	int	0x16
X	ret
X
X_ds:
X	mov	ax,ds
X	ret
X_sp:
X	mov	ax,sp
X	ret
X
X_reset_diskette:
X	xor	ax,ax
X	call	csv
X	push	es		| not preserved
X	int	0x13		| call BIOS DISKETTE_IO
X	pop	es
X	jmp	cret
X
X
X| handle diskio(RW, sector_number, buffer, sector_count, drive) call
X| Do not issue a BIOS call that crosses a track boundary
X_diskio:
X	xor	ax,ax
X	call	csv
X	mov	tmp1,#0		| tmp1 = # sectors actually transferred
X	mov	di,10(bp)	| di = # sectors to transfer
X	mov	tmp2,di		| di = # sectors to transfer
Xd0:	mov	ax,6(bp)	| ax = sector number to start at
X	xor	dx,dx		| dx:ax is dividend
X	div	_cylsiz		| ax = cylinder, dx = sector within cylinder
X	movb	cl,ah		| cl = hi-order bits of cylinder
X	rorb	cl,#1		| BIOS expects hi bits in a funny place
X	rorb	cl,#1		| ditto
X	movb	ch,al		| cx = sector # in BIOS format
X	mov	ax,dx		| ax = sector offset within cylinder
X	xor	dx,dx		| dx:ax is dividend
X	div	_tracksiz	| ax = head, dx = sector
X	movb	dh,al		| dh = head
X	orb	cl,dl		| cl = 2 high-order cyl bits || sector
X	incb	cl		| BIOS counts sectors starting at 1
X	movb	dl,12(bp)	| dl = drive code (0-3 or 0x80 - 0x81)
X	mov	bx,8(bp)	| bx = address of buffer
X	movb	al,cl		| al = sector #
X	addb	al,10(bp)	| compute last sector
X	decb	al		| al = last sector to transfer
X	cmpb	al,_tracksiz	| see if last sector is on next track
X	jle	d1		| jump if last sector is on this track
X	mov	10(bp),#1	| transfer 1 sector at a time
Xd1:	movb	ah,4(bp)	| ah = READING or WRITING
X	addb	ah,*2		| BIOS codes are 2 and 3, not 0 and 1
X	movb	al,10(bp)	| al = # sectors to transfer
X	mov	tmp,ax		| al is # sectors to read/write
X	push	es		| BIOS ruins es
X	int	0x13		| issue BIOS call
X	pop	es		| restore es
X	cmpb	ah,*0		| ah != 0 means BIOS detected error
X	jne	d2		| exit with error
X	mov	ax,tmp		| fetch count of sectors transferred
X	xorb	ah,ah		| count is in ax
X	add	tmp1,ax		| tmp1 accumulates sectors transferred
X	mov	si,tmp1		| are we done yet?
X	cmp	si,tmp2		| ditto
X	je	d2		| jump if done
X	inc	6(bp)		| next time around, start 1 sector higher
X	add	8(bp),#0x200	| move up in buffer by 512 bytes
X	jmp	d0
Xd2:	jmp	cret
X
Xcsv:
X	pop	bx
X	push	bp
X	mov	bp,sp
X	push	di
X	push	si
X	sub	sp,ax
X	jmp	(bx)
X
Xcret:
X	lea	sp,*-4(bp)
X	pop	si
X	pop	di
X	pop	bp
X	ret
X
X|*===========================================================================*
X|*				phys_copy				     *
X|*===========================================================================*
X| This routine copies a block of physical memory.  It is called by:
X|	lcopy(destination segment, offset, source segment, offset, length)
X|    phys_copy( (long) source, (long) destination, (long) bytecount)
X
X_lcopy:
X	pushf			| save flags
X	cli			| disable interrupts
X	push bp			| save the registers
X	push ax			| save ax
X	push bx			| save bx
X	push cx			| save cx
X	push dx			| save dx
X	push si			| save si
X	push di			| save di
X	push ds			| save ds
X	push es			| save es
X	mov bp,sp		| set bp to point to saved es
X
X  L0:	mov ax,22(bp)		| ax = segment of  destination
X	mov di,24(bp)		| di = offset of destination
X	mov es,ax		| es = destination click
X
X	mov ax,26(bp)		| ax = segment of  source
X	mov si,28(bp)		| si = offset of source
X
X	mov cx,30(bp)		| cx = low-order word of byte count
X
X	mov ds,ax		| ds = source click
X
X	test cx,*0x0001		| should we copy a byte or a word at a time?
X	jz L5			| jump if even
X	rep			| copy 1 byte at a time
X	movb			| byte copy
X	jmp L6			| check for more bytes
X
X  L5:	shr cx,*1		| word copy
X	rep			| copy 1 word at a time
X	movw			| word copy
X
X  L6:	pop es			| restore all the saved registers
X	pop ds			| restore ds
X	pop di			| restore di
X	pop si			| restore si
X	pop dx			| restore dx
X	pop cx			| restore cx
X	pop bx			| restore bx
X	pop ax			| restore ax
X	pop bp			| restore bp
X	popf			| restore flags
X	ret			| return to caller
X
X.data
Xbegdata:
Xtmp:	.word 0
Xtmp1:	.word 0
Xtmp2:	.word 0
X.bss
Xbegbss:
Xkerstack:	.zerow STACKSIZE/2	| kernel stack
SHAR_EOF
if test 5153 -ne "`wc -c < 'b2b/bsu.s'`"
then
    echo shar: error transmitting "'b2b/bsu.s'" '(should have been 5153 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b2b/hdparam.h'" '(580 characters)'
if test -f 'b2b/hdparam.h'
then
    echo shar: will not over-write existing file "'b2b/hdparam.h'"
else
sed 's/^X//' << \SHAR_EOF > 'b2b/hdparam.h'
X/*
X *	Hard Disk ROM Parameter Table structure
X *
X * Hawked from Minix's kernel/xt_wini.c
X * note: this table is not EXACT; it is intened to be loaded by a routine
X * that does the actual memory poking
X */
X
X struct param {
X	int nr_cyl;		/* Number of cylinders */
X	int nr_heads;		/* Number of heads */
X	int reduced_wr;		/* First cylinder with reduced write current */
X	int wr_precomp;		/* First cylinder with write precompensation */
X	int max_ecc;		/* Maximum ECC burst length */
X	int ctrl_byte;		/* Copied control-byte from bios tables */
X	int sectors;		/* sectors per track */
X};
SHAR_EOF
if test 580 -ne "`wc -c < 'b2b/hdparam.h'`"
then
    echo shar: error transmitting "'b2b/hdparam.h'" '(should have been 580 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b2b/main.c'" '(3309 characters)'
if test -f 'b2b/main.c'
then
    echo shar: will not over-write existing file "'b2b/main.c'"
else
sed 's/^X//' << \SHAR_EOF > 'b2b/main.c'
X/*
X			Minix Second Stage Boot Loader
X
XIn this program, all the elements of the Minix system are loaded into memory
Xfrom binary files on a filesystem.  All parts of the system are loaded
Xlike any other Minix process, with Text, Data and Stack areas and command
Xoptions on a "command line" (which is actually in a binary format).
X
X*/
X#include <minix/const.h>
X#include <minix/type.h>
X#include <fs/const.h>
X#include <fs/type.h>
X#include <fs/inode.h>
X#include <fs/super.h>
X#include <stdio.h>
X#include <errno.h>
X#include <a.out.h>
X#include "type.h"
X
X/*#define FLOPPY	/* define for fd(0) rather than hd(0,2) */
X/*#undef printf		/* defined in fs/const.h as 'printk' */
X#undef getchar		/* don't want the macros */
X#undef putchar
X#undef putc
X#undef getc
X
Xextern int sizes[], kds, ksp;
Xint error = 0;
Xint segment = 0x60;
Xint filenum = 0;
X
X/*#define DEBUG*/
X
XAOUT load(file)
Xchar *file;
X{	INODE inode;
X	AOUT aout;
X	long t, d, b, s;	/* sizes of Text, Data, BSS and Stack segs */
X
X/*	printf("**********************************************************\n");*/
X	printf("%s\n",file);
X#ifdef DEBUG
X	printf("Segment = 0x%x\n", segment);
X	fgetc();
X#endif
X	if((inode = open_file(file)) == NULL) {
X		error = 1;
X		perror("boot");
X	}
X	aout = load_file(inode, segment);
X#ifdef DEBUG
X	dump_exec(aout);
X#endif
X	if(aout->a_flags & A_SEP) {
X		t = aout->a_text;
X		d = aout->a_data;
X	} else {
X		t = 0;
X		d = aout->a_data + aout->a_text;
X	}
X	b = aout->a_bss;
X	s = aout->a_total - d - b;
X
X#ifdef DEBUG
X	printf("t=%ld d=%ld b=%ld s=%ld\n", t, d, b, s);
X#endif
X	/* write Text, (Data+BSS+STACK) segment info on top of header
X	 * relocation info (that won't be used on 80x86 machines)
X	 */
X	aout->a_trsize = t;
X	aout->a_drsize = d + b;	/* data segment (not including stack) */
X	aout->a_tbase = (long) segment;
X	aout->a_dbase = (long) (segment + clicks(t));
X#ifdef DEBUG
X	printf("trsize=0x%x tbase=0x%x drsize=0x%x dbase=0x%x total=0x%x\n",
X		(int) aout->a_trsize, (int) aout->a_tbase,
X		(int) aout->a_drsize, (int) aout->a_dbase, aout->a_total);
X#endif
X
X	zero_mem(segment + clicks(t + d), 0, (int) b);
X
X	segment += clicks(t + d + b + s);
X/*	sizes[filenum * 2] = clicks(t);
X	sizes[filenum * 2 +1] = clicks(d + b + s);	*/
X	filenum++;
X
X	return(aout);
X}
X
Xmain()
X{	AOUT aout[10];
X	char eq = '\0';
X	int i, stack[5];
X
X	printf("Hello World\n");
X
X#ifdef FLOPPY
X	aout[0] = load("fd0:/etc/kernel");
X	aout[1] = load("fd0:/etc/mm");
X	aout[2] = load("fd0:/etc/fs");
X	aout[3] = load("fd0:/etc/init");
X#else
X	aout[0] = load("hd0.2:/etc/kernel");
X	aout[1] = load("hd0.2:/etc/mm");
X	aout[2] = load("hd0.2:/etc/fs");
X	aout[3] = load("hd0.2:/etc/init");
X#endif
X
X#ifdef DEBUG
X	printf("System Loaded, Initializing...\n");
X	fgetc();
X#endif
X
X	stack[0] = aout[0]->a_dbase + aout[0]->a_total;
X	mmstack(aout[1],stack+1);
X	fsstack(aout[2],stack+2);
X	ksp = kstack(aout, stack);
X
X/*	for(i = 0;i < 8;i++)
X		printf("sizes[%d] = %d %x\n", i, sizes[i], sizes[i]);*/
X
X/*	printf("Segment = 0x%x\n", segment);*/
X
X	kds = 0x60 + ((aout[0]->a_flags & A_SEP) ? clicks(aout[0]->a_text) : 0);
X	printf("Kernel CS=0x%x DS=0x%x SP=0x%x\n", aout[0]->a_text, kds, ksp);
X
X	if(error) {
X		printf("\n\n\nError occured durring system load!!\n");
X		printf("          REBOOT NOW!\n");
X		fgetc();
X	} else {
X		printf("\n\nStrike '=' to execute system:");
X		while((eq=fgetc()) != '=');
X		return(eq);
X	}
X}
SHAR_EOF
if test 3309 -ne "`wc -c < 'b2b/main.c'`"
then
    echo shar: error transmitting "'b2b/main.c'" '(should have been 3309 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b2b/partition.h'" '(729 characters)'
if test -f 'b2b/partition.h'
then
    echo shar: will not over-write existing file "'b2b/partition.h'"
else
sed 's/^X//' << \SHAR_EOF > 'b2b/partition.h'
X/*
X *	Description of entry in the hard disks's partition table
X *
X * Hawked from Minix's commands/fdisk.c program
X */
X
Xstruct part_entry {
X	char	bootind;	/* boot indicator 0/0x80	*/
X	char	start_head;	/* head value for first sector	*/
X	char	start_sec;	/* sector value for first sector*/
X	char	start_cyl;	/* track value for first sector	*/
X	char	sysind;		/* system indicator 00=?? 01=DOS*/
X	char	last_head;	/* head value for last sector	*/
X	char	last_sec;	/* sector value for last sector	*/
X	char	last_cyl;	/* track value for last sector	*/
X	long	lowsec;		/* logical first sector		*/
X	long	size;		/* size of partion in sectors	*/
X};
X
X/*#define SECSIZE		512		/* sector size		*/
X#define	TABLEOFFSET	0x1be		/* offset in boot sector*/
SHAR_EOF
if test 729 -ne "`wc -c < 'b2b/partition.h'`"
then
    echo shar: error transmitting "'b2b/partition.h'" '(should have been 729 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b2b/stack.c'" '(7832 characters)'
if test -f 'b2b/stack.c'
then
    echo shar: will not over-write existing file "'b2b/stack.c'"
else
sed 's/^X//' << \SHAR_EOF > 'b2b/stack.c'
X/*
X	Boot Stage 2 Stack construction
X
XThese routines will construct an initial stack for ther Kernel, Memory Manager,
XFile System and Init programs.
X
X*/
X#include <minix/const.h>
X#include <minix/type.h>
X#include <kernel/const.h>
X#include <kernel/type.h>
X#include <kernel/proc.h>
X#include <a.out.h>
X#include <errno.h>
X#include "type.h"
X
Xextern char **environ;			/* environment pointer */
X
X#define	PTRSIZE	sizeof(char *)
X
X/*#define DEBUG	/**/
X
X/*
X * Build a stack from a set of arguments.
X *
X * This function is derived from Minix's lib/exec.c(execve) function.
X */
Xint buildstack(argv, argsize, envp, envsize, stack)
Xchar *argv[];			/* pointer to argument array */
Xint argsize;			/* size of argument array elements (fixed)*/
Xchar *envp[];			/* pointer to environment */
Xint envsize;			/* size of environment array elements (fixed)*/
Xchar *stack;			/* memory to build the stack in */
X{
X/*  char stack[MAX_ISTACK_BYTES];*/
X  char **argorg, **envorg, *hp, **ap, *p;
X  int i, nargs, nenvps, stackbytes, offset;
X  extern errno;
X
X  /* Count the argument pointers and environment pointers. */
X  nargs = 0;
X  nenvps = 0;
X  argorg = argv;
X  envorg = envp;
X  while (*argorg++ != NIL_PTR) nargs++;
X  while (*envorg++ != NIL_PTR) nenvps++;
X
X  /* Prepare to set up the initial stack. */
X  hp = &stack[(nargs + nenvps + 3) * PTRSIZE];
X#ifdef DEBUG
Xprintf("nargs=%d nenvps=%d hp=0x%x\n",nargs,nenvps,hp);
X#endif
X  if (hp + nargs + nenvps >= &stack[MAX_ISTACK_BYTES]) {
X	errno = E2BIG;
X	return(-1);
X  }
X  ap = (char **) stack;
X  *ap++ = (char *) nargs;
X
X  /* Prepare the argument pointers and strings. */
X  for (i = 0; i < nargs; i++) {
X	offset = hp - stack;
X	*ap++ = (char *) offset;
X	p = *argv++;
X	copy(hp, p, argsize);
X	hp += argsize;
X	if (hp >= &stack[MAX_ISTACK_BYTES]) {
X		errno = E2BIG;
X		return(-1);
X	}
X  }
X  *ap++ = NIL_PTR;
X
X  /* Prepare the environment pointers and strings. */
X  for (i = 0; i < nenvps; i++) {
X	offset = hp - stack;
X	*ap++ = (char *) offset;
X	p = *envp++;
X
X	hp += envsize;
X	if (hp >= &stack[MAX_ISTACK_BYTES]) {
X		errno = E2BIG;
X		return(-1);
X	}
X  }
X  *ap++ = NIL_PTR;
X  stackbytes = ( ( (int)(hp - stack) + PTRSIZE - 1)/PTRSIZE) * PTRSIZE;
X  return(stackbytes);
X}
X
X/*===========================================================================*
X *				patch_ptr				     *
X *===========================================================================*/
X/* taken from Minix's mm/exec.c */
XPRIVATE patch_ptr(stack, base)
Xchar stack[MAX_ISTACK_BYTES];	/* pointer to stack image within MM */
Xvir_bytes base;			/* virtual address of stack base inside user */
X{
X/* When doing an exec(name, argv, envp) call, the user builds up a stack
X * image with arg and env pointers relative to the start of the stack.  Now
X * these pointers must be relocated, since the stack is not positioned at
X * address 0 in the user's address space.
X */
X
X  char **ap, flag;
X  vir_bytes v;
X
X  flag = 0;			/* counts number of 0-pointers seen */
X  ap = (char **) stack;		/* points initially to 'nargs' */
X  ap++;				/* now points to argv[0] */
X  while (flag < 2) {
X	if (ap >= (char **) &stack[MAX_ISTACK_BYTES]) return;	/* too bad */
X	if (*ap != NIL_PTR) {
X		v = (vir_bytes) *ap;	/* v is relative pointer */
X		v += base;		/* relocate it */
X		*ap = (char *) v;	/* put it back */
X	} else {
X		flag++;
X	}
X	ap++;
X  }
X}
X
X/*
X * ProcStack - give a process a stack
X *
X * A stack is built up from the arguments (argv, envp) given, and copied
X * into the process' stack space.  The address that the stack pointer should
X * be assigned is returned.
X */
Xprocstack(argv, sizeargv, envp, sizeenvp, proc)
Xchar **argv;
Xint sizeargv;
Xchar **envp;
Xint sizeenvp;
XAOUT proc;
X{	static char stack[MAX_ISTACK_BYTES];
X	int	size,		/* size of process' stack */
X		seg, offset;	/* segment and offset of stack dest. */
X
X#ifdef DEBUG
X	printf("Procstack...\n");
X#endif
X	size=buildstack(argv, sizeargv, envp, sizeenvp, stack);
X	seg = (int) proc->a_dbase;
X	offset = (int) proc->a_total - size;
X	patch_ptr(stack, offset);
X#ifdef DEBUG
X	printf("seg= 0x%x offset=0x%x length=0x%x\n", seg, offset, size);
X	printf("trsize=0x%x tbase=0x%x drsize=0x%x dbase=0x%x total=0x%x\n",
X		(int) proc->a_trsize, (int) proc->a_tbase,
X		(int) proc->a_drsize, (int) proc->a_dbase,
X		(int) proc->a_total);
X#endif
X	lcopy(seg, offset, ds(), stack, size);
X	return(offset);
X}
X
X/*
X *	Kernel Stack
X *
X *  The kernel stack consists of a "proc" array as argv and a device
X * configuration array as envp.  The processes present in the proc
X * array start with PID 0 (MM) and end with the first user process (INIT).
X *
X * Initially the device configuration is nonexistant.
X */
Xkstack(procinfo, sps)
XAOUT *procinfo;
Xint *sps;
X{	static struct proc proc[4], 	/* Kernel, MM, FS, INIT */
X		*pproc[] = { proc, proc+1, proc+2, proc+3, 0 };
X	static int *kenv[] = { 0, 0 };
X
X	struct proc *p;
X	int *s, sp;
X
X	/* Build a process table for the kernel */
X	p = proc; s = sps; 
X
X	kproc(p++, s++, procinfo[0]);	/* kernel*/
X	kproc(p++, s++, procinfo[1]);	/* MM	*/
X	kproc(p++, s++, procinfo[2]);	/* FS	*/
X	kproc(p++, s++, procinfo[3]);	/* init	*/
X
X	dmpproc(proc);
X	sp = procstack(pproc, sizeof(struct proc), kenv, sizeof(int), procinfo[0]);
X	return(sp);	/* initial stack */
X}
X
X/*
X *	Set Up Kernel Process Table
X */
Xkproc(p, s, procinfo)
Xstruct proc *p;
Xint *s;
XAOUT procinfo;
X{	p->p_map[T].mem_vir  = 0;
X	p->p_map[T].mem_phys = (int) procinfo->a_tbase;
X	p->p_map[T].mem_len  = clicks(procinfo->a_trsize);
X
X	p->p_map[D].mem_vir  = (procinfo->a_trsize == 0) ?
X				 (int) procinfo->a_trsize : 0;
X	p->p_map[D].mem_phys = (int) procinfo->a_dbase;
X	p->p_map[D].mem_len  = clicks(procinfo->a_total);
X
X	p->p_map[S].mem_vir  = p->p_map[D].mem_vir + clicks(procinfo->a_total);
X	p->p_map[S].mem_phys = p->p_map[D].mem_phys +clicks(procinfo->a_total);
X	p->p_map[S].mem_len  = 0;
X
X	p->p_sp = *s;
X}
X
Xdmpproc(proc)
Xstruct proc *proc;
X{
X  register struct proc *rp;
X  vir_bytes base, limit, first, last;
X  phys_bytes ltmp;
X
X  printf("\nPROC   -----TEXT-----  -----DATA-----  ----STACK-----  BASE SIZE SP\r\n");
X  for (rp = proc; rp < proc+4; rp++)  {
X	if (rp->p_flags & P_SLOT_FREE) continue;
X	first = rp->p_map[T].mem_phys;
X	last = rp->p_map[S].mem_phys + rp->p_map[S].mem_len;
X	ltmp = ((long) first << 4) + 512L;
X	base = (vir_bytes) (ltmp/1024L);
X	ltmp = (((long) (last-first) << 4) + 512L);
X	limit = (vir_bytes) (ltmp/1024L);
X	printf("%4d", rp - proc);
X
X	printf(" %4x %4x %4x  %4x %4x %4x  %4x %4x %4x  %3dK %3dK %4x\r\n", 
X	    rp->p_map[T].mem_vir, rp->p_map[T].mem_phys, rp->p_map[T].mem_len,
X	    rp->p_map[D].mem_vir, rp->p_map[D].mem_phys, rp->p_map[D].mem_len,
X	    rp->p_map[S].mem_vir, rp->p_map[S].mem_phys, rp->p_map[S].mem_len,
X	    base, limit, rp->p_sp);
X  }
X}
X
X/*
X *	Memory Manager Stack
X *
X *  The memory manager's stack consists of only the memory size of the system.
X */
Xmmstack(mmproc, sp)
XAOUT mmproc;
Xint *sp;
X{	static int mminfo[] = { 0x55AA },
X	    *mmptr[] = { mminfo, 0 };
X	static int *mmenv[] = { 0 };
X
X#ifdef DEBUG
X	printf("MM ");
X#endif
X	*sp = procstack(mmptr, sizeof(int), mmenv, sizeof(int), mmproc);
X}
X
X/*
X *	File System Stack
X *
X *  The File System's stack consists of five integers in "argv":
X *	[0] Device to load ram disk image (0 if root doesn't need loading)
X *	[1] Device to mount as root
X *	[2] Size of Local RAM disk
X *	[3] Size of Extended Memory (AT) RAM disk
X *	[4] Size of EMS RAM disk
X */
X#define RAM_IMAGE (dev_nr)0x303	/* major-minor dev where root image is kept */
Xfsstack(fsproc, sp)
XAOUT fsproc;
Xint *sp;
X{	static int fsinfo[] = { 0, RAM_IMAGE, 0x1234, 0x5678, 0x9abc, 0 },
X	    *fsptr[] = { fsinfo, fsinfo+1, fsinfo+2, fsinfo+3, fsinfo+4, 0 };
X	static int *fsenv[] = { 0, 0 };
X
X#ifdef DEBUG
X	printf("FS ");
X#endif
X	*sp=procstack(fsptr, sizeof(int), fsenv, sizeof(int), fsproc);
X#ifdef DEBUG
X  printf("FS: 0x%x 0x%x 0x%x 0x%x 0x%x\n", *fsptr[0], *fsptr[1], *fsptr[2], *fsptr[3], *fsptr[4]);
X#endif
X}
SHAR_EOF
if test 7832 -ne "`wc -c < 'b2b/stack.c'`"
then
    echo shar: error transmitting "'b2b/stack.c'" '(should have been 7832 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b2b/standalone.c'" '(540 characters)'
if test -f 'b2b/standalone.c'
then
    echo shar: will not over-write existing file "'b2b/standalone.c'"
else
sed 's/^X//' << \SHAR_EOF > 'b2b/standalone.c'
X/*
X	Stand-Alone (No OS) Support Routines
X */
X
Xprintf(fmt,args)
Xchar *fmt;
Xint args;
X{
X	_doprintf(0, fmt, &args);
X}
X
X/* Print the given character. */
Xputc(c)
Xchar c;
X{
X	fputc(c,0);
X}
X
Xfputc(c,f)
Xchar c;
Xint f;
X{
X	if (c == '\n')
X		_putc('\r');
X	_putc(c);
X}
X
X/*putchar(c)	{ putc(c); }*/
X
X/*write(d, buf, cnt)
Xint d;
Xchar *buf;
Xint cnt;
X{
X	fputc('!',0);
X	while(--cnt)	fputc(*buf++);
X}*/
X
X/* Get a character from the user and echo it. */
Xfgetc(f)
Xint f;
X{
X	register c;
X
X	if ((c = _getc() & 0xFF) == '\r')
X		c = '\n';
X	fputc(c,0);
X	return(c);
X}
X
SHAR_EOF
if test 540 -ne "`wc -c < 'b2b/standalone.c'`"
then
    echo shar: error transmitting "'b2b/standalone.c'" '(should have been 540 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'b2b/type.h'" '(140 characters)'
if test -f 'b2b/type.h'
then
    echo shar: will not over-write existing file "'b2b/type.h'"
else
sed 's/^X//' << \SHAR_EOF > 'b2b/type.h'
X/*
X	Types for the Stage 2 Bootstrapper
X
X*/
X
Xtypedef struct inode *INODE;
Xtypedef struct super_block *SUPERBLOCK;
Xtypedef struct exec *AOUT;
SHAR_EOF
if test 140 -ne "`wc -c < 'b2b/type.h'`"
then
    echo shar: error transmitting "'b2b/type.h'" '(should have been 140 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'kernel/main.c.diff'" '(5503 characters)'
if test -f 'kernel/main.c.diff'
then
    echo shar: will not over-write existing file "'kernel/main.c.diff'"
else
sed 's/^X//' << \SHAR_EOF > 'kernel/main.c.diff'
X*** /usr/src/minix/kernel/main.c	Fri Dec  2 00:01:47 1988
X--- main.c	Fri Apr 21 11:17:30 1989
X***************
X*** 47,65 ****
X  /*===========================================================================*
X   *                                   main                                    * 
X   *===========================================================================*/
X! PUBLIC main()
X  {
X  /* Start the ball rolling. */
X  
X    register struct proc *rp;
X    register int t;
X    int i, old_state;
X!   vir_clicks size;
X!   phys_clicks base_click, mm_base, previous_base;
X    phys_bytes phys_b;
X    int	stack_size;
X    int * ktsb;			/* kernel task stack base */
X-   extern unsigned sizes[8];	/* table filled in by build */
X    extern int port_65, ega, color, get_chrome();
X    extern int s_call(), disk_int(), tty_int(), clock_int(), disk_int();
X    extern int wini_int(), lpr_int(), trp(), rs232_int(), secondary_int();
X--- 47,65 ----
X  /*===========================================================================*
X   *                                   main                                    * 
X   *===========================================================================*/
X! PUBLIC main(argc, argv)
X! int argc;
X! struct proc **argv;
X  {
X  /* Start the ball rolling. */
X  
X    register struct proc *rp;
X    register int t;
X    int i, old_state;
X!   phys_clicks base_click;
X    phys_bytes phys_b;
X    int	stack_size;
X    int * ktsb;			/* kernel task stack base */
X    extern int port_65, ega, color, get_chrome();
X    extern int s_call(), disk_int(), tty_int(), clock_int(), disk_int();
X    extern int wini_int(), lpr_int(), trp(), rs232_int(), secondary_int();
X***************
X*** 84,131 ****
X  
X    old_state = lock();			/* we can't handle interrupts yet */
X    base_click = BASE >> CLICK_SHIFT;
X-   size = sizes[0] + sizes[1];	/* kernel text + data size in clicks */
X-   mm_base = base_click + size;	/* place where MM starts (in clicks) */
X  
X    for (ktsb = t_stack, t = -NR_TASKS, rp = &proc[0];
X  		rp <= &proc[NR_TASKS+LOW_USER];  rp++, t++) {
X! 	for (i = 0; i < NR_REGS; i++) rp->p_reg[i] = 0100 * i;	/* debugging */
X! 	if (t < 0) {
X  		stack_size = tasktab[t+NR_TASKS].stksize;
X  		ktsb += stack_size / sizeof (int);
X  		rp->p_sp = ktsb;
X  		rp->p_splimit = ktsb - (stack_size - SAFETY) / sizeof(int);
X! 	} else {
X! 		rp->p_sp = INIT_SP;
X! 		rp->p_splimit = rp->p_sp;
X! 	}
X  	rp->p_pcpsw.pc = tasktab[t + NR_TASKS].initial_pc;
X  	if (rp->p_pcpsw.pc != 0 || t >= 0) ready(rp);
X  	rp->p_pcpsw.psw = INIT_PSW;
X  	rp->p_flags = 0;
X  
X- 	/* Set up memory map for tasks and MM, FS, INIT. */
X- 	if (t < 0) {
X- 		/* I/O tasks. */
X- 		rp->p_map[T].mem_len  = VERY_BIG; 
X- 		rp->p_map[T].mem_phys = base_click;
X- 		rp->p_map[D].mem_len  = VERY_BIG; 
X- 		rp->p_map[D].mem_phys = base_click + sizes[0];
X- 		rp->p_map[S].mem_len  = VERY_BIG; 
X- 		rp->p_map[S].mem_phys = base_click + sizes[0] + sizes[1];
X- 		rp->p_map[S].mem_vir = sizes[0] + sizes[1];
X- 	} else {
X- 		/* MM, FS, and INIT. */
X- 		previous_base = proc[NR_TASKS + t - 1].p_map[S].mem_phys;
X- 		rp->p_map[T].mem_len  = sizes[2*t + 2];
X- 		rp->p_map[T].mem_phys = (t == 0 ? mm_base : previous_base);
X- 		rp->p_map[D].mem_len  = sizes[2*t + 3];
X- 		rp->p_map[D].mem_phys = rp->p_map[T].mem_phys + sizes[2*t + 2];
X- 		rp->p_map[S].mem_vir  = sizes[2*t + 3];
X- 		rp->p_map[S].mem_phys = rp->p_map[D].mem_phys + sizes[2*t + 3];
X- 	}
X- 
X- 
X  #ifdef i8088
X  	rp->p_reg[CS_REG] = rp->p_map[T].mem_phys;
X  	rp->p_reg[DS_REG] = rp->p_map[D].mem_phys;
X--- 84,111 ----
X  
X    old_state = lock();			/* we can't handle interrupts yet */
X    base_click = BASE >> CLICK_SHIFT;
X  
X    for (ktsb = t_stack, t = -NR_TASKS, rp = &proc[0];
X  		rp <= &proc[NR_TASKS+LOW_USER];  rp++, t++) {
X! 	/* Set up memory map for tasks and MM, FS, INIT. */
X! 	if (t < 0) {		/* I/O tasks. */
X! 		copy(rp, argv[0], sizeof(struct proc));
X  		stack_size = tasktab[t+NR_TASKS].stksize;
X  		ktsb += stack_size / sizeof (int);
X  		rp->p_sp = ktsb;
X  		rp->p_splimit = ktsb - (stack_size - SAFETY) / sizeof(int);
X! 	} else {		/* MM, FS, and INIT. */
X! 		copy(rp, argv[t+1], sizeof(struct proc));
X! /*		rp->p_sp = INIT_SP;*/
X! 		rp->p_splimit = rp->p_sp;
X! 	}
X! 
X! 	for (i = 0; i < NR_REGS; i++) rp->p_reg[i] = 0100 * i;	/* debugging */
X  	rp->p_pcpsw.pc = tasktab[t + NR_TASKS].initial_pc;
X  	if (rp->p_pcpsw.pc != 0 || t >= 0) ready(rp);
X  	rp->p_pcpsw.psw = INIT_PSW;
X  	rp->p_flags = 0;
X  
X  #ifdef i8088
X  	rp->p_reg[CS_REG] = rp->p_map[T].mem_phys;
X  	rp->p_reg[DS_REG] = rp->p_map[D].mem_phys;
X***************
X*** 275,281 ****
X    unsigned vec[2];
X    unsigned u;
X    phys_bytes phys_b;
X-   extern unsigned sizes[8];
X  
X    /* Build the vector in the array 'vec'. */
X    vec[0] = (unsigned) addr;
X--- 255,260 ----
X***************
X*** 283,289 ****
X    u = (unsigned) vec;
X  
X    /* Copy the vector into place. */
X!   phys_b = ( (phys_bytes) base_click + (phys_bytes) sizes[0]) << CLICK_SHIFT;
X    phys_b += u;
X    phys_copy(phys_b, (phys_bytes) vec_nr*4, (phys_bytes) 4);
X  }
X--- 262,268 ----
X    u = (unsigned) vec;
X  
X    /* Copy the vector into place. */
X!   phys_b = proc[NR_TASKS + HARDWARE].p_map[D].mem_phys << CLICK_SHIFT;
X    phys_b += u;
X    phys_copy(phys_b, (phys_bytes) vec_nr*4, (phys_bytes) 4);
X  }
X***************
X*** 300,302 ****
X--- 279,292 ----
X  PUBLIC dp8390_int(){}			/* Ethernet interrupt */
X  #endif
X  
X+ /*
X+ 	Intra-Segment Copy
X+ 
X+     copy(destination, source, length)
X+ */
X+ copy(d,s,l)
X+ char *d, *s;
X+ int l;
X+ {
X+ 	while(--l)	*d++ = *s++;
X+ }
SHAR_EOF
if test 5503 -ne "`wc -c < 'kernel/main.c.diff'`"
then
    echo shar: error transmitting "'kernel/main.c.diff'" '(should have been 5503 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'fs/cache.c.diff'" '(662 characters)'
if test -f 'fs/cache.c.diff'
then
    echo shar: will not over-write existing file "'fs/cache.c.diff'"
else
sed 's/^X//' << \SHAR_EOF > 'fs/cache.c.diff'
X*** /usr/src/minix/fs/cache.c	Sat Aug 13 14:20:45 1988
X--- cache.c	Tue Apr 18 11:31:22 1989
X***************
X*** 210,216 ****
X  	err_code = ENOSPC;
X  	major = (int) (sp->s_dev >> MAJOR) & BYTE;
X  	minor = (int) (sp->s_dev >> MINOR) & BYTE;
X! 	if (sp->s_dev == ROOT_DEV)
X  		printf("No space on root device (RAM disk)\n");
X  	else
X  		printf("No space on device %d/%d\n", major, minor);
X--- 210,216 ----
X  	err_code = ENOSPC;
X  	major = (int) (sp->s_dev >> MAJOR) & BYTE;
X  	minor = (int) (sp->s_dev >> MINOR) & BYTE;
X! 	if (sp->s_dev == root_dev)
X  		printf("No space on root device (RAM disk)\n");
X  	else
X  		printf("No space on device %d/%d\n", major, minor);
SHAR_EOF
if test 662 -ne "`wc -c < 'fs/cache.c.diff'`"
then
    echo shar: error transmitting "'fs/cache.c.diff'" '(should have been 662 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0