Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

17KB

Developing Your Own 32-Bit Operating System — Chapter-17: Introduction to the Source Code

  • Source: /library/Developing Your Own 32-Bit Operating System/source-file.pdf
  • PDF pages: 347–356
  • Pages without text: 347, 348, 349, 356
  • Note: Includes the Part IV divider plate and its blank verso before the chapter.

29q| Part IV ■ The Operating System Source Code This chapter discusses each of the important source files, some of the things that tie all of the source files together, and how to build the operating system using the tools included on the CD-ROM. One of my goals was to keep the source code organized in an easy-to-understand fashion. I hope I've met this goal. You may find some of the source files rather large, but most of the dependent functions will be contained in the file you are viewing or reading. You won't have to go searching through hundreds of files to find a three-line function. Comments in the Code You'll find out that I make a lot of comments in my source code. By including many com- ments, I can, a year or two later, go back and figure out what I did. It's not that I couldn't actually figure out the code without the comments; I just expend the time up front instead of later. In fact, sometimes I write the comments describing a small block of code before I actu- ally code it. Doing so helps me think. Calling Conventions I bring up the topic of calling conventions here because, as you look through the code, you will see that much of the assembler looks almost as if it were generated by a compiler. When a human writes this much assembler (and the code is to be interfaced with assembler generated by a compiler), the human becomes a compiler of sorts. Many of the lower-level procedures use registers to pass data back and forth. Quite a few of them, however, use the stack just as a compiler would. Two conventions are used throughout the operating system. The most prominent and the preferred method is pushing parameters left to right, with the called procedure cleaning the stack. The other is a mangled version of what you'd find in most C compilers for functions with an ellipsis (...). I call it mangled ‘be- cause the arguments are still pushed left to right, but the number of variable arguments is passed in the EDI register. The caller cleans the stack in this convention. Organization The MMURTL source code is organized in a modular fashion. Each logical section is con- tained in one file (or more) that is either C or assembler source code. There are also header files for the C source, and there are INCLUDE files for the assembler that tie publics, common variables, and structures together. All source files are located in one directory. There are 29 main source files (excluding header and include files). A brief description of each of the main source files follows:

Chapter 17 ■ Introduction to the Source Code MOSIDTASM This defines the basic Interrupt Descriptor Table (IDT). The IDT is a required table for the Intel processors. This is really just a data position holder in the data segment, because the entries in the IDT are done dynamically. The position of this file in relationship to the others is critical because the offset to the IDT must be identified to the processor. The IDT is the first file in the source, which means its data will be at the lowest address. In fact, it ends up at physical and linear address 0. MOSGDT.ASM This defines the Global Descriptor Table (GDT). This table is also a required table for the Intel processors when they run in protected mode. The GDT is 6K in size. Several selector entries are predefined so you can go directly into protected mode. This ends up at address 800h physical and linear. The position of this file is also critical, because the file is identified to and used by the processor. This must be the second source file in the assembler template file. MOSPDRJVSM This is also a data definition file that sets up the operating system's page directory and first page table. This file should also remain in its current order because I have hard-coded its address in some source modules. MPublics.ASM This is also a table, but it is not used by the processor. This defines the selector entries for all MMURTL public calls. MAIN.ASM This is the first assembler file that contains code. The operating system entry point is located here (the first OS instruction executed). Also some data is defined here. This file should be left in the order I have it in. The ordering for the remainder of the modules is not as important. On the other hand, I haven't tried playing “musical source files” either. Leaving them in their current order would probably be a good idea. Keyboard.ASM The keyboard source goes against my own rule of not combining a device driver with a system service. Keyboard.ASM was one of the first files written, and it works rather well, so I am reluctant to begin rewriting it (although I will, undoubtedly, someday). System services in assembly language are not fun to write or maintain. Chapter 25, “Keyboard Code,” explains all the mysteries behind this table- driven piece of work. Video ASM Video.ASM code and data was also one of the first pieces I wrote. You have to see what you're doing, even in the earliest stages of a project. Chapter 26, “Video Code,” goes into detail on this file's contents. Debugger.ASM This file contains the bulk of the debugger logic. Debugging is never fun when you have to do it at the assembler level. Debugging a debugger is even less fun. UASM.C This file is the debugger disassembler. It is a table-driven disassembler used to display instructions in the debugger. It's not very pretty, but it's effective and accurate. H

330 Part PV ■ The Operating System Source Code DevDrvr-ASM The device-driver interface code and data are contained in this file. This provides the re-entrancy protection and also the proper vectoring (indirect calling) of device-driver functions. Floppy.C Floppy disk device drivers are much harder to write than IDE hard disk drivers. This is one complicated driver. It seems to me that hardware manufacturers could be a little more compassionate toward software people. The reasoning behind controlling the drive motors separately from the rest of the floppy electronics still baffles me. HardlDE.C The IDE hard disk device driver was fairly easy to write. I was sur- prised. You will still see remnants of MFM drive commands in here because I started with that. I think it still works with MFM drives, but I don't have any more to test it. If you have MFM drives, you're on your own. RS232.C This file contains the RS-232 UART driver. It drives two channels, but it can be modified for four, if necessary. It supports the 16550 but only to enable the input buffer (which helps). Parallel. C The simple parallel port driver is contained here. FSys.C This is an MS-DOS FAT-compatible file system. It has only the necessary calls to get the job done. It provides stream access as well as block access to files. JobC.C The program loader and most of the job-related functions are handled in this file. JobCodeASM Lower-level job functions and supporting code for functions in JobC.C are contained in this file. TmrCodcASM The interrupt service routine for the primary system timer — along with all of the timer functions, such as Sleep ( ) — are in this file. IntCode.ASM Interrupt Service Routine (ISR) handling code can be found here. RQBCodcASM Request block management code is in this file. DMACodcASM In many systems, when device driver writers need DMA, they must handle it themselves. This file has routines that handle DMA for the program- mer writing device drivers. They need only to know the channel, how much to move, and the mode. Device driver writers will appreciate this. NumCnvrt.ASM This is some code used internally to convert numbers to text and vice-versa. MemCodcASM The code memory allocation, address aliasing, and management of physical memory can be found in this file. SVCCodcASM System service management code such as RegisterSvc( ) is in this file. MiscCodcASM This file has all the little things you need, but you never know where to put. High-speed string manipulation and comparison, as well as port I/O support, is in this file.

Chapter 17 ■ Introduction to the Source Code Kernel ASM All of the kernel calls and most of the kernel support code is in this file. Chapter 18, “Kernel Code,” discusses the kernel and presents the most important pieces of its code along with discussions of the code. ExceptASM Exception handlers such as those required for processor faults are in this file. Most of them cause you to go directly into the Debugger. InitCodcASM This file has all the helper routines that initialize most of the dynamic operating-system functions. Monitor.C The monitor program is contained in this file. It provides a lot of the OS functionality, but it really isn't part of the operating system. You could replace quite easily. H Building MMURTL MMURTL requires the CM32 compiler (included on the CD-ROM) for the C source files and the DASM assembler (also included on the CD-ROM). One MS-DOS batch file (MakeALL.BAT) will build the entire operating system. This takes about 1.5 minutes on a 486/33. Each of the C source files is turned into an assembler file (which is what the CM32 compiler produces). All of the assembly language source files are then assembled with DASM. DASM produces the operating system RUN file. The RUN file is in the standard MMURTL Run file format, which is described completely in Chapter 28, “DASM: A 32-Bit Intel-Based Assembler.” The only two MS-DOS commands you need are CM32 and DASM. An example of compiling one of the source files is the following: C:\MMURTL> CM32 Monitor.C After all the C source files are compiled, you use the DASM command, as follows: C:\MMURTL> DASM MMURTL. ATF It's truly that simple. If you want an error file, specify /E on the command line after the name. If you want a complete listing of all processor instructions and addresses, specify / L on the command line after the name. The following is the Assembler Template File (ATF). This file is required to assemble complex programs with DASM. The assembler is discussed in detail in Chapter 28, but you don't need to read all the DASM documentation to build MMURTL. ; Assembler Template File for MMURTL V1.0 .DATA ; These first 5 INCLUDES MUST be in this order!!!! .INCLUDE MOSIDT.ASM ; Defines the Interrupt Descriptor Table .INCLUDE MOSGDT.ASM ; 6K for GDT @ 00000800h Physical (1.5 Pages, 6K) $

I
332 Part IV ■ The Operating System Source Code .INCLUDE MOSPDR.ASM .INCLUDE MPublics.ASM .INCLUDE MAIN. ASM ; OS Page Directory & 1st Table (8k) ; Indirect calling address table ; Main OS code and some data & START address ; Ordering for the remainder of the modules is not as important. ; An asterisk (*) by the include file indicates it originates as ; a C source file and must be compiled first with ; CM32 (no switches needed). INCLUDE Keyboard. ASM Keyboard ISR and Service INCLUDE Video. ASM Video code and data INCLUDE Debugger. ASM Code & Data for Debugger INCLUDE UASM.ASM

  • Code & Data for Debugger Disassembler INCLUDE DevDrvr.ASM Code and Data for Device Driver Interface INCLUDE Floppy. ASM
  • Floppy Device Driver INCLUDE HardlDE.ASM
  • IDE Disk Device Driver INCLUDE RS232.ASM
  • Serial Comms Device Driver INCLUDE Parallel. ASM ; Parallel Comms Device Driver INCLUDE FSys.ASM
  • File System Service INCLUDE JobCode.ASM Additional Job management INCLUDE JOBC.ASM
  • Loader/Job handling Code & Data INCLUDE TmrCode.ASM Timer Code INCLUDE IntCode.ASM ISR handling code INCLUDE RQBCode.ASM Request Block Code INCLUDE DMACode.ASM DMA Handling Code INCLUDE NumCnvrt.ASM Maybe Move to DLL later or can it INCLUDE MemCode.ASM Memory management code INCLUDE SVCCode.ASM System Service management code INCLUDE MiscCode.ASM Misc. code (string, array, I/O support) INCLUDE Kernel. ASM Kernel code INCLUDE Except. ASM Exception handlers INCLUDE InitCode.ASM Initialization support code INCLUDE Monitor. ASM
  • The monitor code & data .END If you've read all of the chapters preceding this one, you'll understand that all MMURTL pro- grams are comprised of only two segments — code and data. The order of the assembler files in the ATF file determines the order of the data and code. As each piece of code is assembled, it is placed into the code segment in that order. The same is true for the data as it is encountered in the files. Using Pieces of MMURTL in Your OS You'll find that most of the source code is modular. For instance, you can take the file system code (FSYS.C) and turned it into a free-standing program with little effort. I built each section of code in modular pieces and tried to keep it that way. Even though I use CM32 to compile the C source files, the code can be compiled with any ANSI C compiler. You will, no doubt, use another compiler for your project. You'll find that many items in MMURTL depend on the memory alignment of some of the structures. This is one thing you should watch. CM32 packs all structure fields completely. In fact,CM32 packs all variables with no additional padding.

Chapter 17 ■ Introduction to the Source Code fTT7 Using Pieces of MMURTL in Other Projects Some of you may find some of the code useful in projects that have absolutely nothing to do with writing an operating system. The same basic warning about the alignment of structures applies. The assembler INCLUDE files that define all the structures actually define offsets from a memory location. This is because DASM doesn't support structures, but you would have no problem setting them up for TASM or MASM. The calling conventions (described earlier) may get you into trouble if you want to use some of the assembler routines from a high-level language. If your C compiler allows it, you can declare functions as Pascal functions (some even use the old PLM type modifier), and they will work fine. Otherwise, you can calculate the correct offsets and fix the EQU statements for access where a C compiler would put them on the stack. You would also need to remove the numbers following the RET and RETF statements so that the caller could clean the stack, as is the C con- vention.

Powered by TurnKey Linux.