Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!bloom-beacon!apple!oliveb!amiga!cbmvax!jesup From: jesup@cbmvax.UUCP (Randell Jesup) Newsgroups: comp.sys.amiga.tech Subject: Re: Unix V7 functionality under (or along with) AmigaDOS? (*LONG*) Keywords: Unix V7 Minix AmigaDOS shells ... CATS? Randell?? :-) Message-ID: <6185@cbmvax.UUCP> Date: 9 Mar 89 03:26:54 GMT References: <6157@cbmvax.UUCP> Reply-To: jesup@cbmvax.UUCP (Randell Jesup) Distribution: comp Organization: Commodore Technology, West Chester, PA Lines: 229 In article shadow@pawl.rpi.edu writes: >In article <6157@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes: >>In article shadow@pawl.rpi.edu writes: >>>So Exit() only ever releases resources if pr_ReturnAddr points to some >>>such cleanup routine? What does CreateProc() normally initialize >>>pr_ReturnAddr to, then? Exactly such a routine? >> >> It sets up pr_returnaddr so you'll end up in the same place as if >>you RTS'ed from your program. > >Which is? (Cleanup code for CreateProc, or something else?) Whatever called the program (and should cause any needed cleanup to be done). For something started by CreateProc, code to cleanup and remove the process. For something started by a shell, code to cleanup and return to the command loop. For things Run from a shell, similar to CreateProc (with the addition of cleanup code for CLI structure). >>>I don't understand what the pr_GlobVec field is used for. Will >>>non-BCPL programs ever use it? What do I need to initialize it to? >> >> Non-BCPL shouldn't be using it. > >And if I wanted to (gasp!) support BCPL programs? >(yeah, yeah... use Execute()...) pr_GlobVec can normally be filled in from the dos library structure. Treat it as a magic cookie. >>>pr_CLI will be set to zero. >> >> CLI-only programs may expect it. > >Hmm. I'd like to be able to have non-CLI programs; different startup >code, no CLI structures tied to it, etc. The CLI is a shell. I'd >rather not design a shell which depends on another one. Therefore I'd >like to be able to break from the CLI, yet support programs which >depend on it. Which brings up the question - Is there any feasible >(and practical) way to determine if a program depends on the CLI? >(Aside from trial and error; I want the shell to determine it, if >possible.) No. I'd advise using an extended CLI structure if you want any sort of compatibility. This may break in 1.4, but it will at least work (please note in your docs that this may well break in 1.4 in that case). >One way it could be done would be have another load-file format, and >convert the binaries to that format. (maybe a.out-like format) >However, I'm not too keen on the idea of going so far as to write a >linker and a loader. (Or a converter and loader.) It just seems to >be going too far. Yup. >So, is there any legitimate way to identify the binaries as "I don't >need a CLI environment"? Essentially, is there a way to tag the >binaries with a "magic number"? Such that it won't interfere with >LoadSeg() or the code itself? Can you set a hunk name on the >hunk_header hunk? > >(The answer looks like it should be "yes", but I don't have any blink >docs onhand; only this AmigaDOS manual.) No. I advise against modifying binaries. Use one of the user protection bits. >>>What's the best way to set pr_ReturnAddr? Set it to the PC plus a >>>constant? JSR to a piece of code which stores the return address in >>>pr_ReturnAddr and JMP's to the code? Hmm. Silly question. The >>>latter, of course. >> >> Look how BCPL sets it up. > >Where am I to look? How does BCPL set it up? Break out wack or metascope or some such, and look at some running processes (write a test program). Also, reread your tech ref manual, then reread it again a few more times. :-( >>>My added structure would then follow. Do you forsee any compatibility >>>problems caused by a setup like this? >> >> In 1.4, quite possibly, but for 1.3 (modulo above) it might be ok. >>Having it run BCPL programs is harder. > >Hmm. Any suggestion how to keep things compatible through V1.4? >(besides "don't rock the boat..." :-) Maintain current CLI/Process structures, at least as a subset. >> Tannenbaum has two students doing a port. > >Nice to hear. I wouldn't relish the task. At least, replacing the >REAL low-level stuff, like Exec and the device handlers, I really >don't feel like messing with. Rewriting the file system is as >low-level as I want to get at this point, on such a scale. (And >that's no small project either.) That's why I suggested a long time ago that Amiga-Minix be implemented on top of Exec/Graphics/Intuition/etc. This also means you get your expansion hardware to work without having to hack the kernal for your specific configuration, and plead for driver source from the HD makers. >> 1.4 should have FFS in ROM (and available for floppies). > >I'm not sure FFS is all it could be, but it is clearly a step in the >right direction. Who ever said FFS was static? :-) >> Exec? In C? That's a nasty thought. Exec is in ASM, of course, for >>speed. > >Not all of it in C, but I imagine most of it could be written in C >without too much of a performance penalty, and it would likely gain >much maintainability. But, I can see keeping Exec in ASM. But please >ditch the BCPL and use either C or Assembly for the file system. And >also try to work in links in the file system. (hard links at the very >least, preferably symbolic links as well.) Almost everything in Exec in performance critical. FFS is in ASM already. >> VERY hard to do without an MMU, since you MUST duplicate the stack >>and data, and those contain absolute pointers. There is no way to know >>where these pointers are. The ST/Amiga-Minix gets around this by copying >>the data/stack of the two processes to save areas, and "swapping" in the >>data/stack to the original position whenever one needs to run. Luckily, >>almost all fork() calls are followed almost immediately by exec(), so the >>overhead isn't too horrible. > >Oh, icky. My, I had overlooked that aspect. *sigh* It's a kludge, >but I guess it'll work. Can the tc_Switch and tc_Launch fields in the >task structure be used to handle this? Or are they already used or >not usable as such? yes, but respect any values already there (grab the old value, stuff yours, and after you're called call the old value). An example of stuff that might use this would be saving '881 registers. >> there is no way to dup a filehandle. > >It would be duping handles to a table entry holding the file handle. >(along with the count.) Fine, but watch out: if two BCPL programs try to use the same filehandle, fireworks will erupt. >> I think you're working at too low a level. There are better ways to >>implement the functionality you want without making the internal semantics the >>same as in Unix. Define your functionality first, then figure out what you >>need to get that. > >Well, I'm afraid part of the functionality I want is that which fork() >and exec() provide. Along with pipe(). Besides, I prefer the interface. As you wish. >test program: > >#include >#include > >struct DosLibrary *DOSBase; >char msg[]="Hello, World!\n"; > >main() >{ > if (DOSBase=(struct DosLibrary *) OpenLibrary("dos.library",0)) { > Write(Output(),msg,sizeof(msg)); > CloseLibrary((struct Library *) DOSBase); > } >} > >compile with "lc -b -r -v -y -O hello.c" >link with "blink hello.o to hello" First: drop -b and -r, they're redundant. -y isn't needed, but use -b0 (so you don't need code to set up a merged data pointer, normally in c.o). Add a return 0, no random return codes please. Add -cs to put strings in the code section, allows pc-rel access, faster, no relocations. >(Yes, I'm looking for the smallest executable possible in C. This >came to about 168 bytes or so.) Note a fair amount of that is load-file overhead. >Question is, do I need the OpenLibrary and CloseLibrary calls, or can >I make the loader perform them? > >(and is dropping the calls courting disaster?) The "resident libraries" in the loadfile format were supposed to allow that, but a) they're somewhat broken, and b) there's no way to specify version. Do NOT try to use this feature, it won't work the way it's documented, and will probably disappear in the future. >One other thing. How can I make a simple program which runs another >program and exits? (without using Execute(), that is.) I want it to >use the current CLI and structure, along with command line and >arguments, all being handled by the executed program. > >I tried something with LoadSeg() followed by a jsr (via a small >assembly module which took one argument - an address to jsr to.) >to BADDR(++segment) followed by UnLoadSeg(--segment). It loaded the >code and seemed to run ok, but when it exited, GOMF popped up several >times complaining about freeing memory already freed. And the memory >it loaded into never got freed. What gives? > >Is there some way to do this? If you don't need BCPL, it's easy, but requires ASM (well, not really with 5.0). You must set up A0/D0 with command string and length. pr_ReturnAddr should be set to avoid Exit() bypassing you. After the program exits, you must UnLoadSeg it. Note that BCPL programs will NOT work in such an environment, they are much harder to support. Some other fields need to be set, such as cli_Module, and other CLI fields. When doing UnLoadSeg, use cli_Module for your pointer, don't stash it and free. Some programs zero cli_Module to keep from being UnLoadSeg()ed. Make sure you save and restore any fields in the process/cli that you change. -- Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup