⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysprg.doc

📁 MMURTL(tm) Computer Operating System Ver x0.8, source code.
💻 DOC
📖 第 1 页 / 共 3 页
字号:
Copyright 1991-1993  R.A. Burgess

Systems Programming

This section is aimed squarely at the MMURTL systems programmer.  It describes writing message based system services and device drivers.  Use of the associated OS calls are described in a generic format that can be understood by C, Pascal, and Assembly language programmers. 

System Programming deals with writing programs that work directly with the operating system and hardware, or provide services to application programs.

System programers require a better understanding of the operating system.  Application programmers shouldn't have to worry about hardware and OS internal operations to accomplish their tasks.  They should have a basic understanding of multitasking and messaging and be able to concentrate on the application itself.  

If you want (or need) to build device drivers or system services, you should make sure you understand the material covered in MMURTL Architecture and Applications Programming sections.  They contain theory and examples to help you understand how to access services, use messaging, and memory management operations.


Writing Message Based System Services

System Services are installable programs or OS included services that provide system-wide message based services for application programs (and even other services).  MMURTL is a message based operating system and is designed to support programs in a client-server environment.  People always associate the term client-server with a separate computer system that is the server for client workstations.  MMURTL takes this down to a level right inside on a single processor.  A program that performs a specific function or group of functions can be shared with two or more programs is a system service.  This is the basis behind the Request and Respond messaging primitives.  Client programs make a Request, the service does the processing and Responds.  It can be compared to Remote Procedure Calls with a twist.   The file system and keyboard service are prime examples of message based system services.   

The basic steps to initialize your service and start serving requests are listed below:

1) Initialize or allocate any resources required:
	- Allocate additional memory (if required)
	- Allocate Main Service exchange (customers come here)
	- Allocate additional exchanges (if needed)
	- Create addtional tasks if required
	- Anything else you need to get ready for business 
	  (Initialize variables etc.)

2) Call RegisterSVC with your name and Main Service Exchange

3) Wait for messages, service them, then Respond.

Sound simple?  It really is.  Below is the world's simplest system service for the MMURTL OS.  It's purpose it to hand out unique numbers to each request that comes in.  Not real useful, but a good clean example.  The service name is "NUMBERS " (note than name is space padded).  Service names ARE case sensitive.  The service will get a pointer in the request block (pData1) of where the user wants the number returned.

/* Simple System Service */

struct RqBlk {  
      ..
      ..
      ..
	}

struct pRqBlk *RqBlk;
unsigned long NextNumber = 0;  	/* First number */
unsigned long MainExch;
unsigned long Message[2];

void main(int argc, char *argv[])
{
unsigned long error;

  error = AllocExch(&MainExch);	/* get an exchange */
  if (error) 
    exit (error);

  error = RegisterSvc("NUMBERS ", MainExch);
  if (error) 
    exit (error);

  while (1) {		/* forever */

    error = WaitMsg(MainExch, Message); /* Exch & pointer */
    if (!error) {
      pRqBlk = Message[0];

    error = Respond(dRqHndl, 0): dError
  }

}



Writing Device Drivers

Device Drivers control or emulate hardware on the system.  Disk drives, comms ports (serial and parallel), tape drives, RAM disks, and network frame handlers are all examples of devices (or pseudo devices) that require device drivers to control them.  MMURTL has standardized entry points for ALL devices on the system.  

MMURTL is built on layers.  The device drivers are the closest layer to the OS.  You should not confuse device drivers with message based system services.  Device drivers are accessed via call gates (transparent to the applications programmer) which allow callers to easily (and rapidly) access code with a procedural interface from high level languages (e.g., C and Pascal), or from by simply "pushing" parametrs on the stack in assembler. 

MMURTL provides several built-in device drivers including Floppy Disk, Hard Disk, Basic Video, Keyboard, and comms (serial and parallel)

There are two basic types of devices; RANDOM and SEQUENTIAL oriented.  Random oriented devices are things like disk drives and RAM disks that require the caller to tell the driver how much data to read or write as well as WHERE the data is on the device. Network frame handlers may also be random because a link layer address is usually associated with the read and write functions, although they may be sequential too (implementation dependent).  Some types of tape drives allow reading and writing to addresses (sectors) on the tape and therefore may also be random devices.  Sequential devices are things like comms ports, keyboard, and sequential video access (ANSI drivers etc.)  Most byte oriented devices tend to be sequential devices because that don't have a fixed size block and are not randomly accessed (e.g., they don't have specific address locations of data). 

The MMURTL standard Device Driver interface can handle BOTH sequential and random devices with fixed OR variable block/sector lengths.  The interface is non-specific.

All device drivers use a Device Control Block (DCB).  The device driver defines and keeps the DCB in it's memory space (which actually becomes the OS memory space when you load it).  When a device driver installs, it passes in a pointer to it's DCB. If a device driver controls more than one device it will pass in a pointer to an array of DCBs. Things like Device name, Block Size, and Device Type are examples of the fields in a DCB.  Each device driver must also maintain (in it's data area) all hardware specific data (variables) needed to control and keep track of the state of the device.

Device Driver Theory

MMURTL is a protected mode, paged memory OS that uses 2 of the 4 possible protection levels of the 386/486 processors.  The levels are 0 and 3 and are referred to as System (0) and User (3). We have made it rather painless to build fast, powerful, device drivers (and we have even gone into substantial detail for beginners). 

Device drivers must have access to the hardware they control.  Device drivers have complete access to processor I/O ports for their devices without OS intervention.  Only System code (protection level 0) is allowed processor port I/O access.  This means message/request based system services and application code (both at User level 3) can NOT access ports at all, or a processor protection violation will occur.  For example, the file system is at user level (3). It does NOT directly access hardware. The device driver builder must not access ports other than those required to control their hardware.

Device drivers must NOT attempt to directly control the system DMA, Timer hardware, interrupt vectors, the PICUs, or any OS structures.  MMURTL provides a complete array of calls to handle all of the hardware which ensures complete harmony in MMURTL's real-time, multitasking, multi-threaded environment, while providing a fair amount of hardware independence.  MMURTL takes care of synchronization of system level hardware access so device driver programmers don't have to worry about ir (or do it).  Those that have written device drivers on other systems will appreciate this concept. 

Building Device Drivers

When the device driver is installed by the loader (or is inlcuded in the OS code at build time) it has to make a system call to set itself up as a device driver in the system.  Other system calls may also have to be made to allocate or initialize other system resources it requires before it can handle it's device.

Device drivers can be anything from simple disk device emulations (e.g., RAMDISK), all the way up to handling complex devices such as hard drives, SCSI ports, or network frame handlers (i.e. network link layer devices).

The call to setup as a device driver is InitDevDr.  With InitDevDr, you provided a pointer to your Device Control Blocks (DCB) after you have filled it (or them) in with the required information.  The DCB is shared by both the device driver and OS code.

Before calling InitDevDr you will most likely have to allocate other system resources and possibly even set up hardware interrupts that you will handle from your device.  Additional system resources available to device drivers are discussed later in this section.

The device driver looks (and is programmed) like any application in MMURTL.  It has a main entry point which you specify when writing the program. In C this would be "main" or in Pascal it's the main program block.  In assembler this would be the 'START' entry point specified for the program.  This code is immediately executed after loading the driver (just like any other program).  This code will only execute once to allow you to initialize the driver.  The main entry point will never be called again.  This will generally be a very small section of code (maybe 30 lines). 

How Callers Reach Your Driver

All device drivers are accessed via one of 3 public calls defined in the OS.  You will have functions in your driver to handle each of these calls.  When you fill in the DCB you will fill in the addresses of these 3 entry points that the OS will call on behalf of the original caller.

Your driver program must interface properly with the 3 public calls. You can name them anything you want in your program, but they must have the same number and type of parameters (arguments) as the PUBLIC calls defined in the OS for all device drivers.  The OS defines the 3 following PUBLIC calls:

	1) DeviceInit (parameter list described later)
	2) DeviceOp (parameter list described later)
	3) DeviceStat (parameter list described later)

The parameter lists and what the functions are expected to do are discussed in detail in a later section.  Your functions may, or may not, have to do anything when called depending on the device you are controlling, but they MUST at least accept the calls and return a status code of 0 (for no error) if they ignore it.  When programs call one of these PUBLIC calls, MMURTL does some housekeeping and then calls your specified function.  

Device Driver Setup and Installation

The "main" section of your device driver must make certain calls to set up and install as a driver. The generic steps are described below. Your actual calls may vary depending on what system resources you need.

A) Initialize or allocate any resources required:
	- Allocate any additional memory (if required)
	- Allocate exchanges if needed for messaging from
       a second task or the ISRs (see the floppy device
	  driver for an example of a device driver with 
	  a separate task to handle hardware interrupts).
	- Setup Interrupt Service Routines (if needed)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -