URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
[/] [eco32/] [trunk/] [doc/] [history] - Rev 56
Go to most recent revision | Compare with Previous | Blame | View Log
Project History---------------14-Nov-2002Project launched.Main makefile written.Directory structure created.15-Nov-2002Kernel of UNIX 7th Edition copied.Download and installation of lcc.This included the following steps:1) In 'src', copy 'mips.md' to 'eco32.md' without changes,except that the interface record is named 'eco32IR'.The code output remains for now as it is in 'mips.md'.2) Add instructions to makefile for compiling 'eco32.md'.3) In 'src', add the interface record definition 'eco32IR'to the file 'bind.c'.4) Add a directory 'include/eco32/linux' and copy all headerfiles from the corresponding directory for the mips processor.5) In 'etc', copy 'irix.c' to 'eco32-linux.c' and change thecontents of this file to properly call the preprocessor,the compiler, etc.6) Add the option -DLCCDIR=\"$(BUILDDIR)/\" to the instructionin the makefile which compiles $(HOSTFILE).7) In 'src', substitute 'lex.c' with a newer version, whichcomputes the types of hexadecimal constants correctly.Disk creator done.Program to write the bootstrap sector done.16-Nov-2002Preliminary instruction formats defined.Preliminary instruction set constructed.Some ideas for an address translation unit noted.17-Nov-2002Final instruction formats defined.Preliminary version of simulator finished.19-Nov-2002Instruction set cleanup done.Work on assembler started.23-Nov-2002Four of the five ROMs translated to ECO32.24-Nov-2002Preliminary version of assembler/linker/loader finished.25-Nov-2002Bootstrap monitor ROM translated to ECO32.Simulator is running.Bootstrap sector on disk created.Now it is possible to boot from the disk.26-Nov-2002Work on an ECO32 back-end for the C compiler started.27-Nov-2002Preliminary version of back-end done.28-Nov-2002'Load address' instruction invented as macro for a setof short sequences of instructions which are difficultto generate by the back-end.29-Nov-2002Startup code (c0.s, c1.s) revised.Writing the bootstrap sector revised.System ROMs revised.Tests revised.30-Nov-2002Started to program the MMU.Surprise: we don't need an MMU enable bit! The unit can beswitched on all the time, but we have to be careful not touse the TLB before it is properly initialized.01-Dec-2002Interrupt system re-designed.Added the last missing case in the 'lda' implementation.Timer interrupt is working properly.We now have a new instruction: 'nor'. With this it is easyto implement the bitwise complement of an integer. Done.The compiler option -Wo-kernel compiles a program so thatit can be run in kernel mode.This is a big step forward: hello.c is running (in kernelmode of course).02-Dec-2002The characteristic feature of kernel mode programs as well asof the kernel itself is that they want to handle all sorts ofspecial conditions for themselves (e.g., interrupts, exceptions,startup code). So if the flag -Wo-kernel is given, the startuplibrary code (c0.s and c1.s) is no longer linked in automatically.03-Dec-2002The assembler now contains a complete expression parser which canhandle additive, multiplicative and shift expressions as well asunary and parenthesized expressions.Error in back-end corrected: mul & div instructions did notcorrectly specify the second source register.04-Dec-2002The low-level code generators in the assembler had completely tobe redone: they could not handle big constants (immediate valuesand addresses) in instructions that allow only 16 bit constants.05-Dec-2002I now have a pair of functions which allow to get/set aninterrupt service routine in the interrupt service routinetable. The low-level register save/restore is handled inassembler, but the interrupt service routine itself can bewritten in C. An application of this principle shows how todetermine the total amount of physical memory by probingthe memory until a bus timeout exception occurs. This canfully be formulated in C.The back-end generates a 'jal' instruction even when theargument is a register. Although it would perhaps be moreappropriate to generate a 'jalr' instruction, I changed theassembler to accept an address as well as a register withthis instruction.06-Dec-2002TLB flush is the first instruction dealing with the TLB.Implemented.07-Dec-2002Until now we only had one special processor register, theprocessor status word. With the MMU present, this will change.Renamed 'gpsw' (get processor status word) to 'mvfs' (movefrom special register). Renamed 'ppsw' (put processor statusword) to 'mvts' (move to special register). These instructionshave two arguments: a single register and a number specifyingthe special register.It is perhaps better to use an established set of instructionsdealing with the TLB (i.e., the way MIPS is doing this) insteadof an even more minimalistic one, which is not guaranteed tocover all cases. So I will abandon 'TLB flush' in favor of thefour instructions found in the MIPS instruction set ('tbs','tbwr', 'tbri', and 'tbwi').As is documented in the MIPS reference book, the valid bit V isnot involved in the TLB matching process. Implementation changed.Perhaps we don't need the V bit at all? I'll leave it out for now.08-Dec-2002Today I came up with the idea to test the MMU implementation byrunning a somewhat more realistic test: a task which is compiledfor virtual address 0 and has a minimal I/O library which trapsto the kernel to output a character.09-Dec-2002It is not necessary to prepare real page tables for the task, as Ithought initially. Since we have only one task which uses exactlytwo pages (code and stack), it is possible to preset the TLB withtwo entries for the pages and then leave it alone.The test is running.10-Dec-2002Now for the next step: two tasks running concurrently, preemptedby a timer interrupt. This is really a lot more complicated thana single task because now the entries in the TLB must be flushedand re-programmed when a task switch occurs.Another complication is the need for two kernel-mode stacks, onefor each task, in addition to the task-specific user-mode stacks.This is necessary because of two facts:- the kernel cannot rely on the integrity of the user-mode stacks- the state of the suspended task must be preserved somewhere,even if the other task is running and trapping to the kernelfor a system call.11-Dec-2002This was indeed much harder than expected, but now it works.12-Dec-2002It is evident that only a very short sequence of instructions isable to handle a TLB miss exception efficiently. MIPS is doingthis by giving the TLB miss exception a separate interrupt vector.We don't want to go so far, but of course we cannot tolerate toexecute all the lengthy actions at the beginning of the standardtrap handler. So we will sort out the TLB miss exception at thevery beginning of the standard exception handling.13-Dec-2002It is easy to catch the TLB miss - but how should it be handled?Some sort of page table has to supply the necessary informationso that a new entry can be filled into the TLB. How should thepage tables be organized? In the past I saw cascaded page tablesas the only solution. But it might be better to have a singlepage table which itself is paged and lies in virtual memory.The big advantages of this scheme are fast access (no pointersto chase) and (almost) no waste of memory because gaps in thetable do not need any real memory. But then of course we haveto handle TLB misses while accessing the page table...Very confusing!14-Dec-2002What information is needed in which format if a TLB miss (or anyother TLB exception) occurs? I really have no stringent answer tothis question, so I will follow again a minimalistic design path:Implement a register in the MMU which is set to the offendingvirtual address in case the translation didn't work. Done.As I realize now, this hardware equipment can support a variety ofdifferent organizations of the page tables handled by software.Even inverted page tables seem feasible!It would be very convenient if the kernel could use anotherregister without having to save its contents first. I thinkwe could let the kernel have also register 28 at its disposal.17-Dec-2002Yesterday I realized that the 'lda' macro instruction is no longerneeded because 'add' does the very same job. Deleted.18-Dec-2002It is very desirable to have an interrupt mask in the PSW.If, e.g., the timer interrupts and the timer ISR decides todisable interrupts from all devices but the timer itself,then this is not easily achievable without a central mask.19-Dec-2002One's complement, represented by '~', is another operatorimplemented in the assembler.20-Dec-2002As well as bitwise and, bitwise xor, and bitwise or,represented by '&', '^', and '|', respectively. Theseoperators are left associative and have the same priorityas they have in C, i.e., & > ^ > |, in order of decreasingpriority.21-Dec-2002Because of the new structure of the PSW all tests must beupdated and carried out once more. A lot of work...22-Dec-2002I spotted a minor bug in the simulator: a breakpoint whichwas set to address C0000004 in order to catch any interruptor exception will not work for exceptions. This is due tothe handling of exceptions by setjmp/longjmp. Corrected.23-Dec-2002ECO32 Version 0.0 released.26-Dec-2002Today I started to convert the original sources ofUNIX 7th Edition to ANSI C.29-Dec-2002I found a real programming error in the text.c module:if (ip->i_flag&ITEXT==0) return;My compiler warned: 'expression with no effect elided'.'==' has higher precedence than '&', but ITEXT does notequal zero, so the whole test expression becomes zeroand the return is never executed. The line should read:if ((ip->i_flag&ITEXT)==0) return;31-Dec-2002The masters made a typoe: in the file kl.c, the functionnamed 'ttioccomm' is spelled 'ttioccom'. I think thisdid go undetected because of the very restricted lengthof symbols with external linkage.01-Jan-2003Today I began investigating the startup procedure. I willplace the per-process kernel stack in the top half of theu area, which itself is one page in size and is locateddirectly underneath the kernel at 0xC0000000 - 0x1000.This part of the virtual address space is mapped and sothe u area of the running process is always accessible.02-Jan-2003How do we do the memory management? This is THE centralquestion of our porting effort. One possibility whichoffers the chance of only minor changes to the existingsources would be to keep the management by the coremaparray, but with the granularity changed to 4 k, the pagesize. This route of course would not barely touch thepower of demand paging, which is possible by our hardware.Nevertheless, I will follow this path for the time being.I changed the coremap/swapmap entries into structs of twointegers instead of two shorts. Otherwise the range ofaddresses might get too small (although this is unlikely:64 k pages of 4 k bytes each equals 256 M bytes - quite alot of memory).04-Jan-2003This last change is nonsense - much of the other storedinformation about processes would have to be changed also.Reverted.Because ECO32 does not have two different stack pointers(as the PDP-11 has) we must switch to the kernel stackexplicitly. But we must not do the switch if the interrupthit while the machine was running in kernel mode already -then the sp points deep into a properly setup kernel stack.Switching stacks would then destroy the stack completely.11-Jan-2003I discovered a mysterious overwriting of some bytes ofthe loaded UNIX kernel. This took place even before anyof its code was executed! A little bit of searching, andthe guilty one was found: the bootmon ROM code and itsstack. Now there is a problem: where should we put thestack of the bootmon ROM?We have two ways to get some program into the bare machine:a) The 'realistic hardware' scenario: a ROM holds an initialprogram which e.g. may boot the operating system from disk.b) The 'convenient debugging scenario': the program, e.g. theoperating system, is somewhat magically loaded into RAM.The error described above is caused by the unwanted interactionof a) and b) when used together. So I think that the correctsolution of the problem is to forbid the specification of bothsimulator options -r and -l at the same time.13-Jan-2003The simulator uses all CPU power which is available, evenwhen only waiting for a command line. This can easily bechanged by inserting a usleep(100) call into the inputwaiting loop of the curses interface. Done.Two new pseudo-ops (.syn and .nosyn) added to the assembler.They allow or disallow synthesizing instructions with 'big'constants, respectively. This can be used e.g. in the TLB misshandler, where much finer control over the usage of register$1 is needed.15-Jan-2003The constant BSLOP in param.h must be set to 0. Otherwise therewould exist blocks which don't start at an address which is amultiple of 4. This would result in a Bus Address Error if e.g.an integer is fetched from the block.16-Jan-2003The type mapping from C to machine types is as follows:PDP-11 ECO32char byte (1 byte) byte (1 byte)short word (2 bytes) half (2 bytes)int word (2 bytes) word (4 bytes)long double word (4 bytes) word (4 bytes)T * word (2 bytes) word (4 bytes)As can be seen, only ints and pointers are differently mapped.This is of not much concern with in-memory data structures butcan be desastrous with on-disk data structures (super block,inodes). Therefore we have to do the following:a) define ino_t as unsigned shortb) rearrange the components in struct filsys (and in principle instruct dinode and struct direct too) so that no padding occurs.I thought that I could simply write a disk with the PDP-11 simulatorand then use it with the ECO32 simulator; this is not possibledue to different endianness.17-Jan-2003Here are the changes I actually made:1) in param.h:a) type 'ino_t' is 'unsigned short' instead of 'unsigned int'b) type 'dev_t' is 'short' instead of 'int'2) in filsys.h:a) delete all components of struct filsys below the comment'remainder not maintained by this version of the system'b) 's_isize' is of type 'daddr_t', not of type 'unsigned short'c) 's_nfree' is of type 'int', not of type 'short'd) 's_ninode' is of type 'int', not of type 'short'e) exchange components 's_isize' and 's_fsize'3) in inode.h:a) 'i_flag' is of type 'short', not of type 'char'b) 'i_count' is of type 'short', not of type 'char'The size of the superblock structure is thus increased by 6 bytesto 424 bytes (well below the 512 bytes block boundary), and allpadding or misalignment is avoided.18-Jan-2003I replaced the "Hello, world!" message in the default master bootrecord by a somewhat more appropriate message.19-Jan-2003In order to simplify things a bit, I removed the '-n' option fromthe assembler. Now assembler output files always do have headers.There are of course situations in which the header must be strippedoff, e.g. with the boot record, or with the ROM in the simulator.We have therefore now a 'loader', a little program which convertsan assembler output file into a memory image without any header.This has the additional benefit that the simulator does no longerneed to know the executable format, which is especially good if wechange the format or add new formats.20-Jan-2003Started to port the 'mkfs' utility.21-Jan-2003Started to program a 'show file system' utility.22-Jan-2003Today I decided to spare a small number of TLB entries (4) fromrandom replacement. This helps to keep such vital information asthe current kernel stack permanently mapped.25-Jan-2003I changed the disk so that it is now similar to the 'rp' devicein the PDP-11. This has the advantage that the usr file systemis located on a different device (specifically: a different minordevice, i.e., a different partition) so that mounting can be tested.The partitions and their intended use is as follows:device size in blocks use as-------------------------------------------rp0 14000 whole diskrp1 2000 rootrp2 4000 swaprp3 8000 usr28-Jan-2003This was quite a lot of work, but finally 'mkfs' is running.The crucial tool to achieve this was 'shfs' - show file system,which allows displaying arbitrary blocks of a disk in severalformats (raw data, super block, inode block, directory block,free list block, or indirect block). So everything on the diskcan be examined in detail.By the way, the main hurdles to overcome had been differentendianness of ECO32 and x86, different padding of structures,and alignment restrictions with ECO32, which are not presenton the x86 architecture.29-Jan-2003Here is a short report on byte-ordering on x86, ECO32, and PDP-11.The C data type 'long' is stored in 4 bytes on all thre machines,as already stated above (16-Jan-2003). The order of the bytes isdifferent on all three machines. We number the bytes from MSB(most signigicant byte) to LSB (least significant byte): thenthe number (b1 b2 b3 b4) has the value b1*2^24+b2*2^16+b3*2^8+b4.If 'A' is the lowest (byte) address where the number is to be stored,then the memory layout of the three architectures look like this:x86 A+0:b4 A+1:b3 A+2:b2 A+3:b1 (i.e., little endian)ECO32 A+0:b1 A+1:b2 A+2:b3 A+3:b4 (i.e., big endian)PDP-11 A+0:b2 A+0:b1 A+0:b4 A+0:b3 (i.e., mixed)An additional complication results from the fact that disk addressesin inodes on a disk are stored in a three byte format, which isdifferent on ECO32 and PDP-11 (there is no such format on the x86,because we don't want to run a file system on a bare PC, only withinthe ECO32 simulator). In this format only the three least significantbytes (b2 b3 b4) are stored; if b1 were non-zero an error would betriggered. So then, here are the layouts of this special format:ECO32 A+0:b2 A+1:b3 A+2:b4PDP-11 A+0:b2 A+1:b4 A+2:b3As can be seen, this format is constructed on both architectures byomitting b1 (the MSB) from the four byte format.I changed the routines that convert the three byte format from and tothe four byte format (iexpand() and iupdat(), both in module iget.c)in order to cope with the changed byte-ordering.Reduced the RAM size to 1M; this fits better to the disk swap size.Added a counter to the simulator which counts the total number ofinstructions executed since the last reset. This helps a lot if onewants to re-visit a specific location in the program, if a lot ofsingle-stepping has been done to find the location for the first time.31-Jan-2003There has been an inconsistency with the object file format sinceits invention: the header data is stored in little endian format,which is convenient for the tools working in the cross developmentsetup. The tools running on the target architecture require thedata to be in ECO32 format of course. This is especially true forthe kernel exec file loader. Changed.03-Feb-2003ECO32 Version 0.1 released.04-Feb-2003Added to 'shfs' a command which translates an inode number into theblock number in which this inode is located, together with an inodenumber relative to that block.The simulator's 't' command now displays also the special registersof the MMU (Index, EntryHi, EntryLo, BadAddress).Memory commands of the simulator completed.05-Feb-2003ATTENTION: I changed the output of the disassembler to get it moreconsistent with the rest of the simulator, and especially with itsinline assembler. There are no more '0x' prefixes in front of numbers,and we don't have any decimal output. All numbers are given as hexnumbers without a prefix (the only exception to this rule are thenumbers of registers proper, of course, which are given in decimal).The instructions which do sign extension show their arguments assigned hex numbers. Labels are also no longer prefixed.Inline assembler completed.17-Feb-2003ECO32 Version 0.2 released.20-Aug-2003ECO32 Version 0.3 released.21-Aug-20031) I changed the 'ldhi' opcode from 0x1E to 0x1F.Reason: The instruction decoding gets more regular.2) The ALU has now an 'xnor' instruction instead of a 'nor':(a xnor b) = ~(a ^ b) = (~a ^ b) = (a ^ ~b) = (a == b),bitwise parallel for all 32 bits.Reason: The ALU is easier to implement, and the instructionset becomes more regular.3) The PC relative jumps (j, jal, all conditional branches) nowhave PC+4 as their reference location (and no longer PC).Reason: PC+4 is computed early in the instruction cycle; allother RISC machines do this alike.4) The PC relative jumps (j, jal, all conditional branches) nowencode a word offset, and no longer a byte offset.Reason: The target ranges for the jumps are quadrupled withoutany additional effort.07-Oct-2003Explored the possibilities to implement a graphics controller forECO32. Easy from the simulator's point of view, not quite so easyfrom the implementer's point of view (due to X complications,threads needed) but certainly feasible.13-Oct-2003Graphics controller implemented.20-Oct-2003Curses feeds certain keypad codes directly into the simulator'sterminal, e.g. KEY_BACKSPACE. There the MSBs get stripped off anda wrong keycode is supplied to the simulated program. Now thesespecial codes are mapped to regular control characters, e.g. BS.25-Oct-2003The assembler now understands the option '-h' which suppresses theoutput of the executable's header and appends the BSS's size bytesof zeroes at the end of the executable. This in turn renders the'load' tool redundant, which can be deleted. Done.26-Oct-2003A group of students is working on a ROM-based monitor program. Theyneed an instruction to implement breakpoints. Because the instructionmap is already crowded they have to use 'trap'. But they want ofcourse a breakpoint trap be easily distinguishable from any otherkind of trap. So the assembler now allows a constant operand for'trap'. This operand is assembled into the otherwise unused bitsof the instruction. These bits are in turn ignored by the CPU (aswas the case all the time) but can be inspected by software whichmust read the instruction from memory in order to do this. Now abreakpoint trap can get a unique bit pattern distinct from the bitpatterns of all other traps. Remark: not only the regular assemblermust understand this but also the simulator's inline assembler aswell as its disassembler. Done.09-Nov-2003The curses library correctly sets the terminal mode to "raw" so thatneither SIGINT nor SIGQUIT signals can be generated by the keyboard.With a graphics controller attached it is however possible that theuser selects "kill" from the window menu of the monitor window andthus shuts down the connection to the X server. This in turn leadsto an uncontrolled instant termination of the whole simulator whichcannot be tolerated (e.g. the terminal would stay in raw mode: veryannoying for an unsuspecting user). Solution: install an I/O errorhandler which gets called from the X system in case the connectionto the server is lost. Done.16-Nov-2003I added a check to the initialization of the memory simulation ensuringthat neither ROM image files nor program files loaded into main memorycan overflow the available space (and thus crash the simulator).18-Nov-2003The terminal simulation now handles the following control characters:(input) <return> 0x0D<backspace> 0x08<arrow down> 0x0E<arrow up> 0x10<arrow left> 0x02<arrow right> 0x06(output) 0x07 beep0x0D return cursor to begin of current line0x0A scroll if cursor is in last line,set cursor to next line in same column0x02 move cursor left (stop at leftmost column)0x06 move cursor right (stop at rightmost column)0x10 move cursor up (stop at topmost line)0x0E move cursor down (stop at bottom line)0x08 delete character to the left of cursor,move cursor left0x09 output spaces (minimum is one space),until column mod 8 = 019-Nov-2003Today I took the first few steps towards a bootable system disk.Changes in bootstrap monitor:- 'g' command deleted- monitor stack sits just below 1M- master boot record loaded at physical address 0x00000000- master boot record started at virtual address 0xC0000000Changes in constructing the default master boot record:- relocate code to 0xC000000020-Nov-2003Now here is the big picture of the boot process:a) ROM bootstrapThe ROM loads the first sector of the disk and starts whatever ithas loaded (provided that the signature is present). Until now thiswas always the default master boot record. In the future this willbe the first stage bootstrap. This part is already finished.b) First stage bootstrapThe first stage looks for a file named "boot" in the root directoryof the file system on the boot disk. This part must fit into a singlesector and thus is restricted in its capabilities:- boot must lie in the root directoy- it must be one of the first 320 directory entries in the rootdirectory (only the 10 direct blocks of the directory file aresearched for it)- it must not be bigger than 5120 Bytes (only the 10 direct blocksof the executable file are loaded)c) Second stage bootstrapThis stage loads the kernel, perhaps asking the user for its name.22-Nov-2003First stage bootstrap completed.27-Nov-2003Second stage bootstrap completed.It was indeed possible to ask the user for the path to the kernel hewants to get started. The only kernel available for now is one of thetests from tst/os.29-Nov-2003Makefiles tweaked.06-Dec-2003Today I started to develop the tools shfs and mkfs for file systemswith 4K blocksize. With this blocksize it should be possible to dothe bootstrap without a named second stage. Conceptually there areagain two stages (first load a single sector, then the rest), butboth stages should fit within the boot block.20-Dec-2003I discovered a small bug (?) in the simulator: if a write to $0 isrequested by an instruction, not only the write is suppressed (thisis expected) but also the source operand does not get computed.Thus the instruction ldw $0,$0,1 which is incorrect if no TLB entryfor page 0 exists (and is so even if it exists because of alignmentviolation) does not lead to an exception (which is quite unexpected).Solution: Always compute the source operands, even if $0 is the target.30-Dec-2003In order to use swap space on the same disk where the root file systemis located we need some form of disk partitioning, preferrably NOTdeeply coded into the disk driver (as the original UNIX has done it).In other words, we need a real master boot record, a partition tableand a tool ("fdisk" or "mkpart") to set up such a table.01-Jan-2004"mkpart" finished. It constructs a partition table from a textualconfiguration file and writes it to sector 1. It also copies an MBR(which has not been done yet) to sector 0, and a bootstrap manager(which also has yet to be done) to sectors 2-7.MBR coded.02-Jan-2004Bootstrap manager done.03-Jan-2004Tool "mkpart" is working.New tool "shpart" displays a partition table, read from a disk image.04-Jan-2004I made the file systen viewer aware of partitions.05-Jan-2004Now "mkfs" also knows something about partitions.08-Jan-2004If the operating system is booted from a partition of a disk (incontrast to being booted from the start of the whole disk) its diskdriver must know where logical sector 0 of the partition is locatedon the disk. In other words, the master bootstrap must transfer alittle bit of information to the boot loader of the OS. This couldbe done as follows: $26 holds the start sector of the partition fromwhere the OS is booted and $27 holds its size. In order to use thevery same bootstrap also in the case that the disk has no partitions(and thus the file system occupies the whole disk), this informationmust also be supplied by the ROM bootstrap sequence. Done.Surprise: this scheme would allow the sub-partitioning of a partitionwithout any modification!10-Jan-2004Now the whole bootstrap chain is working. It goes like this:a) The ROM loads the first sector of the disk and starts whatever ithas loaded (provided that the 0x55AA signature is present). Thismay be either the master boot record if the disk is partitioned,or an ordinary boot record if it is not (see remark below).b) In case the master boot record is executing, it loads sectors 2..7into memory (sector 1, the second sector of the disk, is skippedbecause it holds the partition table). These sectors contain a smallprogram, the boot manager, in executable format. The boot manager isstarted by the master boot record.c) The boot manager loads the partition table from sector 1 of the disk,displays the partitions of the disk, and asks the user to enter apartition number to boot. An attempt to boot a partition outside therange 0..15 is rejected, as well as requesting to boot a partitionwhich does not contain a file system of any kind, or does not havethe "bootable" flag set. If all is well, the boot record of theselected partition is loaded. If it has a valid 0x55AA signature,it is started.Remark: This is the point in the bootstrap chain which is reachedimmediately from the ROM code if the disk is not partitioned.d) The boot record code loads partition relative sectors 1..7, i.e.the rest of the boot block. These sectors contain a small program,the bootstrap loader, in executable format. The bootstrap loader isstarted by the boot record code.e) The bootstrap loader asks the user for a path to a file which mustexist, must be a regular file, and must be executable by its owner.This will of course be normally an operating system kernel. Thedefault value is /boot/unix. The file is loaded and started.Throughout the whole process registers $26 and $27 hold the start sectorand size of the currently selected range of the disk, respectively.12-Jan-2004The register conventions shown above must be changed somewhat becausewith more than one disk present it is also necessary to tell the diskdriver which disk to use:$26 base address of disk controller$27 start sector of partition (or disk)$28 size of partition (or disk) in sectors28-Jan-2004After rewriting parts of the make file system utility (so that doubleindirect blocks can be used, which is necessary for a file system with512 byte blocks to hold files of more than 69K) it is now possible toboot our port of UNIX 7th Edition from the disk. Alas, it is not yetrunning very stable.10-Mar-2004Finally I added the generation of copying loops to the compiler'sback-end. This has long been missing.17-Apr-2004Translating virtual addresses using the TLB costs time because theparallel associative hardware must be simulated by serial software.This is very noticeable with programs running in user mode; they runat roughly one third of the speed kernel mode programs do. In orderto alleviate this I added a function which acts almost the same asthe TLB associative lookup does, but without any error checks. Itssole pupose is to use up time and it is called whenever an unmappedaddress is detected by the virtual-to-physical address translation.21-Apr-2004Up till now the assembler located the data segment directly abovethe code segment. This is not a viable strategy once paging is ineffect. Due to code sharing and protection reasons, the data segmentshould start on the next page boundary above the code. The resultinggap may also be present in the executable file: there is no need tostore any bytes for it in the executable (at least as long as it isan executable with a header - for headerless executables the gapbytes must be stored within the file).It would have been possible to define two different executable formats,one with the data segment directly following the code segment, andanother one with the data segment aligned on a page boundary. Thetwo formats then would have to be distinguished by different magicnumbers in the header. I did not do this, however, because I sawno reason to keep the "directly following" format. If one wants tocompress code and data as much as possible, one can in any case putboth into the code segment.24-Apr-2004The simulated graphics device did not detect memory accesses whichlie within the device address bounds but outside the screen memory.These accesses were propagated to the X Window System and in turn anX Window data structure was accessed outside of its allocated memory.At least on our Sun computer this translated to an immediate deathof the simulator process. Now the graphics device detects such anattempt to access simulated memory outside the screen, and producesa 'bus timeout' exception.06-May-2004ECO32 Version 0.4 released.08-May-2004I intend to give the ECO32 simulator the ability to run with more thanone simulated terminal. This will work best if there is no differencebetween the first terminal and the other ones, so I will open a separatewindow for each terminal (and use the first window in which the simulatorwas started only for controlling the simulator, and NOT for a simulatedterminal). Then using curses is no longer necessary and can be removed.But I want to retain command line editing, so I will use the 'getline'library.Curses interface removed.Getline library installed.Interrupt priorities changed:15 not used14 timer13 not used12 not used11 not used10 not used09 not used08 disk07 terminal 3 receiver06 terminal 3 transmitter05 terminal 2 receiver04 terminal 2 transmitter03 terminal 1 receiver02 terminal 1 transmitter01 terminal 0 receiver00 terminal 0 transmitter10-May-2004SIGINT handler installed (for use within the control window to regaincontrol in case of a runaway program).In order to use a single timer callback routine for all terminals, thecallback routine must get an argument, telling which terminal is doingthe callback. So ALL timer callbacks now have such an argument, whichcan be used arbitrarily by the callback initiator to communicate aninteger to the callback routine.17-May-2004The new terminal implementation must be tested as well as the changedinterrupt priority scheme. And even more important: allocation of thedata segment on a page boundary (see 21-Apr-2004) must be verified!Done for the 'tst' directory.18-May-2004Done for the 'eos' directory.27-Feb-2005ECO32 Version 0.5 released.28-Feb-2005Despite the long time since the release of the previous version thiswas very premature: I did not read the comments above and forgot toconduct many of the tests. And indeed, the bootstrap does not workany longer.01-Mar-2005The bootstrap manager should not be compiled to any standard executableformat, because this part of the boot process is independent of anyoperating system. It should be compiled to plain binary format, as isthe master boot record. Now we are facing a dilemma: We want to writethe boot manager (mostly) in C and therefore will have a separate datasegment, aligned on a page boundary. But we also want a headerlessbinary output, so there will be no loading information. All gaps inthe loaded program and data will therefore be filled with zeroes.Then either we must define another executable format in which the datasegment follows directly after the code segment (without padding to thenext page boundary, see discussion above) or we have to spend somewhatmore space on disk for the bootstrap managers's program/data image.I think I will do the latter.04-Mar-2005The solution above is not very elegant: The same reasoning applies alsoto the bootstrap within a partition. Then we are forced to reserve twoblocks instead of the traditional single one for the bootstrap. This isnot totally out of question, but not very appealing either.There is another solution, if we accept the boot manager to be compiledto standard executable format: write a very compact loader for this formatand squeeze it into the master boot record. Difficult, but it can bedone, as I proved today.Changes from above reverted.Disk partitioning, master boot record, and boot manager done.05-Mar-2005Boot record and bootstrap loader done.08-Mar-2005I think that today I completed the tests and changes which I begunon 17-May-2004.ECO32 Version 0.6 released.27-Oct-2005ECO32 Version 0.7 released.This was done in order to have a stable release on which to builda simplified version of the ECO32, which is named ECO32e (the 'e'stands for 'embedded'). The ECO32e will get implemented in an FPGA.26-Jun-2006We do have an error in the implementation of the SAR instructions,really! The C standard says that the result of shifts with shiftamounts greater than or equal to (!) the number of bits in the leftexpression's type is undefined. Consequently, in the CPU implementationcpu.c we have to replacesmsk = (MSB ? 0xFFFFFFFF << (32 - scnt) : 0);in the SAR and SARI instructions withsmsk = (MSB ? ~(((Word) 0xFFFFFFFF) >> scnt) : 0);because if scnt == 0 then 0xFFFFFFFF << (32 - scnt) is undefined.Thanks to Rolf Viehmann for pointing this out.27-Jun-2006The rfx instruction must not be executed in user mode, because itwrites the previous mode and interrupt enable bits of the PSW overthe current ones. Therefore rfx becomes a privileged instructionwhich triggers EXC_PRV_INSTRCT if executed in user mode.Again thanks to Rolf Viehmann for recognizing the potential dangerif this instruction is executed in user mode.09-Jul-2006Pending interrupts are now displayed when executing the 'register'command. It is not meaningful to display pending exceptions, however,because these are immediately handled within the longjump frameworkand thus would never show anything else but 'off'.10-Jul-2006We have a new command to display (and possibly change) the value ofthe PSW. This comes in very handy if debugging in user mode and thusnot having access to privileged addresses.12-Jul-2006There is a new control bit in the PSW, the 'vector bit' V, which directsinterrupts to ROM_BASE + 4 if it is off and to RAM_BASE + 4 if it is on.This bit is cleared when the CPU is reset. In this way the software candecide whether the interrupt service routine is located in ROM or in RAM.15-Jul-2006I decided to give "user TLB misses" an extra interrupt service routineentry point. These are TLB misses triggered by an access to a virtualaddress with MSB = 0, regardless of execution mode (user or kernel).22-Jul-2006The physical address space (2^30 bytes) is partitioned as follows(in order to be compatible with the ECO32e):RAM virt start 0xC0000000 phys start 0x00000000 size 0x20000000ROM virt start 0xE0000000 phys start 0x20000000 size 0x10000000I/O virt start 0xF0000000 phys start 0x30000000 size 0x10000000The I/O address space is evenly divided into 256 devices which mayoccupy up to 1MByte each.30-Jul-2006We now have two control bits in the outgoing part of every entry ofthe TLB: a "valid" bit (which triggers a "TLB invalid exception" ifthis entry is selected by a memory translation and the bit is 0) anda "write" bit (which triggers a "TLB write exception" if this entryis used to map a write access to a page and the bit is 0). The "TLBdouble hit exception" does not exist any longer.The reason for existence of the "write" bit is obvious (possibilityto protect pages from writing, implement a copy-on-write policy).The reason for existence of the "valid" bit is speed: the TLB refillroutine should run as fast as possible and therefore should avoidtests for special cases as much as possible. If some processing mustbe done for a page to be usable, the check for this condition shouldnot be done in the TLB miss handler. If the valid bit is cleared inthe page table, the refill routine will enter the translation that itgets from the page table into the TLB without checking, but the nextuse of this entry will lead to another exception, where the processingthen can be done.31-Jul-2006The implementation of the ECO32e suggested a different coding of thesingle register operand in the jr and jalr instructions. It is nowcoded in the src1 field instead of the dst field of these instructions.01-Aug-2006a) I rearranged the exceptions as follows:EXC_BUS_TIMEOUT 16EXC_ILL_INSTRCT 17EXC_PRV_INSTRCT 18EXC_DIVIDE 19EXC_TRAP 20EXC_TLB_MISS 21EXC_TLB_WRITE 22EXC_TLB_INVALID 23EXC_ILL_ADDRESS 24EXC_PRV_ADDRESS 25In this way they are grouped together more logically.b) The detection of an EXC_ILL_ADDRESS exception (formerly calledEXC_BUS_ADDRESS) is now done in the MMU and thus operates on logicaladdresses. It is then possible to store the offending address in theBadAddr register for further processing by OS software.c) The EntryHi register now gets loaded with the page base addressif one of the three TLB exceptions occurs, so that it need not becomputed from the contents of the BadAddr register.02-Aug-2006A "context" register, which is preloaded by OS software with the baseaddress of memory-resident page tables, and where the page number ofa page with missing translation is ored-in by hardware would speed upthe TLB miss handler. On the other hand, it practically mandates theuse of a certain page table format (or, if the OS designer wants adifferent format, the context register would not be used at all).Therefore I will not implement a context register.03-Oct-2006Major instruction format redesign: the decision to put the destinationregister address in a fixed location within the instruction was wrong.It implied that the source register addresses were not fixed and thusmust be multiplexed early in the instruction cycle dependent upon theopcode. It should be done the other way around. Completed.19-Nov-2006Today I completed the back-port of the display and keyboard from ECO32e.Both are available if the command line switch -c ("console") is given.The default number of terminals was in turn reduced to 0.14-Feb-2007Interrupts are now level triggered. If at any time interrupt sharingwould become necessary (this is in fact quite possible with only 16interrupts) it cannot be realized if interrupts were edge triggered.04-Jun-2008Project finally split:ECO32 (version 0.17) -- FPGA hardware, simulator, assemblerEOS32 (version 0.11) -- C compiler, ROM monitor, operating system20-Feb-2009ECO32 now has its own linkable object file format, which is a variantof the venerable a.out format. Consequently, 'asld' has been split intothe assembler 'as' and the linking loader 'ld'. Additionally, there isa program 'dof' which dumps the contents of an object file.22-Feb-2009What is the exact meaning of 'jalr $31'? This can of course be definedarbitrarily, but the natural semantics would likely be "jump to theroutine addressed by $31 and remember the return address (in $31)".To my surprise, the hardware did exactly that, while the simulatorinterpreted the instruction as "store the return address in $31 andthen jump to the routine addressed by $31", which resulted in nottaking the jump at all. Simulator corrected.14-Feb-2011B_PHYS and B_MAP macros eliminated. They both are only used with thePDP-11 UNIBUS map functionality.15-Feb-2011In the simulated ECO32, if I try to allocate 60 chunks of memory, eachof them having 10000 bytes, I get a kernel panic: exception 22 in kernelmode. The reason is untested code, executed for the first time ever: thekernel is doing an "expansion swap" in order to get enough memory forthe process.16-Feb-2011Now this is interesting: what is the field "b_bcount" in struct buf(include/buf.h) good for? Do any transfers with b_bcount != BSIZEexist? The answer is yes, in two places:a) swap I/O (src/bio.c)b) raw I/O (src/bio.c)(There is a third (mis-)usage of the field b_bcount: it is used asb_active flag in some block device drivers.)Raw I/O has to be overhauled in any case, so we concentrate on swapI/O here. Swap I/O transfers possibly many pages at once, startingat a given disk block and a given memory address. But this is onlycorrect under the current "contiguous physical memory per process"allocation policy. It is useless under any policy which allocatesphysical memory for a process non-contiguously - provided that thetransfer mechanism accesses physical memory and not virtual memory(this is typically the case with DMA). So the kernel will no longerrely on the disk driver (and possibly the disk hardware) to transfermultiple blocks in a single call, but split them up into single blocktransfers. Done - the "expansion swap" is now running.----------------------------------------------------------------In the meantime...- experiments with porting ECO32 to another FPGA board- splitting the project (separating the OS part)- experiments with a pipelined version of ECO32----------------------------------------------------------------03-Feb-2014Project "ECO32" created on OpenCores, based on version eco32-0.22:http://opencores.org/project,eco3218-Feb-2014Several changes in the simulator:a) There are two independent identical timer/countersavailable, of course with different interrupts and I/Oaddresses (see below).b) The timer/counters are readable, so that they canbe used for short-time measurements. They count clockcycles (no pre-scaling any longer). This change willaffect all programs which use the timer/counters.c) The simulation timing model is completely based onclock cycles (and does no longer try to function insome sort of "real-time"). As there is no real clockwithin the simulator, but the natural time unit isone instruction, the simulation time is incrementedby the CPI value (clock cycles per instruction) everyinstruction. I measured the CPI value in the real ECO32implementation: it's a horrible 18 cycles per instruction,yielding an instruction rate of about 2.8 MIPS. There isso much room for improvements...d) I changed the resolution of the simulation timers tomicroseconds. All timing constants had to be adapted andcan now be specified more precisely. They are automaticallyscaled to clock cycles (see above).e) The addressing scheme for peripherals of the same sorthas changed slightly. Virtual addresses of I/O devices havethe form 0xFxxyyrrr, where xx is the device type, yy is thedevice number, and rrr is the register within the device(must be a word address). This change could affect existentprograms which use more than one terminal.f) The ECO32 simulation got a new peripheral, called the"shutdown device". A write to address 0xFF100000 resultsin terminating the simulation run, with the lower 8 bitsof the data written supplied as exit status.
Go to most recent revision | Compare with Previous | Blame | View Log
