6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings Interrupts ◦ Section...

46
6. HAL and IDT ENGI 3655 Lab Sessions

description

Richard Khoury3 Hardware Abstraction Layer  Last week we created an interface to avoid using “int” and “char” because they might be too platform-dependant ◦ We want our OS to work on any hardware  But our OS does need to work with the hardware ◦ We can’t hide technical details and specificities forever

Transcript of 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings Interrupts ◦ Section...

Page 1: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

6. HAL and IDTENGI 3655 Lab Sessions

Page 2: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 2

Textbook Readings Interrupts

◦ Section 13.2.2 Hardware Abstraction Layer

◦ Section 22.3.1

Page 3: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 3

Hardware Abstraction Layer Last week we created an interface to avoid

using “int” and “char” because they might be too platform-dependant◦ We want our OS to work on any hardware

But our OS does need to work with the hardware◦ We can’t hide technical details and specificities

forever

Page 4: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 4

Hardware Abstraction Layer We’ll write declarations for the functions we

need that are not system-specific◦ Using our interface data types◦ Put them all in header files

We’ll write system-specific function implementations ◦ One version for each system we want to support◦ They all implement the same header file

We’ll pick the one we need◦ Dynamically at run time, by loading the right module◦ At linking time, picking the right object file

That is a hardware abstraction layer (HAL)◦ Our data type definitions are part of it

Page 5: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 5

Hardware Abstraction Layer Our initial HAL will have few parts HAL

◦ CPU Registers GDT IDT

◦ Basic memory-handling functions

Page 6: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 6

Hardware Abstraction Layer HAL.h

◦ Included in our main file◦ Defines the HAL initialization and shutdown

functionsextern uint32_t hal_initialize();extern uint32_t hal_shutdown();◦ The initialize function is the only one the kernel

calls; it will initialize everything else

Page 7: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 7

HAL CPU The initialize and shutdown functions activate and

deactivate the hardware◦ For now, our only hardware is the CPU

CPU.hextern uint32_t cpu_initialize ();extern void cpu_shutdown (); Registers.hstruct _R16BIT { uint16_t ax, bx, cx, dx, si, di, bp, sp,

es, cs, ss, ds, flags; uint8_t cflag;};

Page 8: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 8

HAL GDT The CPU initialization will create a new GDT

◦ To put the GDT under the control of our OS rather than the bootloader

◦ For now, just the same GDT as before, but written with C structures

Recall: the GDT descriptors are 8-byte structures, and we had five of them loaded into the processor◦ Also, specific to Intel processor; not part of the

interface, so included in i86.c, an implementation of CPU.h

Page 9: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 9

HAL GDT We’ll create a GDT structure to store the informationstruct gdt_descriptor {uint16_t limit;uint16_t baseLo;uint8_t baseMid;uint8_t access;uint8_t gran;uint8_t baseHi;

} __attribute__((packed)); We can create each of our five descriptors with these But then we need a place to store themstatic struct gdt_descriptor _gdt [MAX_DESCRIPTORS];

Page 10: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 10

HAL GDT Next we can define the

descriptors We can even define

constants to make the codemore readable

/*Bits 5-6: Privilege*/#define I86_GDT_DESC_RING0 0x0000 //_00_____#define I86_GDT_DESC_RING1 0x0020 //_01_____#define I86_GDT_DESC_RING2 0x0040 //_10_____#define I86_GDT_DESC_RING3 0x0060 //_11_____ And we create each descriptorgdt_set_descriptor(uint32_t i, uint64_t base, uint64_t limit, uint8_t access, uint8_t gran)

; code descriptordw 0FFFFh ; limit lowdw 0 ; base lowdb 0 ; base middledb 10011010b ; accessdb 11001111b ; granularitydb 0 ; base high

Page 11: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 11

HAL GDT Recall that loading the GDT into the CPU

requires two things A special structure representing the start

and size of the GDTtoc:

dw end_of_gdt - gdt_data - 1dd gdt_data

A special Assembly instructionlgdt [toc]

We’ll need to do that from C

Page 12: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 12

HAL GDT We’ll start by defining the GDT structure

struct gdtr {uint16_t m_limit;uint32_t m_base;

} __attribute__((packed));

static struct gdtr _gdtr;

_gdtr.m_limit = (sizeof (struct gdt_descriptor) * MAX_DESCRIPTORS)-1;

_gdtr.m_base = (uint32_t)&_gdt[0];

We’ll need an external Assembly function to load the GDT

extern void gdt_install ();

Page 13: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 13

HAL GDT Next, we create a new Assembly include file

◦ “GlobalCFunctions.inc”◦ Include it in our Kernel

Needs to work with our C function◦ Define the function to load the GDT

global _gdt_install ◦ Use the GDT data structure

extern __gdtr ◦ Note the extra _ character

Page 14: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 14

HAL GDT Then write the function in Assembly_gdt_install:

◦ Load the GDT into its special register using the special instruction

lgdt [__gdtr] ◦ Put the offset of the data segment in the registers

mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax

◦ Far-jump to the offset of the code segment jmp 0x08:endgdtendgdt: ret

Page 15: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 15

Hardware Abstraction Layer

HAL.h

i86.cHAL.c

CPU.h

main.c

Intel 80x86 processor with VGA-compatible video card

AMD-specific implementation files

System-specific implementation files

Hardware-independent

interface

Kernel

ENGI3655 computers

GDT.h/cIDT.h/c Mode7.c

Mode7.h

Data types(stdint.h)

Registers.h

Page 16: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 16

Interrupts OS needs to interact with the I/O hardware

◦ We already did some of that, making the bootloader interact with the screen (int 10h) and the disk (int 13h)

◦ For optimal performance, OS should be informed immediately when an I/O device needs attention

◦ When ready, run special I/O code OS needs to be immediately informed of

exceptions in programs◦ Illegal code: needs to substitute special

exception-handling code

Page 17: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 17

Interrupts Different functions, but both require the

same kind of action◦ Interrupt current process’s execution◦ Jump to special code and execute◦ Return if possible

Interrupts◦ Hardware Interrupts◦ Software Interrupts (traps)

Page 18: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 18

Hardware Interrupts

I/O Controller

Input or output ready, or error

Translate IRQ into Interrupt no.Send IRQ

Signal CPU’s Interrupt Request

line

Execute instruction

Check IR line

Execute instruction

Check IR line

Jump to location pointed in IDT

Save state information

Interrupt Handler Routine

Restore state information

Perform regular I/O functions

Programmable Interrupt Controller (PIC)

CPU

OS

Execute IHR

Page 19: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 19

Software Interrupts (Traps)Execute instruction

Exception!

Generate Interrupt number

Jump to location pointed in IDT

Save pointer to instruction

Interrupt Handler Routine

Return if possible

CPU

OS

Execute IHR

Page 20: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 20

Handling Interrupts Our OS doesn’t handle interrupts yet Try it: add an interrupt in the C kernel using

inline Assembly codeasm volatile ("int $0x3");

What happens?

Page 21: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 21

For This Lab... We will handle interrupts

◦ Build an interrupt descriptor table (IDT)◦ Write interrupt handlers

Page 22: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 22

Interrupt Vector Table A table of 256 entries

◦ Each one represents a kind of event that requires interrupting the CPU

◦ Each one is 4 bytes large: it consists of a memory address (2 bytes offset + 2 bytes segment)

When an interrupt vector (0x10 for example) is generated, the CPU looks up the entry (0x10 * 4 in the IVT) and jumps to that address in memory◦ That address should contain executable code to

handle whatever generated that interrupt

Page 23: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 23

Interrupt Vector Table But wait! Recall: before switching to protected mode,

our second-state bootloader disabled interrupts

And we never enabled them again afterwards

IVT is only accessible from Real Mode If we want to use interrupts from Protected

Mode, we’ll need to set up an Interrupt Descriptor Table

Page 24: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 24

Interrupt Descriptor Table Like the IVT, the IDT has 256 entries Each one is 8 bytes long Three different descriptor types

◦ Interrupt Gates: For I/O interrupts◦ Trap Gates: For exception interrupts

They are almost identical, except that interrupts are disabled by interrupt gate and not by trap gate, so IG is better for hardware interrupts

◦ Task Gates: For task-switching interrupts

Page 25: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 25

Descriptor StructureBits Interrupt

GateTrap Gate Task Gate

0-15 Interrupt Handler Routine address (0-15)

Not used

16-31 Code Segment Selector Task State Segment (TSS) Selector

32-35 Not Used36-39 Reserved (set to zero) Not used

Page 26: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 26

Descriptor StructureBits Interrupt

GateTrap Gate Task Gate

40-44Type

01110: 32 bits00110: 16 bits

01111: 32 bits00111: 16 bits

00101

45-46 Privilege Ring Level (00 highest – 11 lowest)47 0/1 = Segment is absent/present48-63 Interrupt Handler Routine

address (16-31)Not used

Page 27: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 27

Descriptor Structure Easy to represent as a C structure

◦ Remember our C data type interface from last week?

struct idt_descriptor {uint16_t baseLo;uint16_t sel;uint8_t reserved;uint8_t flags;uint16_t baseHi;

};

Page 28: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 28

Interrupt Descriptor Table 256 Interrupts defined by

Intel for the 80x86 0: Divide by 0 1: Debugger single step 2: Non-maskable interrupt 3: Debugger breakpoint 4: Overflow 5: Out of bounds 6: Undefined Operation

Code (OPCode) instruction 7: No coprocessor 8: Double fault 9: Coprocessor segment

overrun

10: Invalid Task State Segment (TSS)

11: Segment not present 12: Stack fault 13: General protection

fault 14: Page fault 15 is unassigned 16: Coprocessor error 17: Alignment check

(486+ Only) 18: Machine check

(Pentium/586+ Only) 19-31 are reserved by Intel 32-255 are free for

software use

Page 29: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 29

Interrupt Descriptor Table The IDT is a table of 256 interrupt descriptors

◦ We’ve already seen the idt_descriptor data structure

◦ An array of them is simply:static struct idt_descriptor_idt[i86_MAX_INTERRUPTS];

We’ll create two interface functions to the IDT◦ i86_install_ir: to modify an interrupt descriptor in

our table◦ i86_idt_initialize: to initialize the table with the

default 256 descriptors Each descriptor includes the address of the

interrupt handler routine

Page 30: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 30

Interrupt Handler Routine Sometimes called Interrupt Service Routine

(ISR) The function that dictates what to do when a

given interrupt occurs There are 256 interrupts

◦ 32-255 are free for software use – we won’t write complex functions for them

◦ We’ll need functions for int 0 to 31◦ For now, we’ll simply make a default handler

function that displays an error message and runs an endless loop

i86_default_handler()

Page 31: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 31

Installing a Handler Handler routine address is bits 0-15 and 48-63 of

interrupt descriptor structure

for (i=0; i<I86_MAX_INTERRUPTS; i++)i86_install_ir ((I86_IRQ_HANDLER)i86_default_handler);

i86_install_ir (I86_IRQ_HANDLER irq) {uint64_t uiBase = (uint64_t)&(*irq);_idt[i].baseLo = (uiBase & 0xffff);_idt[i].baseHi = ((uiBase >> 16) & 0xffff);}

Page 32: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 32

Installing a Handler The i86_install_ir function also needs you to specify

the interrupt number the function is for, the code segment (0x8) and the descriptor attributes ◦ Bits 40-44: Descriptor type◦ Bits 45-46: Privilege ring◦ Bits 47: Descriptor present/abscent◦ Values defined as constants in idt.h

#define I86_IDT_DESC_RING0 0x00 //_00_____#define I86_IDT_DESC_RING3 0x60 //_11_____

Page 33: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 33

Loading the IDT Like the GDT, the IDT is simply installed by loading

the base address and size into a special CPU register We’ll create a C structure

struct idtr {uint16_t limit;uint32_t base;

} __attribute__((packed));struct idtr _idtr;

Set them to the right values_idtr.limit= sizeof(struct idt_descriptor)*I86_MAX_INTERRUPTS-1;

_idtr.base = (uint32_t)&_idt[0]; And define an extern Assembly function

extern void idt_install();

Page 34: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 34

Loading the IDT The Assembly function is even simpler than

the one to load the GDTglobal _idt_installextern __idtr

_idt_install: lidt [__idtr] ret

Page 35: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 35

Loading the IDT Once it’s done, test it We already added an interrupt in the C

kernelasm volatile ("int $0x3");

What happens now?

Page 36: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 36

Interrupt Handler Routine Now we only have one common handler

routine that does nothing We’ll build better routines for our first 32

interrupts◦ Save the stack◦ Display a personalized message◦ Reload the stack

Clearly, we’ll need a good mix of Assembly and C functions

Page 37: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 37

Interrupt Handler Routine The routine called by an interrupt will be divided in

three parts Low Part

◦ Push error code on stack (if not done automatically)◦ Push interrupt number on stack◦ Jump to common part

Common Part◦ Push all registers on stack◦ Call top part

Top Part◦ Take action specific to interrupt

Low and Common are in Assembly, top in C

Page 38: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Six interrupts automatically push an error code before the Low Part

Interrupt Handler Routine

Richard Khoury 38

0: Divide by 0 1: Debugger single step 2: Non-maskable interrupt 3: Debugger breakpoint 4: Overflow 5: Out of bounds 6: Undefined Operation Code

(OPCode) instruction 7: No coprocessor 8: Double fault 9: Coprocessor segment

overrun

10: Invalid Task State Segment (TSS)

11: Segment not present

12: Stack fault 13: General protection

fault 14: Page fault 15 is unassigned 16: Coprocessor error 17: Alignment check

(486+ Only) 18: Machine check

(Pentium/586+ Only) 19-31 are reserved by Intel 32-255 are free for

software use

Page 39: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 39

Interrupt Handler Routine (low part) Structure of Low Part (for interrupt #)global _isr#

_isr#: cli push byte 0 (if not done

automatically) push byte # jmp isr_common_stub The 0 byte is a dummy error code

◦ Not needed for traps

Page 40: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 40

Interrupt Handler Routine (common) Structure of Common Part (for all int)isr_common_stub:

◦ Push all registers pusha push (ds, es, fs, gs)

◦ Load the kernel data segment descriptor mov ax, 0x10 mov (ds, es, fs, gs), ax

◦ Call the function mov eax, esp push eax mov eax, _fault_handler call eax

◦ Pop all registers reverse order and far-return pop …

add esp, 8 iret

Page 41: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 41

Interrupt Handler Routine (top part) Top Part is a C functionvoid fault_handler(){

◦ Do something specific to each interrupt} Declared as “extern” in the Assembly code Problem: how does the function know which

interrupt number has been called?

Page 42: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 42

Interrupt Handler Routine Answer: It has been pushed on the stack by the

Low Part We can access it in C with a register data

structure (Registers.h)struct isrregs{ uint32_t gs, fs, es, ds; uint32_t edi, esi, ebp, esp, ebx, edx,

ecx, eax; uint32_t int_no, err_code; uint32_t eip, cs, eflags, useresp, ss;

};

eax-------------gs, fs, es, ds-------------pusha(edi, esi, ebp, esp, ebx, edx, ecx, eax) -------------Interrupt number-------------Error code-------------eip, cs, eflags, useresp, ss

Top of stack

These were pushed automatically by the CPU before our Low Part

Page 43: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 43

Interrupt Handler Routine (top part) Now we can pass it to our Top Part and use itvoid fault_handler(struct isrregs *r){

◦ Do something specific to each r->int_no} But what to do?

◦ We need a generic default behaviour (displaying a message)

◦ We want personalized default messages for the first 32 interrupts

◦ We want to be able to easily “plug in” new custom interrupt handlers for the first 32 interrupts

Page 44: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

How to plug in new ISR?◦ An ISR is a function – it has an address◦ So we’ll keep track of ISR addresses

void *idt_routines[32];◦ Then we can plug in an ISR by putting in the function’s

address at the entry in the arratvoid i86_install_handler(uint32_t idt, void (*handler)(struct isrregs *r))

{ idt_routines[idt] = handler; }◦ We can also unplug an ISR by setting that entry in the array

to 0void i86_uninstall_handler(uint32_t idt){idt_routines[idt] = 0;}

Interrupt Handler Routine (plug in)

Richard Khoury 44

Page 45: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Our top part can check if there is a custom function installed for an interrupt by checking the array

void (*handler)(struct isrregs *r);handler = idt_routines[r->int_no];if ( (uint32_t)handler != 0 ){ handler(r);}else{ default behaviour } So don’t forget to initialize all entries to 0!

Interrupt Handler Routine (plug in)

Richard Khoury 45

Page 46: 6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section 13.2.2  Hardware Abstraction Layer ◦ Section 22.3.1.

Richard Khoury 46

Lab Assignment Add the HAL to your kernel Write the three-part Interrupt Handler

Routines for the first 32 interrupts◦ Don’t forget to install your new handlers in the

IDT instead of the default handler! Test with inline Assembly interrupts and

make sure it displays the right message!◦ When you compile the IDT you will get a “cast

from pointer to integer” warning – that’s normal