1 / 14

Tips for R3: Process Initialization

Tips for R3: Process Initialization. When we create processes to represent our 5 test procedures we must correctly initialize its context by placing values into its stack, data segment and extra segment.

zander
Download Presentation

Tips for R3: Process Initialization

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Tips for R3: Process Initialization • When we create processes to represent our 5 test procedures we must correctly initialize its context by placing values into its stack, data segment and extra segment.

  2. 1) We need to define a special global structure to represent the “context” of a process which is automatically saved onto the processes stack when the process is interrupted: typedef struct context { unsigned int BP, DI, SI, DS, ES; unsigned int DX, CX, BX, AX; unsigned int IP, CS, FLAGS; } context; context *context_p;

  3. Recall that: • When an interrupt occurs the HARDWARE saves the flags register (PSW), CS (code segment), IP (instruction pointer) onto the stack in this order!!!!! • Next because of the interrupt keyword being specified in the implementation of our interrupt handler: void interrupt sys_call_handler() • Assembler instructions will be added to the routine to automatically save the following registers onto the stack: AX, BX, CX, DX, ES, DS, SI, DI, AND BP • Code will also be automatically added at the end of the routine to restore these!!!!!

  4. We need to set up the initial context of each process by initializing the contents of its stack. • The declaration of the PCB should contain a pointer to a stack of size 1k, which should initially be initialized to all zeros!! The stack pointer should be initialized to the “highest” address in your stack (stack address +1024) (remember that the stack grows from high memory down.) • We need to store the initial context of the process in the top portion of the stack!

  5. Pcb.stack_p = pcb.stack_base + pcb.stack_size – sizeof(context); Context_p = (context *)pcb.stack_p; context_p->DS = _DS;context_p->ES = _ES;context_p->CS = FP_SEG(&testn_R3);context_p->IP = FP_OFF(&testn_R3);context_p->FLAGS = 0x200

  6. Process cause interrupts by: • Each process will voluntarily give up control of the CPU using a call to “sys_req” which will generate a system call interrupt. Processes call “sys_req” with two possible op_code values: • IDLE: which will return the process to the ready queue • EXIT: which is a request to terminate the process, and free the PCB. • This call to sys_req will result in an interrupt being generated which should be processed by our “sys_call_hander”

  7. Setting up “sys_call_handler” • During initialization you must set the “sys_call” vector to contain the address of your interrupt handler. It has the prototype: int sys_set_vec (void (*handler)()); The single parameter handler is a pointer to your system call handler. If your handler has the name sys_call, then it should have the prototype: void sys_call (void); Your call to sys_set_vec, which should occur during initialization, will have the form sys_set_vec(sys_call);

  8. Sys_req passes a single parameter to your sys_call_handler, via the stack (previous stack contents) Buffer length pointer parameter (*count) Buffer address parameter (*buffer) Device_id parameter Op_code parameter Flag CS IP AX BX CX DX ES DS SI DI BP We will need to retrieve the contents of the 1st four parameters to identify the type of request made by the calling process.

  9. To access these parameters we define another structure similar to the “context” structure: typedef struct params {int op_code;int device_id;byte *buf_addr;int *count_addr;} params;

  10. We gain access to the op_code by: The stack structure must be a named type. A pointer to this structure is also required: params *param_p; Finally, the following assignment will set the pointer to the address of the actual stack frame to be accessed: param_p = (params*)(MK_FP(_SS,_SP) + sizeof(context)); It is now possible to refer to the op_code value as param_p->op_code.

  11. We then need to interpret this code and take the appropriate action! • First save a copy of the SS and SP and switch to another temporary stack. (local variables should be declared as static) #define SYS_STACK_SIZE 200 byte sys_stack[SYS_STACK_SIZE]; unsigned short ss_save; unsigned short sp_save; unsigned short new_ss; unsigned short new_sp; /* in syscall*/ ss_save = _SS; sp_save = _SP; new_ss = FP_SEG(sys_stack); new_sp = FP_OFF(sys_stack); new_sp += SYS_STACK_SIZE; _SS = new_ss; SP = new_sp;

  12. set param_p point to the correct place: cop->stack_ptr = (unsigned char *) MK_FP(_SS, _SP);param_p = (params *)(cop->stack_ptr + sizeof(context)); • if parm_p->op_code is IDLEchange the state of cop to readyinsert cop to ready queue by priority • else if param_p->op_code is EXITdelete the pcbset cop to NULL • else set context_p->AX to error code. • call dispatch()

  13. In the dispatcher • Automatically saves the data registers onto the temporary stack for the calling process • Then a complete outline for the dispatcher is:

  14. if sp_save is null, ss_save = _SS sp_save = _SP remove the PCB at the head of the ready queue if a PCB was found set cop to this PCB set _SS and _SP to the PCB's stack pointer else set cop to NULL set _SS to ss_save set _SP to sp_save end if "return from interrupt"

More Related