📄 osinit.doc
字号:
Copyright (c) 1991-1993, R.A. Burgess
OS INITIALIZATION
Initialization of MMURTL is not trivial. The 0.8x version of MMURTL loads from MS-DOS. We assume that no one wants to take a prototype operating system and overwrite their current boot environment. This means we must work within the constraints of MS-DOS, which actually is not that difficult. MS-DOS is a real mode, 16 bit operating system which means we must load MMURTL code and data into the real mode operating space where MS-DOS programs are normally loaded, then relocate prior to executing. MS-DOS is really nothing but a loader for the MMURTL operating system. Kind of expensive for a loader program, but I'm sure you'll find other uses for it.
MMURTL OS Loader Code
The loader code in version 0.8x is actually a very small 16 bit segment at the end of MOS.ASM.
In later versions (x0.89 to x0.95) it is separate program that loads MMURTL which is in MS-DOS executable format. Even though MMURTL is in the "EXE" format it can't be executed by MS-DOS. It is in that format because we used an MS-DOS compatible linker.
In version 1.0, MMURTL is a MMURTL run image with a separate program to load it from MS-DOS. THis means we built MMURTL V1.0 with DASM.
The loader code performs the following functions:
-Clears interrupts
-Sets the A20 Line Gate ON
-Relocates the OS Data segment to physical address 0
-Relocates the OS Code to the next physical page
above the OS data.
-Stores the location of the Global Descriptor Table
(GDT) in the GDT register.
-Store the location of the Interrupt Descriptor Table
(IDT) in the IDT register.
-JUMPs to the far address of the MMURTL 32 bit
initialization routines.
If you know something about MS-DOS and the 80x86 series of processors you know that we have overwritten the Interrupt Vector table and we are at the point of NO RETURN. No return to MS-DOS that is (until you reset your system).
What is the A20 Line Gate? It all stems back to IBMs initial PC-AT design. As most of you are aware (if you're programmers), the real mode addresses are 20 bits wide. This is enough bits to cover a full one megabyte. These address lines are numbered A0 through A19. If you use one more bit, you can address above 1MB. While in real mode, the A20 address line serves no purpose. I suppose it even caused some problems because they provided a way in hardware to turn it off (always 0). It seems that memory address calculations wrapped around in real mode (from 1MB to 0), and they wanted the same problem to exist in the AT series of processors.
My goal was not to discover why it existed, but to ensure it was turned on and left that way. I tried several methods, some which didn't work on all machines, and ended up sticking with the way it was documented in the orginal IBM-AT documentation. This seems to work on most machines, although some people may still have problems with it. It is controlled through a spare port on the 8042 keyboard controller (actually a dedicated microprocessor). If your machine doesn't support this method you may have to do some tweaking of the code. Meanwhile, back to the initialization (already in progess).
Our Global Descriptor Table (GDT) contains the entries that describe our protected mode environment (that we just jumped into). With one simple jump instruction (aided by our GDT and IDT entries) we have moved into a 32 bit, protected mode environment that opens up the real power of the 386/486 processors. This is the last we ever see of 16 bit code (no great loss at all).
At this point we are executing the OS initialization code which sets up the structures that MMURTL will need for messaging, program, and task management. Mostly this will be setting up simple linked lists that manage our pools (arrays) of structures such a Job Control Block (JCBs), Exchanges (Exchs), Link Blocks (LBs), Task State Segments (TSSs), and so on. Along with simply placing these structures into linked lists, we also initialize some of the data in them.
When all of the static linked lists for these initial structrures are setup, we set up our first valid TSS. This done by allocating and filling in our first Task State Segment (TSS). The TSS is simply a structure in memory that the the hardware and the OS share to keep track of a single task. Remember, a task is a single thread of execution. After the Monitor/OS task is created we move to the Debugger task. After this we can use some simple OS messaging (messaging cause task switches). We can allocate exchanges at this point.
Now we call InitMemMgmt. This sets up all of the tables for managing memory. There are no linked lists of any kind in the memory management code. It is all done with tables and arrays. This is because we are getting ready to make another JUMP (like the one into protected mode) that will take us into paged memory management. To do this PHYSICAL address MUST equal LINEAR addresses. Now you know why the OS code sts at the bottom.
Paged memory management uses the Intel paging harware built into the processor. It allows us to manage our entire linear memory as 4Kb pages. Memory management is discussed in great detail in the Architecure section, so I won't go into great detail here. There are a few rules that must be obeyed when going into or out of paged memory mode. When going into Paged memory mode you must have already defined an initial Page Directory (PD). The PD must contain valid entries for page tables that describe the physical addresses of the code and data you will be accessing as soon as you go into paged mode or you will get an immediate page fault. If the tables were not set up correctly, you will probably even end up with what is known as a "Double Fault" (and we're not even on the tennis courts). A double fault is caused by a mistake that creates a processor fault, then when the fault tries to execute it's handler, it gets another fault. Needless to say, if this happens, you will probably not even know it. Talk about a machine locking up on you - this is the ultimate. It's definately time for the reset button here...
If the tables are all set up properly, you will be in paged memory mode and ready to continue the last of the intialization. At this point we allocate memory for dynamic OS structures (Request Blocks, Exchanges, etc.) See Mos.asm.
After this is all done, we jump to the Monitor code which completes the initialization which proceeds to initialize all internal device drivers (displaying errors on the screen as it goes). Internal system services are done last.
At this point you are ready to load the CLI (or whatever your going to run).
---------------- End of Init Documentation --------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -