[net.micro.mac] INIT Resources

vishniac@wanginst.UUCP (Ephraim Vishniac) (05/29/85)

Last night, Stew Rubenstein from Harvard was kind enough to tell me
what he knows about INIT resources.  (IM is silent on the subject.)
In case anybody else is interested, here's what he told me:

During system startup, each INIT resource is loaded and branched to 
via a JSR instruction.  So, an INIT resource is just a piece of code
that ends in RTS and does something useful at system startup.

There are a couple of handy techniques to use with INIT code.
First, if part of the INIT is going to be permanently resident
(e.g., if the INIT installs a system patch), the code to install
the patch is placed at the *end*, with a branch to it at the beginning.
After it's done the installation work, the INIT resource can call the
resource manager to reduce its own size.  So, only the permanently
resident code continues to occupy heap space.

In a similar vein, INIT's that don't want to leave anything behind
can be set up as unpurgeable resources (to protect themselves during
execution), then set themselves purgeable just before exiting.

BTW, RMaker does not have INIT as a native type.  The MDS documentation
doesn't mention INIT, but the Aztec C documentation does.  They explain
that since INIT is much like PROC, just say "TYPE INIT = PROC" (followed
by the info that a PROC description would normally have).

Now for a question: the Aztec C documentation also says that INIT resources
cannot have overlays (no surprise) nor can they have *any initialized data*.
From a brief experiment, it appears that this precludes any use of strings.
If so, is Aztec C essentially useless for constructing INIT's?  How can I
open a file, named resource, or driver?

-- 
Ephraim Vishniac
  [apollo, bbncca, cadmus, decvax, harvard, linus, masscomp]!wanginst!vishniac
  vishniac%Wang-Inst@Csnet-Relay

hamachi@KIM.BERKELEY.EDU (Gordon Hamachi) (04/11/86)

Can someone explain INIT resources, or say where they are documented?  I
have not been able to find out anything from Inside Macintosh, except that
there is a resource type "INIT".  So, how come people are posting INIT
resource installers?  How do they find out how to write them?

Using the resource editor, I notice that my system 3.1.1 has the following
init resources:

#35, with 370 bytes
#13, with 258 bytes
#3, named "Q", with 202 bytes
#2, with 768 bytes
#1, with 100 bytes
#0, with 646 bytes

What do these do?  Is the number at all significant?

--Gordon Hamachi

oster@ucblapis.berkeley.edu (David Phillip Oster) (04/11/86)

Since INITs, like DRVRs, get renumbered if they collide with something
that is already there, PLEASE give your INITs mnemonic names so that
people using ResEdit can tell they're yours.

I like to put version info in mine: for example: "Name Key 1.0", so that my
install software can easily check to see if you've got the correct version
of my INIT resource.  The mac changes, your first released version is
never your last, INIT resources have to be compatible with EVERYBODY
else's code.  Be ready to upgrade your customers!

(On Menu Clock V 2.0, the install program sometimes reboots the Mac+.
(It only reboots it when people other than me run the program. :-) )
version 2.1 is ready now, and fixes the problem.)

berry@tolerant.UUCP (David W. Berry) (04/15/86)

An INIT resource is a piece of code which gets executed automatically
at system boot time.  I believe they are executed in numerical order
just before the startup application is executed.  They are executable
code with an entry point at offset 0.

An INIT installer is an application which copies an INIT resource into
the system file, presumably after checking for conflicts with existing
resources.

As a sample, the following is an INIT resource to patch a problem I
was having with programs passing NULL to EnableItem and DisableItem:


(-- Cut Here for Usable sample.  Assemble with MDS Asm )
		include		mactraps.d
		include		sysequ.d
	
		resource	'INIT' 4 '{Enable,Disable}Item(NIL)'
		
start:
		; save registers
		movem.l		d0-d1/d7/a0-a4,-(sp)
		
		; fill in all the old address vectors
		lea		patch_table,a4
		lea		start_p,a3
		move		4(a4),d7
	@2:
		move		0(a4),d0
		_GetTrapAddress
		move.l		a0,0(a3,d7.w)
		add.l		#6,a4
		move		4(a4),d7
		bne.s		@2
	
		; allocate the patch block and copy the patch into it
		move.l		#end_p-start_p,d0
		_NewPtr,SYS
		move.l		a0,a1
		move.l		#end_p-start_p,d0
		lea		start_p,a0
		_BlockMove
		
		; set the new trap address to point into the patch block
		lea		patch_table,a4
		move.l		a1,a3
		move		2(a4),d7
	@4:
		lea		0(a3,d7.w),a0
		move		(a4),d0
		_SetTrapAddress
		add.l		#6,a4
		move		2(a4),d7
		bne.s		@4
		
		; restore registers and return
		movem.l		(sp)+,d0-d1/d7/a0-a4
		rts
		
patch_table:	dc.w		$a939
		dc.w		patch1-start_p
		dc.w		trap1-start_p
		dc.w		$a93a
		dc.w		patch2-start_p
		dc.w		trap2-start_p
		dc.w		0,0,0
		
start_p:

patch1:
		move.l		$6(a7),d0
		bne.s		@1
		move.l		(a7)+,a0
		add.l		#6,a7
		jmp		(a0)
@1:
		move.l		trap1(pc),-(a7)
		rts
		
trap1:		dc.l		0

patch2:
		move.l		$6(a7),d0
		bne.s		@1
		move.l		(a7)+,a0
		add.l		#6,a7
		jmp		(a0)
@1:
		move.l		trap2(pc),-(a7)
		rts
		
trap2:		dc.l		0

end_p:

(-- End of Sample )

Hope this answers your questions.
-- 

	David W. Berry
	dwb@well.UUCP
	Delphi: dwb
	{ucbvax,pyramid,idsvax,bene,oliveb}!tolerant!berry

	I'm only here for the beer.

ephraim@wang.UUCP (pri=8 Ephraim Vishniac x76659 ms1459) (04/16/86)

Gordon Hamachi asks:
> Can someone explain INIT resources, or say where they are documented?  I
> have not been able to find out anything from Inside Macintosh, except that
> there is a resource type "INIT".  So, how come people are posting INIT
> resource installers?  How do they find out how to write them?

I found out how to write them by calling Stew Rubinstein at Harvard.
He told me that my INITs should start with a BRAnch to the real code,
and that _SizeRsrc was often used to cut back the resource size after
the one-time-only code in them had run.  INITs are loaded, locked, and
invoked with a JSR from the system code.  For reasons I can't imagine,
the system patches two NOPs (4E714E71) over the start of your INIT after
it returns.

INITs are useful for doing anything you want done at system startup, after
PTCH installation.  The INIT number determines the order in which the INITs
are executed.

Detaching or releasing an INIT is a bit tricky.  I got information on how
to do this from Evan Solley of Infosphere, who evidently disassembled the
system code that invokes INITs.  I don't have the details handy, but the
general idea involves knowing that the system leaves a handle to your INIT
in D7 (?), and faking it out when you release your INIT and invalidate the
handle.

Apple is now providing an INIT (#31) which invokes INITs from other files
so that they don't have to live in the system file.  See the December 
supplement for details.

Ephraim Vishniac
decvax!wanginst!wang!ephraim