[comp.os.os9] more linker problems

edstrom@elmer.hsc.ucalgary.ca (John Edstrom) (01/30/91)

 
Hello, all.  Its me again.  Sorry to bother everybody with this but
I have been having a devil of a time with my device driver and can't
find any solace in my manuals.

The good news is that I think I found the source of my bus error problems.
Now all I need to do is to find a way around it.

After reading the manual several times more closely I learned that the
IOMan and the device driver share the same static storage area.  The
problem comes from the fact that they don't know what each other are
doing.

for example, if I use the device storage area to save some data like an
input buffer (a la Dibble) it would look like this:
 
	vsect
inpntr	ds.l	1   * points to current position in buffer
inbuf	ds.b	80  * body of buffer
	ends

and, since the device routines are called with a2 pointing to static storage, 
they would be used as:

	lea.l 	inbuf(a2),a0  * calculate buffer address
	move.l	a0,inptr(a2)  * initialize data pointer to buffer head

The problem is that IOMan uses the same data section but uses different
offsets which are defined in sys.l.  Thus, V_PORT is defined as $0 and
so is inpntr.  So when the IOMan saves the device port address it overwrites
my inpntr.  I could also have written the above code as:

	lea.l 	inbuf(a2),a0
	move.l	a0,V_PORT(a2)

The reason I was getting spurious bus errors from my driver is that
the IOMan was either using my data as flags, addresses or something else
inappropriate or else my code was interpreting IOMan's data as my own.

So, my question is: how do I get my linker to respect IOMan's data sections?
I would just declare a heap of junk bytes at the top of my vsect if I could
find out how much space the IOMan and SCF filemanager needs to mangle.  Is
that information available anywhere?

I re-read the linker sention of the manual several times and don't see any
options that seem to apply either.  I get no unresolved variables so I think
I'm linking to all of the necessary libraries in the proper order. 

John Edstrom | edstrom@elmer.hsc.ucalgary.ca


--
 RM 2104, HSc Building,  Div. Neuroscience
 U. Calgary School of Medicine,  3330 Hospital Drive NW
 Calgary, Alberta       T2N 3Y4
 (403) 220 4493  (wk)

reising@colix (Josef Reisinger) (01/31/91)

|>
|> [...]
|>
|>I re-read the linker sention of the manual several times and don't see any
|>options that seem to apply either.  I get no unresolved variables so I think
|>I'm linking to all of the necessary libraries in the proper order. 
|>
|>John Edstrom | edstrom@elmer.hsc.ucalgary.ca
|>

 I think the information you seek is _not_ in the linker's manual, but
 you may find it in the systems technical manual.
 In your defs-directory is a file, which defines a constant V_USER
 (I think it's defs/io.a, but...). This is the amount of space used by IOMan.
  all you have to do is:

	use ....../defs/io.a (?)
	.	
	.	
	.	
 	vsect
	ds.b	V_USER
inptr	ds.l	1
inbuf   ds.b	80
	.
	ends		.	
	.	
	.	
        move.l	inptr(a2),...


 Hope this helps.
 /jr
--
######################################################################
    Josef Reisinger    (Software Quality never goes out of style...)
    Digital Equipment Corporation    
    D-5000 Koeln
    Stolberger Strasse

reisinger@col01.enet.dec.com                   ! VAX/VMS via USA
...unido!decum!col01.enet!reisinger            ! VAX/VMS in EUROPE

reising@colix.enet.dec.com	               ! VAX/Ultrix via USA
...unido!decum!colix.enet!reising              ! VAX/Ultrix in EUROPE
######################################################################

meindert@inducom.UUCP (Meindert Kuipers) (01/31/91)

From article <1991Jan29.114204.1751@yogi.fhhosp.ab.ca>, by edstrom@elmer.hsc.ucalgary.ca (John Edstrom):
> 
> 
> After reading the manual several times more closely I learned that the
> IOMan and the device driver share the same static storage area.  The
> problem comes from the fact that they don't know what each other are
> doing.

Not really, IOMan uses the driver's static storage for passing parameters
etc.

> 
> for example, if I use the device storage area to save some data like an
> input buffer (a la Dibble) it would look like this:
>  
> 	vsect
> inpntr	ds.l	1   * points to current position in buffer
> inbuf	ds.b	80  * body of buffer
> 	ends
> 
> The problem is that IOMan uses the same data section but uses different
> offsets which are defined in sys.l.  Thus, V_PORT is defined as $0 and
> so is inpntr.  So when the IOMan saves the device port address it overwrites
> my inpntr.  I could also have written the above code as:
> 
> So, my question is: how do I get my linker to respect IOMan's data sections?
> I would just declare a heap of junk bytes at the top of my vsect if I could
> find out how much space the IOMan and SCF filemanager needs to mangle.  Is
> that information available anywhere?

The linker collects all the vsects in all ROF's, and links them together
with the first vsect starting at offset zero. in your /dd/LIB directory
are several file like scfstat.l and drvs2.l etc. These contains vsects
with definitions of the driver static storage. One of these libs must be
the first on a linker command line like:

	l68 /dd/LIB/scfstat.l sc_driver.r -l=/dd/sys.l -O=sc_driver

for a standard SCF device driver. With the RDUMP command and its options
you can get a listing of the contents of the library files.
If your driver is for a custom filemanager things are a little tricky,
because you have to create this library file yourself. In the /dd/DEFS
directory (print all the files out NOW, you will learn a lot about OS-9)
you can find a file like scfstat.a or scfstat.d which is basically the
source for scfstat.l (or scfstat.r, the names sometimes differ). This source
refers to many other files, like io.a.

Microware sells a (non-supported) free driver pack for a small amount of
dollars. I think the listings of the makefiles alone are worth it and it
could have prevented a lot of your time. There is also a lot of driver
source code included for both SCF and RBF.

Good luck.

-------------------------------------------------------------------------------
  +-----+                  Inducom Systems B.V.
  |     <                  Raadhuislaan 27   NL - 5341 GL  Oss, Netherlands
  |  o  |                  P.O. Box 627      NL - 5340 AP  Oss, Netherlands
  |  INDUCOM SYSTEMS       Phone: (31)-(0)4120-41922
  +-----+                  Fax:   (31)-(0)4120-22640
  Specialists in OS-9, VMEbus and G-64

  Meindert Kuipers, Inducom Systems B.V.
  UUCP: meindert@inducom.UUCP        ...!uunet!mcsun!hp4nl!inducom!meindert
  -- Coming soon to a VMEbus system near you: VMEtro BusBusters --
-------------------------------------------------------------------------------

kdarling@hobbes.ncsu.edu (Kevin Darling) (02/01/91)

edstrom@elmer.hsc.ucalgary.ca (John Edstrom) writes:

> So, my question is: how do I get my linker to respect IOMan's data sections?

First, my apologies... about a week ago it suddenly struck me what
your problem was, but I forgot to send you email (and kind of hoped that
Bruce Isted had fixed you up via voice).  Anyway...

Yes, the first part of device static storage always has the same variables
(used by kernel, manager and driver), and these are defined in "iodev.a".
This section ends at V_USER, which is a little bit misleading because it
actual denotes the beginning of File Manager storage.

The second section is file manager specific, and for SCF it's "scfdev.a".
It starts at V_USER and ends at V_SCF, which is the total amount needed
to be reserved for all SCF devices.  After all those come your own driver
specific variables.

So look in DEFS at "scfstat.a", which uses both "iodev.a" and "scfdev.a".
And finally, that file has been precompiled into the LIB as "scfstat.l".

To compile your driver then, you could use:

  "l68 /dd/lib/scfstat.l  rels/mydriver.r  -O=objs/mydriver"

Note that "scfstat.l" must come _first_, of course, so that the vsect's
defined there will end up before your own variables.

(The SCF driver static storage is $54 bytes long, btw) - kevin
 <kdarling@catt.ncsu.edu>  or <76703.4227@compuserve.com>

PS: You should be using V_PORT(a2) to get the address of the ram area,
to be address-independent.  Keep asking Q's!

davely@mcrware.UUCP (Dave Lyons) (02/01/91)

In article <1991Jan29.114204.1751@yogi.fhhosp.ab.ca> edstrom@elmer.hsc.ucalgary.ca (John Edstrom) writes:

>So, my question is: how do I get my linker to respect IOMan's data sections?
>I would just declare a heap of junk bytes at the top of my vsect if I could
>find out how much space the IOMan and SCF filemanager needs to mangle.  Is
>that information available anywhere?
>
>I re-read the linker sention of the manual several times and don't see any
>options that seem to apply either.  I get no unresolved variables so I think
>I'm linking to all of the necessary libraries in the proper order. 

After looking at our makefile's to refresh my memory, I think the solution 
is this:  link the file scfstat.l (found in the LIB directory on distribution
media) before your driver's .r file, i.e., a command line something like this

	l68 /dd/LIB/scfstat.l RELS/yourdriver.r -l=/dd/LIB/sys.l -O=OBJS/yourdriver

The file sys.l has a vsect which has ds's for all the storage needed by 
IOMan and the SCF file manager.  You can also use the technique I saw
described in another posting which would be to do something like this:

	* declare driver static storage
	*
			vsect
			ds.b	V_SCF
	MyStuff	ds.l	V_MyVar

Note that you need to use the value V_SCF here instead of V_USER.  V_USER
defines the beginning of the file manager static storage area and so would
not be enough to get you clear of the memory used by the file manager for
things like V_QUIT, V_PCHR and the like.

I hope this helps solves your problems.

Davel

-- 
|Dave Lyons - uunet!mcrware!davely    | Just like a V8 under the hood       |
|-------------------------------------|     of a car made of nails and wood |
| The opinions of the party of the    | Your big heart's gonna break        |
| first part shall not be taken as... |     your little body                |

kdarling@hobbes.ncsu.edu (Kevin Darling) (02/01/91)

In another message I wrote:

>PS: You should be using V_PORT(a2) to get the address of the ram area,

Ooops. Obviously I was thinking of 6809 OS9, as 68K OS9 also passes the
port address in a register.  Got myself mixed up there.  - kev