Presentation is loading. Please wait.

Presentation is loading. Please wait.

Principles of Computers 21st Lecture

Similar presentations


Presentation on theme: "Principles of Computers 21st Lecture"— Presentation transcript:

1 Principles of Computers 21st Lecture
Pavel Ježek, Ph.D.

2 Back To Simplified View: Concept of an HBA (Host Bus Adapter)
Code executed by CPU: MOV EAX, h ; load constant MOV [3F6BFC10h], EAX ; store EAX content CPU 32-bit physical address space Code executed by CPU: MOV AL, 05h ; load 8-bit constant MOV [ h], AL ; 8-bit store addr 0 memory controller (refresh) comm. protocol: 32-bit address space 1 GB DRAM module memory bus MWr addr $100 memory bus comm. protocol: 32-bit address space 512 MB DRAM module device A zoomed view: addr 1 1 B register Y MWr 2 B register X reg Y system bus $ reg X $FFFFFFFF = 232-1 4 GB device B $ addr 8 1 B register device C = bus 2 controller (HBA) bus 2 $ 512 MB $5FFFFFFF addr 7 1 GB $3FFFFFFF = 230-1 1 B register addr 13 addr 1 device D device E $ = 0 1 B register 1 B register 1 B register

3 Graphics Card HCI

4 8-bit Sound Card HCI DAC Address decode Playback logic Data W/O reg
sound buffer (100kB – MB) RWAddr reg ... $F $F DD $F $F $F $F DAC PlayAdr reg auto increment auto increment Loudspeaker image (CC Attribution) authored by Sallee Design,

5 16-bit Sound Card HCI (Byte Ordering as Part of HCI)
Address decode Playback logic Data W/O reg MSB LSB sound buffer (100kB – MB) RWAddr reg ... $F DD $F $F $F $F $F DAC PlayAdr reg auto increment on MSB write (LSB and MSB must be written at once during a single 16-bit write [if on 16-bit system bus] or LSB must be written first and MSB second if on 8-bit system bus) auto increment Loudspeaker image (CC Attribution) authored by Sallee Design,

6 16-bit Sound Card HCI DAC Address decode Playback logic Data W/O reg
MSB LSB sound buffer (100kB – MB) RWAddr R/W reg ... $F DD $F $F AA $F $F $F DAC PlayAdr reg auto increment auto increment Loudspeaker image (CC Attribution) authored by Sallee Design,

7 16-bit Sound Card HCI DAC Address decode Playback logic Data W/O reg
MSB LSB sound buffer (100kB – MB) RWAddr R/W reg ... $F DD $F $F AA $F CF $F $F DAC PlayAdr reg auto increment Config R/W reg ▪sample rate ▪sample size ▪mono/stereo auto increment Loudspeaker image (CC Attribution) authored by Sallee Design,

8 16-bit Sound Card HCI DAC Address decode Playback logic Data R/W reg
MSB LSB sound buffer (100kB – MB) RWAddr R/W reg ... $F DD $F $F AA $F CF $F CT $F DAC PlayAdr reg auto increment Config R/W reg ▪sample rate ▪sample size ▪mono/stereo auto increment Control W/O reg ▪play/stop ▪record/stop Loudspeaker image (CC Attribution) authored by Sallee Design,

9 16-bit Sound Card HCI DAC Address decode Playback logic Data R/W reg
MSB LSB sound buffer (100kB – MB) RWAddr R/W reg ... $F DD $F $F AA $F CF $F CT $F ST DAC PlayAdr reg auto increment Config R/W reg ▪sample rate ▪sample size ▪mono/stereo auto increment Control W/O reg ▪play/stop ▪record/stop Status R/O reg ▪play position ▪playing? ▪recording? Loudspeaker image (CC Attribution) authored by Sallee Design, Base address: $F

10 PIO (Programmed I/O) – Reading 1 Byte From Controller
6502: LDA ctrl_data_reg_address STA buffer_address

11 PIO (Programmed I/O) 6502: 1 tx = read/fetch load instruction opcode
LDA ctrl_data_reg_address STA buffer_address 1 tx = read/fetch load instruction opcode 1 tx = read data from controller’s data register 1 tx = read/fetch store instruction opcode 1 tx = write data from A to buffer in memory = 4 tx

12 PIO (Programmed I/O) 6502: 1 tx = read/fetch load instruction opcode
LDA ctrl_data_reg_address STA buffer_address 1 tx = read/fetch load instruction opcode 1 tx = read data from controller’s data register 1 tx = read/fetch store instruction opcode 1 tx = write data from A to buffer in memory = 4 tx 6502: LDA addr = 3 byte instruction STA addr = 3 byte instruction 3 tx = read/fetch load instruction opcode 1 tx = read data from controller’s data register 3 tx = read/fetch store instruction opcode 1 tx = write data from A to buffer in memory = 8 tx

13 PIO (Programmed I/O) 6502: 1 tx = read/fetch load instruction opcode
LDA ctrl_data_reg_address STA buffer_address 1 tx = read/fetch load instruction opcode 1 tx = read data from controller’s data register 1 tx = read/fetch store instruction opcode 1 tx = write data from A to buffer in memory = 4 tx 6502: LDA addr = 3 byte instruction STA addr = 3 byte instruction 3 tx = read/fetch load instruction opcode 1 tx = read data from controller’s data register 3 tx = read/fetch store instruction opcode 1 tx = write data from A to buffer in memory = 8 tx e.g. system bus: 1 byte/tx 2 cycles/tx 1 MHZ cycles = 0,5 MB/second = x B/s PIO transfer = (x / 8) B/s = 62,5 kB/s

14 PIO (Programmed I/O) Solution: DMA 6502:
LDA ctrl_data_reg_address STA buffer_address 1 tx = read/fetch load instruction opcode 1 tx = read data from controller’s data register 1 tx = read/fetch store instruction opcode 1 tx = write data from A to buffer in memory = 4 tx 6502: LDA addr = 3 byte instruction STA addr = 3 byte instruction 3 tx = read/fetch load instruction opcode 1 tx = read data from controller’s data register 3 tx = read/fetch store instruction opcode 1 tx = write data from A to buffer in memory = 8 tx e.g. system bus: 1 byte/tx 2 cycles/tx 1 MHZ cycles = 0,5 MB/second = x B/s PIO transfer = (x / 8) B/s = 62,5 kB/s Solution: DMA

15 CPU Is Master / Devices Are Slaves
Code executed by CPU: MOV EAX, h ; load constant MOV [3F6BFC10h], EAX ; store EAX content CPU 32-bit physical address space Code executed by CPU: MOV AL, 05h ; load 8-bit constant MOV [ h], AL ; 8-bit store master addr 0 memory controller (refresh) comm. protocol: 32-bit address space 1 GB DRAM module memory bus MWr addr $100 slave memory bus comm. protocol: 32-bit address space 512 MB DRAM module device A zoomed view: addr 1 1 B register Y MWr 2 B register X slave reg Y system bus $ reg X $FFFFFFFF = 232-1 4 GB device B $ addr 8 slave 1 B register device C = bus 2 controller (HBA) bus 2 $ 512 MB $5FFFFFFF addr 7 1 GB $3FFFFFFF = 230-1 slave 1 B register addr 13 addr 1 device D device E $ = 0 1 B register 1 B register 1 B register

16 Programming Target Address for DMA Write
CPU 32-bit physical address space master memory controller (refresh) comm. protocol: 32-bit address space 1 GB DRAM module memory bus memory bus comm. protocol: 32-bit address space 512 MB DRAM module device A zoomed view: 1 B register Y MWr 2 B register X reg Y system bus slave $ reg X $FFFFFFFF = 232-1 4 GB device B $ 1 B register device C = bus 2 controller (HBA) bus 2 $ 512 MB $5FFFFFFF 1 GB $3FFFFFFF = 230-1 1 B register device D device E $ = 0 1 B register 1 B register 1 B register

17 DMA Write CPU slave master memory controller (refresh) 1 GB DRAM
32-bit physical address space memory controller (refresh) comm. protocol: 32-bit address space 1 GB DRAM module memory bus MWr slave memory bus comm. protocol: 32-bit address space 512 MB DRAM module device A zoomed view: MWr 1 B register Y master 2 B register X reg Y system bus $ reg X $FFFFFFFF = 232-1 4 GB device B $ 1 B register device C = bus 2 controller (HBA) bus 2 $ 512 MB $5FFFFFFF 1 GB $3FFFFFFF = 230-1 1 B register device D device E $ = 0 1 B register 1 B register 1 B register

18 16-bit Sound Card HCI DAC Address decode Playback logic Data R/W reg
MSB LSB sound buffer (100kB – MB) RWAddr R/W reg ... $F DD $F $F AA $F CF $F CT $F ST DAC PlayAdr reg auto increment Config R/W reg ▪sample rate ▪sample size ▪mono/stereo auto increment Control W/O reg ▪play/stop ▪record/stop Status R/O reg ▪play position ▪playing? ▪recording? Loudspeaker image (CC Attribution) authored by Sallee Design, Base address: $F

19 16-bit Sound Card HCI with DMA Bus Master
Address decode Playback logic DMA Addr R/W reg 32-bit ... $F000010A A3 $F A2 $F A1 $F A0 $F L3 $F L2 $F L1 $F L0 $F CF $F CT $F ST sound buffer (100kB – MB) auto increment DMA Length R/W reg 32-bit DAC PlayAdr reg DMA BufferAddr reg Config R/W reg ▪sample rate ▪sample size ▪mono/stereo auto increment auto increment Control W/O reg ▪play/stop ▪record/stop Status R/O reg ▪play position ▪playing? ▪recording? Loudspeaker image (CC Attribution) authored by Sallee Design, Base address: $F

20 DMA: Do Not Forget: Logical vs. Physical Address Space
CPU arch. CPU name Data width Logical address width Current instruction register(s) Physical address width 8-bit 6502 MOS 6502 8-bit data 16-bit PC (64 kB) x86-16 x86 Intel 8088 bit 20-bit (1 MB) Intel 8086 16-bit data logical address (16 bit & 16 bit): Segment:Offset physical address (20 bit): (Segment * 16) + Offset logical address: $AAAA:$0000 physical address: $AAAA * 16 = $AAAA shl 4 = $AAAA0 + $0000 = $AAAA0

21 Where To Get Initial Code on Von Neumann Architeture?
CPU 32-bit physical address space memory controller (refresh) comm. protocol: 32-bit address space 1 GB DRAM module memory bus memory bus comm. protocol: 32-bit address space 512 MB DRAM module device A zoomed view: 1 B register Y 2 B register X reg Y system bus $ reg X $FFFFFFFF = 232-1 4 GB device B $ 1 B register device C = bus 2 controller (HBA) bus 2 $ 512 MB $5FFFFFFF 1 GB $3FFFFFFF = 230-1 1 B register addr 13 addr 1 device D device E $ = 0 1 B register 1 B register 1 B register

22 System Bus – Firmware ROM
CPU comm. protocol: 20-bit address space 1 MB ROM module 32-bit physical address space memory bus memory controller (refresh) comm. protocol: 32-bit address space 1 GB DRAM module memory bus memory bus comm. protocol: 32-bit address space 512 MB DRAM module device A zoomed view: 1 B register Y 2 B register X reg Y system bus $ reg X $FFFFFFFF = 232-1 4 GB FW ROM device B $ 1 B register device C = bus 2 controller (HBA) bus 2 $ 512 MB $5FFFFFFF 1 GB $3FFFFFFF = 230-1 1 B register addr 13 addr 1 device D device E $ = 0 1 B register 1 B register 1 B register

23 PURPLE = computer firmware code executed by CPU
firmware test and configures HW firmware tries to locate SW to run

24 PURPLE = computer firmware code executed by CPU
firmware test and configures HW firmware checks and calls option ROMs

25 PURPLE = computer firmware code executed by CPU
firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM

26 Example of Firmware ABI via Software Interrupts
BIOS API functions/procedures Interrupt vector (arguments passed in registers) Disk access – e.g. read sector $13 Screen output – e.g. print text to screen $10 Keyboard input – e.g. read last key pressed $16 Get total amount of RAM installed $12 Get memory map $15

27 PURPLE = computer firmware code executed by CPU
GREEN = boot loader code executed by CPU firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with application code/data loaded to RAM call application entrypoint

28 PURPLE = computer firmware code executed by CPU
GREEN = boot loader code executed by CPU firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint

29 PURPLE = computer firmware code executed by CPU
GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLUE = user program code executed by CPU firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint kernel init call Exec(‘Prog.exe’) load Prog.exe call Prog.exe entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE ...

30

31 PURPLE = computer firmware code executed by CPU
GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER

32 PURPLE = computer firmware code executed by CPU
GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER call Exec(‘Prog.EXE’) load Prog.EXE call Prog.EXE entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE

33 Selected Faults/Traps/Exceptions of x86 ISA
CPU Exception Interrupt vector (all push IP of faulting instruction) Invalid opcode 6 Divide by zero (DIV0) Alignment check 17 ($11)

34 Selected Faults/Traps/Exceptions of x86 ISA
CPU Exception Interrupt vector (all push IP of faulting instruction) Invalid opcode 6 Divide by zero (DIV0) Alignment check 17 ($11) General Protection Fault 13 ($0D)

35 CPU starts in supervisor mode
PURPLE = computer firmware code executed by CPU GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU CPU starts in supervisor mode firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER call Exec(‘Prog.EXE’) load Prog.EXE call Prog.EXE entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE

36 PURPLE = computer firmware code executed by CPU
GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU CPU starts in supervisor mode firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER call Exec(‘Prog.EXE’) load Prog.EXE call Prog.EXE entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE Kernel sets super := 0, CPU gets to user mode

37 Cannot disable HW interrupts (IRQs)
PURPLE = computer firmware code executed by CPU GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU CPU starts in supervisor mode firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER call Exec(‘Prog.EXE’) load Prog.EXE call Prog.EXE entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE Kernel sets super := 0, CPU gets to user mode Cannot modify IVT Cannot disable HW interrupts (IRQs) Kernel code runs in user mode :(

38 INT n instruction is executed by the CPU as an atomic sequence of:
PURPLE = computer firmware code executed by CPU GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU CPU starts in supervisor mode firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint INT n instruction is executed by the CPU as an atomic sequence of: PUSHF ← push flags register to stack CLI ← disable HW interrupts CALL [IVT[n]] ← call actual interrupt handler (works in this way for SW interrupts, CPU faults, and HW interrupts) kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER call Exec(‘Prog.EXE’) load Prog.EXE call Prog.EXE entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE Kernel sets super := 0, CPU gets to user mode Cannot modify IVT Cannot disable HW interrupts (IRQs) Kernel code runs in user mode :(

39 INT n instruction is executed by the CPU as an atomic sequence of:
PURPLE = computer firmware code executed by CPU GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU CPU starts in supervisor mode firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint INT n instruction is executed by the CPU as an atomic sequence of: PUSHF ← push flags register to stack flags.supervisor := 1 ← call actual interrupt handler CLI ← disable HW interrupts CALL [IVT[n]] ← call actual interrupt handler (works in this way for SW interrupts, CPU faults, and HW interrupts) kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER call Exec(‘Prog.EXE’) load Prog.EXE call Prog.EXE entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE Kernel sets super := 0, CPU gets to user mode Syscall switches CPU to supervisor mode

40 INT n instruction is executed by the CPU as an atomic sequence of:
PURPLE = computer firmware code executed by CPU GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU CPU starts in supervisor mode firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint INT n instruction is executed by the CPU as an atomic sequence of: PUSHF ← push flags register to stack flags.supervisor := 1 ← call actual interrupt handler CLI ← disable HW interrupts CALL [IVT[n]] ← call actual interrupt handler (works in this way for SW interrupts, CPU faults, and HW interrupts) kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER call Exec(‘Prog.EXE’) load Prog.EXE call Prog.EXE entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE Kernel sets super := 0, CPU gets to user mode Syscall switches CPU to supervisor mode IRET from syscall restores flags, so super := 0, so CPU switches back to user mode

41 INT n instruction is executed by the CPU as an atomic sequence of:
PURPLE = computer firmware code executed by CPU GREEN = boot loader code executed by CPU RED = kernel code executed by CPU BLACK = shell code executed by CPU BLUE = user program code executed by CPU CPU starts in supervisor mode firmware test and configures HW firmware checks and calls option ROMs firmware tries to find bootable drive: load boot sector to RAM jump/call to boot sector entrypoint in RAM boot loader running repeat call ReadSector firmware API firmware communicates with drive’s controller firmware stores received sectors data into RAM until all sectors with kernel code/data loaded to RAM call kernel entrypoint INT n instruction is executed by the CPU as an atomic sequence of: PUSHF ← push flags register to stack flags.supervisor := 1 ← call actual interrupt handler CLI ← disable HW interrupts CALL [IVT[n]] ← call actual interrupt handler (works in this way for SW interrupts, CPU faults, and HW interrupts) kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat call ReadKey kernel API kernel communicates with keyboard controller key := result of ReadKey call PrintCharacter kernel API kernel communicates with graphics card until key <> ENTER call Exec(‘Prog.EXE’) load Prog.EXE call Prog.EXE entrypoint ... Prog.EXE’s RTL initialization code ... main program of Prog.EXE Kernel sets super := 0, CPU gets to user mode Syscall switches CPU to supervisor mode IRET from syscall restores flags, so super := 0, so CPU switches back to user mode Syscall switches CPU to supervisor mode IRET from syscall restores flags, so super := 0, so CPU switches back to user mode

42 Selected Faults/Traps/Exceptions of x86 ISA
CPU Exception Interrupt vector (all push IP of faulting instruction) Invalid opcode 6 Divide by zero (DIV0) Alignment check 17 ($11) General Protection Fault 13 ($0D) Page Fault 14 ($0E)

43 ... kernel data IVT page tbl kernel code stack free 9 8 A data 7 6 5
A code 4 3 2 1 PT entry Kernel/Supervisor User

44 ... kernel data IVT page tbl kernel code stack free 9 8 A data 7 6 5
A code 4 3 2 1 PT entry Kernel/Supervisor User Read/Only User Read/Write

45 ... kernel data IVT page tbl kernel code stack free 9 8 A data 7 6 5
A code 4 3 2 1 PT entry Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute

46 ... kernel data IVT page tbl kernel code stack free 9 8 A data 7 6 5
A code 4 3 2 1 PT entry Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute

47 ... kernel data IVT page tbl kernel code stack free 10 9 8 A data 7 6
5 A code 4 3 2 1 PT entry Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute

48 call to kernel’s AllocMem API function Non-present Kernel/Supervisor
... kernel data IVT page tbl kernel code stack free 10 9 used (RTL heap) 8 A data 7 6 5 A code 4 3 2 1 PT entry AllocMem API will return based address of a free page (9) to RTL → RTL will manage subsequent allocations in that page call to kernel’s AllocMem API function Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute call to RTL’s New(1000)

49 B A Heap state after: A := New(1000 bytes); B := New(2000 bytes); ...
kernel data IVT page tbl kernel code stack free 10 9 used (RTL heap) 8 A data 7 6 5 A code 4 3 2 1 PT entry 1072 bytes of free memory Heap mngmt record size: 1080 next: nil B 2000 bytes of allocated memory FirstFreeBlock FirstUsedBlock Heap mngmt record size: 2008 next: nil Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute A 1000 bytes of allocated memory Heap mngmt record size: 1008 next:

50 call to kernel’s AllocMem API function Non-present Kernel/Supervisor
... kernel data IVT page tbl kernel code stack free 10 used (RTL heap) 9 8 A data 7 6 5 A code 4 3 2 1 PT entry AllocMem API will return base address of next free page (10) to RTL → RTL will manage subsequent allocations in that page call to kernel’s AllocMem API function Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute 3rd call to RTL’s New(3000) – will not fit current heap (into page 9)

51 8192-3008-2008-1008 = 2168 bytes of free memory
Heap state after: A := New(1000 bytes); B := New(2000 bytes); C := New(3000 bytes); ... kernel data IVT page tbl kernel code stack free 10 used (RTL heap) 9 8 A data 7 6 5 A code 4 3 2 1 PT entry If pagesize = 4096: 2 pages = 2*4096 = 8192 bytes = 2168 bytes of free memory Heap mngmt record size: 2168 next: nil C 3000 bytes of allocated memory Heap mngmt record size: 3008 next: nil B 2000 bytes of allocated memory FirstFreeBlock FirstUsedBlock Heap mngmt record size: 2008 next: Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute A 1000 bytes of allocated memory Heap mngmt record size: 1008 next:

52 8192-3008-2008-1008 = 2168 bytes of free memory
Heap state after: A := New(1000 bytes); B := New(2000 bytes); C := New(3000 bytes); Dispose(B); ... kernel data IVT page tbl kernel code stack free 10 used (RTL heap) 9 8 A data 7 6 5 A code 4 3 2 1 PT entry If pagesize = 4096: 2 pages = 2*4096 = 8192 bytes = 2168 bytes of free memory Heap mngmt record size: 2168 next: nil C 3000 bytes of allocated memory Heap mngmt record size: 3008 next: nil B 2000 bytes of free memory FirstFreeBlock FirstUsedBlock Heap mngmt record size: 2008 next: Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute A 1000 bytes of allocated memory Heap mngmt record size: 1008 next:

53 ... kernel data IVT page tbl kernel code stack free 10 used (RTL heap)
9 8 A data 7 6 5 A code 4 3 2 1 PT entry Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute

54 ... kernel data IVT page tbl kernel code stack guard page free 10
used (RTL heap) 9 8 A data 7 6 5 A code 4 3 2 1 PT entry Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute

55 ... kernel data IVT page tbl kernel code stack guard page free 10
used (RTL heap) 9 8 A data 7 6 5 A code 4 3 2 1 PT entry Non-present Kernel/Supervisor User Read/Only User Read/Write NX/XD No Execute

56 kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat until key <> ENTER call Exec(‘P.EXE’) load P.EXE load & relocate EXE image load & relocate DLL images (A.DLL, B.DLL) call A.DLL entrypoint call B.DLL entrypoint call P.EXE entrypoint ... main program of P.EXE

57 kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat until key <> ENTER call Exec(‘P.EXE’) load P.EXE load & relocate EXE image load & relocate DLL images (A.DLL, B.DLL) call A.DLL entrypoint call B.DLL entrypoint call P.EXE entrypoint call Exit clean up (release resources) ... (never here = rest of P.EXE main program) ... ret goto

58 context switch context switch kernel init call Exec(‘shell.exe’)
load shell.exe call shell.exe entrypoint ... repeat until key <> ENTER call Exec(‘P.EXE’) load P.EXE load & relocate EXE image load & relocate DLL images push currentPID currentPID := AllocateNewPID; call A.DLL entrypoint call B.DLL entrypoint call P.EXE entrypoint call Exit clean up (release resources) ... (never here = rest of P.EXE main program) ... pop currentPID ret goto context switch context switch

59 Allocated memory (pages)
kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... AllocMem → for currentPID = 1 repeat ... until key <> ENTER call Exec(‘P.EXE’) load P.EXE load & relocate EXE image load & relocate DLL images push currentPID (1) currentPID := AllocateNewPID; (2) call A.DLL entrypoint call B.DLL entrypoint call P.EXE entrypoint ... AllocMem → for currentPID = 2 call Exit clean up (release resources) ret ... (never here = rest of P.EXE main program) ... pop currentPID (1) goto context switch to PID 2 context switch back to PID 1

60 Allocated memory (pages)
List of loaded DLLs kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... AllocMem → for currentPID = 1 repeat ... until key <> ENTER call Exec(‘P.EXE’) load P.EXE load & relocate EXE image load & relocate DLL images push currentPID (1) currentPID := AllocateNewPID; (2) call A.DLL entrypoint call B.DLL entrypoint call P.EXE entrypoint ... AllocMem → for currentPID = 2 call Exit clean up (release resources) ret ... (never here = rest of P.EXE main program) ... pop currentPID (1) goto context switch to PID 2 context switch back to PID 1

61 Allocated memory (pages)
List of loaded DLLs CPU fault → kernel interrupt handler → call procTable[currentPID].faultHandlers[faultID] kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... AllocMem → for currentPID = 1 repeat ... until key <> ENTER call Exec(‘P.EXE’) load P.EXE load & relocate EXE image load & relocate DLL images push currentPID (1) currentPID := AllocateNewPID; (2) call A.DLL entrypoint call B.DLL entrypoint call P.EXE entrypoint ... AllocMem → for currentPID = 2 call Exit clean up (release resources) ret ... (never here = rest of P.EXE main program) ... pop currentPID (1) goto context switch to PID 2 context switch back to PID 1

62 ... kernel data IVT proc table page tbl kernel code stack guard page free A data A code PT Non-present Kernel/Supervisor User Read/Only User Read/Write

63 ... kernel data IVT proc table page tbl kernel code stack guard page free A heap A data A code PT Non-present Kernel/Supervisor User Read/Only User Read/Write → Pascal runtime’s call of syscall (OS API) AllocMem

64 ... kernel data IVT proc table page tbl kernel code stack guard page free A heap A data A code PT Non-present Kernel/Supervisor User Read/Only User Read/Write

65 ... kernel data IVT proc table page tbl kernel code stack guard page free B heap B data B code A heap A data A code PT Non-present Kernel/Supervisor User Read/Only User Read/Write

66 ... kernel data IVT proc table page tbl kernel code stack guard page free B heap B data B code A heap A data A code PT Non-present Kernel/Supervisor User Read/Only User Read/Write

67 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code stack guard page free B heap B data B code A heap A data A code A PT B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 Non-present Kernel/Supervisor User Read/Only User Read/Write

68 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code stack guard page free B heap B data B code A heap A data A code A PT B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 Non-present Kernel/Supervisor User Read/Only User Read/Write

69 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code stack guard page free B heap B data B code A heap A data A code A PT B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 Non-present Kernel/Supervisor User Read/Only User Read/Write

70 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code stack guard page free B heap B data B code A heap A data A code A PT B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 Non-present Kernel/Supervisor User Read/Only User Read/Write

71 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code stack guard page free B heap B data B code A heap A data A code A PT B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 Non-present Kernel/Supervisor User Read/Only User Read/Write

72 Allocated memory (pages)
List of loaded DLLs CPU fault → kernel interrupt handler call procTable[currentPID].faultHandlers[faultID] Page table (state of the address space) kernel init call Exec(‘shell.exe’) load shell.exe call shell.exe entrypoint ... repeat until key <> ENTER call Exec(‘P.EXE’) load P.EXE load & relocate EXE image load & relocate DLL images push currentPID currentPID := AllocateNewPID; procTable[currentPID].pageTable := InitilizeNewPageTable; CR3 := procTable[currentPID].pageTable; procTable[currentPID].oldSP := SP – sizeof(entrypoint’s stack frame) call A.DLL entrypoint call B.DLL entrypoint call P.EXE entrypoint call f1 in P.EXE call f2 in P.EXE call Exit clean up (release resources) SP := procTable[currentPID].oldSP ret ... (never here = rest of f2) ... ... (never here = rest of f1) ... pop currentPID goto context switch to PID 2 context switch to PID 2 context switch back to PID 1

73 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code stack guard page free B heap B data B code A heap A data A code A PT page 0 B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 Non-present Kernel/Supervisor User Read/Only User Read/Write

74 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code stack guard page free B heap B data B code A heap A data A code A PT page 0 B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 A’s stack frames B’s stack frames Non-present Kernel/Supervisor User Read/Only User Read/Write

75 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code A stack A’s guard page free B stack B’s guard page B heap B data B code A heap A data A code A PT page 0 B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 A’s stack frames unused A’s stack B’s stack frames Non-present Kernel/Supervisor User Read/Only User Read/Write

76 CPU (x86/IA-32) ... kernel data proc table B page tbl A page tbl
kernel code A stack A’s guard page free B stack B’s guard page B heap B data B code A heap A data A code A PT page 0 B PT CPU (x86/IA-32) EIP ESP CR3 31 page table base 0 A’s stack frames unused A’s stack B’s stack frames Exec: ... procTable[currPID].OldSP := SP; procTable[newPID].StackBottom := AllocateNewStack + PageSize – 1; SP := procTable[newPID].StackBottom; call Entrypoint SP := procTable[currPID].OldSP; FreeStackFor(newPID); Exit: SP := procTable[currPID].StackBottom – entrypoint’s stack frame ret Non-present Kernel/Supervisor User Read/Only User Read/Write

77 Process vs. Thread Process state (context): Allocated memory (pages)
List of loaded DLLs CPU fault → kernel interrupt handler call procTable[currentPID].faultHandlers[faultID] Page table (state of the address space) PID (Process ID) Thread state (context): Call stack (allocated in context of a process) + SP register! Other CPU registers (IP, FLAGS, general register [if running]) TID (Thread ID)

78 CreateThread(@ExecStartFunc)
Thread A: A_entrypoint ... call A_main call funcX call Exec ret from A_entry ret from A_main ret from funcX ret from Exec A stack max SP Exec CreateProcess IP CreateThread(startFunc : pointer) newTID := AllocFreeTID; threadTable[newTID].SP := AllocNewStack; threadTable[currTID].SP := SP; SP := threadTable[newTID].SP; currTID := newTID; jmp startFunc ExecStartFunc: call DLL entrypoints call B_entrypoint ret

79 CreateThread(@ExecStartFunc)
Thread A: A_entrypoint ... call A_main call funcX call Exec ret from A_entry ret from A_main ret from funcX ret from Exec A stack max SP Exec CreateProcess CreateThread(startFunc : pointer) newTID := AllocFreeTID; threadTable[newTID].SP := AllocNewStack; threadTable[currTID].SP := SP; SP := threadTable[newTID].SP; currTID := newTID; jmp startFunc IP ExecStartFunc: call DLL entrypoints call B_entrypoint ret

80 CreateThread(startFunc : pointer) newTID := AllocFreeTID;
Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B: ret from A_entry ret from A_main ret from funcX ret from Exec A stack max SP CreateThread(startFunc : pointer) newTID := AllocFreeTID; threadTable[newTID].SP := AllocNewStack; threadTable[currTID].SP := SP; SP := threadTable[newTID].SP; currTID := newTID; jmp startFunc IP ExecStartFunc: call DLL entrypoints call B_entrypoint ret

81 CreateThread(startFunc : pointer) newTID := AllocFreeTID;
Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B: ret from A_entry ret from A_main ret from funcX ret from Exec A stack max B stack max SP CreateThread(startFunc : pointer) newTID := AllocFreeTID; threadTable[newTID].SP := AllocNewStack; threadTable[currTID].SP := SP; SP := threadTable[newTID].SP; currTID := newTID; jmp startFunc IP ExecStartFunc: call DLL entrypoints call B_entrypoint ret

82 CreateThread(startFunc : pointer) newTID := AllocFreeTID;
Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B: SP ret from A_entry ret from A_main ret from funcX ret from Exec A stack max B stack max CreateThread(startFunc : pointer) newTID := AllocFreeTID; threadTable[newTID].SP := AllocNewStack; threadTable[currTID].SP := SP; SP := threadTable[newTID].SP; currTID := newTID; jmp startFunc ExecStartFunc: call DLL entrypoints call B_entrypoint ret IP

83 Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B:
B_entrypoint ... call funcY ret from A_entry ret from A_main ret from funcX ret from Exec A stack max SP ret from B_entry B stack max IP ExecStartFunc: call DLL entrypoints call B_entrypoint ret

84 Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B:
B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from funcX ret from Exec A stack max ret from B_entry ret from funcY B stack max SP IP

85 Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B:
B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from funcX ret from Exec A stack max ret from B_entry ret from funcY ret from Yield B stack max SP Yield: IP

86 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from funcX ret from Exec A stack max ret from B_entry ret from funcY ret from Yield B stack max SP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret IP

87 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from funcX ret from Exec A stack max ret from B_entry ret from funcY ret from Yield B stack max SP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret IP

88 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from funcX ret from Exec A stack max ret from B_entry ret from funcY ret from Yield B stack max SP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret IP

89 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from funcX A stack max ret from B_entry ret from funcY ret from Yield B stack max SP IP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

90 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from funcX A stack max ret from B_entry ret from funcY ret from Yield B stack max SP IP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

91 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main A stack max ret from B_entry ret from funcY ret from Yield B stack max SP IP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

92 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from Yield A stack max ret from B_entry ret from funcY ret from Yield B stack max SP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret IP

93 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from Yield A stack max ret from B_entry ret from funcY ret from Yield B stack max SP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret IP

94 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from Yield A stack max ret from B_entry ret from funcY ret from Yield B stack max SP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret IP

95 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield ret from A_entry ret from A_main ret from Yield A stack max ret from B_entry ret from funcY B stack max SP IP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

96 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield funcY cont. call funcZ ret from A_entry ret from A_main ret from Yield A stack max ret from B_entry ret from funcY B stack max SP IP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

97 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield funcY cont. call funcZ ret from A_entry ret from A_main ret from Yield A stack max ret from B_entry ret from funcY ret from funcZ B stack max SP IP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

98 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield funcY cont. call funcZ ret from A_entry ret from A_main ret from Yield A stack max ret from B_entry ret from funcY ret from funcZ ret from Yield B stack max SP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret IP

99 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield funcY cont. call funcZ ret from A_entry ret from A_main ret from Yield A stack max ret from B_entry ret from funcY ret from funcZ ret from Yield B stack max SP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret IP

100 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield funcY cont. call funcZ ret from A_entry ret from A_main A stack max ret from B_entry ret from funcY ret from funcZ ret from Yield B stack max SP IP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

101 threadTable[currTID].SP := SP; nextTID := GetNextThreadID;
Thread A: A_entrypoint ... call A_main call funcX call Exec funcX cont. ret A_main cont. call Yield Thread B: B_entrypoint ... call funcY call Yield funcY cont. call funcZ ret from A_entry ret from A_main A stack max ret from B_entry ret from funcY ret from funcZ ret from Yield B stack max SP IP Yield: threadTable[currTID].SP := SP; nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

102 We’ve Just Implemented Cooperative Multitasking

103 Scheduler Yield: threadTable[currTID].SP := SP;
nextTID := GetNextThreadID; SwitchProcessContextIfNecessary SP := threadTable[nextTID].SP; currTID := nextTID; ret

104 Preemptive Multitasking


Download ppt "Principles of Computers 21st Lecture"

Similar presentations


Ads by Google