th@python.UUCP (T. Hartnett) (11/14/85)
Here's a vote for net.os! My interest is in XINU (Re: "Operating System Design - The XINU Approach", D. Comer, Prentice-Hall, 1984). I had a small newsletter going on the subject which I distributed using a mailing list. At last count, approximately 70 email addresses were on that list. On any given day, using mail, a fair number of the "mail"ings would be returned by a mail deamon and I couldn't keep track of who got what. Tom Hartnett ... bellcore!python!th (201) 758 - 2583 P.S. This is a reprint, of sorts, of a blurb I wrote when I first got Xinu up and going. You may find it helpful. Note that my port has been through several changes since I wrote the article below. ******************************************************************************* Subject: Porting XINU (Part I: Getting Started) From: Tom Hartnett .. nvuxd!th or .. bellcore!python!th The following is the first installment in a summary description of how I ported XINU to an M68000-based single board computer. First, you will need a copy of Doug Comer's book: "Operating System Design, The XINU Approach" (Prentice-Hall). If you are working with an LSI-11, most everything is done for you already. You just have to get a hold of the distribution tape from Prentice- Hall (it's approx. $60 plus a copy of your UNIX license). If, like me, you are interested in another machine, you will have to study up on the hardware of your system: memory configuration, special peripheral devices, interrupt servicing, etc. I ported the system in sections. Generally, this is good advice. The "basic" system I used first included the process management routines and the tty drivers. With this much, I was able to start writing simple user programs to verify that the os was operating in a multitasking mode and that individual routines were working correctly. Only later were the buffer, port, disk driver, and file system routines added; one at a time! Lets get started! You'll need to have and understand the following headers/routines: conf.h io.h kernel.h mark.h mem.h proc.h q.h sem.h sleep.h slu.h tty.h chprio.c clkinit.c close.c conf.c control.c create.c freemem.c getc.c getitem.c getmem.c getpid.c getprio.c getstk.c init.c initialize.c insert.c insertd.c ioerr.c ioinit.c ionull.c kill.c kprintf.c mark.c newqueue.c open.c putc.c queue.c read.c ready.c receive.c recvclr.c resched.c resume.c scount.c screate.c sdelete.c seek.c send.c signal.c signaln.c sleep.c sleep10.c sreset.c ssclock.c suspend.c ttycntl.c ttygetc.c ttyiin.c ttyinit.c ttyoin.c ttyputc.c ttyread.c ttywrite.c userret.c wait.c wakeup.c write.c xdone.c doprnt.c The tty routines, in particular, will require reworking if your UART registers and operation are different from the "slu" described in the text. Actually, your first cut at bringing up the operating system need not include the full scale, interrupt-driven, tty device drivers, as output can be handled with kputc, via kprintf. These two routines are easier to understand and can be adapted easily to different UARTs. My system uses Zilog Z8530 Serial Com- munication Controllers. Also, pay close attention to type casting in all the routines; the lsi-11 C compiler uses sizeof(int) = sizeof(pointer) = 2! The 68000 compiler I work with uses sizeof(int) = 2, sizeof(pointer) = 4 (Ouch!). This means, for starters, that integer routines can't pass back pointers simply by type- casting them to int's. Also watch out for structure member address alignment. You will have to write several assembly language routines before you go any further. These routines will, of course, be in the assembly language of the target processor. What is more difficult is including all the hardware differences in these routines. clkint.s ctxsw.s lowcore.s panic.s setclkr.s sizmem.s startup.s Clkint processes the real-time clock interrupts; when I first started with Xinu, I wrote clkint in C. This worked fine while the system was being tested, but, for efficiency reasons, you will want to code clkint in assembler sooner or later. Ctxsw is the basic context switcher; if it doesn't work, you'll know it! Actually, even if the context switcher is broken, you should still get through system initialization and see some printed output before the crash. Lowcore initializes the jump vector, or exception, table. Panic prints a message and dumps register contents when the system reaches an impasse. Sizmem determines the size of memory XINU can use; it can be omitted and a hardwired address used on first cut. Setclkr tests to see if the real-time clock in the system works. Setclkr can be omitted on first cut if, and only if, you are absolutely sure your clock is generating the required interrupts. Xinu can be run without a real-time clock simply by removing the definition of RTCLOCK in conf.h (though I've never tried it). Startup is the entry point to Xinu. It calls a few routines like sizmem and setclkr then eventually calls initialize. Initialize initializes all XINU's data structures and sets up a run- time environment to support multitasking. Initialize eventually becomes the null process (sort of like init in UNIX). The last thing initialize does is start a new process, called main. Main is the entry point to the user soft- ware. On the 68000 system I used, locations 0x0-0x3ff are vectors and the space above the vector table is used by the local prom monitor. I compiled XINU to be loaded starting at location 0x1000. The first routine must be startup.o. The order of the remaining routines is not critical, but you may want to group them by function (process routines, i/o routines, device drivers, etc.). I download XINU with the prom monitor then transfer control to Xinu by jumping to location 0x1000. From that time on, XINU controls the processor and the prom monitor never regains control (except that, for "panics", the last thing I do is jump to the prom monitor entry point). You will, no doubt, want to have a Makefile while porting and debugging your system. At first, you should load the kernel and user code together. Once things are running smoothly, its easy to implement a system call interface so that the user routines can be loaded independent of the kernel. By user code, I mean main.c and any non-system routines it calls/uses. *******************************************************************************