Anton Burtsev February, 2017

Slides:



Advertisements
Similar presentations
1/1/ / faculty of Electrical Engineering eindhoven university of technology Memory Management and Protection Part 3:Virtual memory, mode switching,
Advertisements

Copyright © 2001, Daniel W. Lewis. All Rights Reserved. CHAPTER 11 SYSTEM INITIALIZATION.
Using VMX within Linux We explore the feasibility of executing ROM-BIOS code within the Linux x86_64 kernel.
CS 4284 Systems Capstone Godmar Back Linking and Loading.
Intel MP.
Microprocessors system architectures – IA32 real and virtual-8086 mode Jakub Yaghob.
OS Memory Addressing.
Chapter 6 Limited Direct Execution
CS591 (Spring 2001) The Linux Kernel: Signals & Interrupts.
UQC152H3 Advanced OS Memory Management under Linux.
IA-32 Processor Architecture
Page-Faults in Linux How can we study the handling of page-fault exceptions?
Context Switch Animation Another one by Anastasia.
X86 segmentation, page tables, and interrupts 3/17/08 Frans Kaashoek MIT
Introduction to Kernel
OS Spring’03 Introduction Operating Systems Spring 2003.
OS Spring’04 Introduction Operating Systems Spring 2004.
Administrative Overview 6 Projects Design Review: Monday before 6:30pm Lab Friend Center 010 (“Fishbowl”)
UNIT 2 Memory Management Unit and Segment Description and Paging
Intel MP (32-bit microprocessor) Designed to overcome the limits of its predecessor while maintaining the software compatibility with the.
Windows Kernel Internals Traps, Interrupts, Exceptions
Microprocessor system architectures – IA32 segmentation Jakub Yaghob.
CS 3204 Operating Systems Godmar Back Lecture 11.
Multitasking Mr. Mahendra B. Salunke Asst. Prof. Dept. of Computer Engg., STES SITS, Narhe, Pune-41 STES Sinhgad Institute of Tech. & Science Dept. of.
Hardware process When the computer is powered up, it begins to execute fetch-execute cycle for the program that is stored in memory at the boot strap entry.
LINUX System : Lecture 7 Process Bong-Soo Sohn Lecture notes acknowledgement : The design of UNIX Operating System.
Microprocessor system architectures – IA32 tasks Jakub Yaghob.
Hardware process When the computer is powered up, it begins to execute fetch-execute cycle for the program that is stored in memory at the boot strap entry.
6. HAL and IDT ENGI 3655 Lab Sessions. Richard Khoury2 Textbook Readings  Interrupts ◦ Section  Hardware Abstraction Layer ◦ Section
1 Microprocessors CSE Protected Mode Memory Addressing Remember using real mode addressing we were previously able to address 1M Byte of memory.
1 Structure of Processes Chapter 6 Process State and Transition Data Structure for Process Layout of System Memory THE DESIGN OF THE UNIX OPERATING SYSTEM.
Page Replacement Implementation Issues Text: –Tanenbaum ch. 4.7.
10. Epilogue ENGI 3655 Lab Sessions.  We took control of the computer as early as possible, right after the end of the BIOS  Our multi-stage bootloader.
What You Need to Know for Project Three Steve Muckle Wednesday, February 19 th Spring 2003.
Lecture 5 Rootkits Hoglund/Butler (Chapters 1-3).
Information Security - 2. Task Switching Every process has an associated Task State Segment, whose starting point is stored in the Task register. A task.
OS Memory Addressing. Architecture CPU – Processing units – Caches – Interrupt controllers – MMU Memory Interconnect North bridge South bridge PCI, etc.
Information Security - 2. CISC Vs RISC X86 is CISC while ARM is RISC CISC is Compiler’s heaven while RISC is Architecture’s heaven Orthogonal ISA in RISC.
Lecture 7 Interrupt ,Trap and System Call
What You Need to Know for Project Three Dave Eckhardt Steve Muckle.
Virtualizing the CPU: Processes 1. How to provide the illusion of many CPUs? CPU virtualizing – The OS can promote the illusion that many virtual CPUs.
Stack Operations Dr. Hadi AL Saadi.
Homework / Exam Return and Review Exam #1 Reading Machine Projects
Introduction to Kernel
Virtualization Virtualize hardware resources through abstraction CPU
Operating Systems Engineering
CSE 120 Principles of Operating
Processes.
Structure of Processes
143A: Principles of Operating Systems Lecture 7: System boot
Anton Burtsev February, 2017
Anton Burtsev February, 2017
ICS143A: Principles of Operating Systems Lecture 13: Context switching
Overview of today’s lecture
Anton Burtsev February, 2017
143A: Principles of Operating Systems Lecture 5: Address translation
CS 5204 Operating Systems Linking and Loading Godmar Back.
Information Security - 2
ICS143A: Principles of Operating Systems Lecture 15: Locking
x86 segmentation, page tables, and interrupts
Page Replacement Implementation Issues
More examples How many processes does this piece of code create?
CS 4284 Systems Capstone Linking and Loading Godmar Back.
Discussions on HW2 Objectives
Discussions on HW2 Objectives
Information Security - 2
Low-Level Thread Dispatching on the x86
Interrupts and System Calls
Lecture 10 review Booting sequence in Brief
CS444/544 Operating Systems II Virtual Memory
Presentation transcript:

Anton Burtsev February, 2017 ICS143A: Principles of Operating Systems Lecture 12: Starting other CPUs Anton Burtsev February, 2017

Starting other CPUs

We're back to main() 1317 main(void) 1318 { ... 1336 startothers(); // start other processors 1337 kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); 1338 userinit(); // first user process 1339 mpmain(); 1340 }

Starting other CPUs Copy start code in a good location 0x7000 (remember same as the one used by boot loader) Pass start parameters on the stack Stack for a high-address kernel Each CPU allocates a page from a physical allocator Entry point (mpenter()) Two entry page table To do the low to high address switch

Start other CPUs 1374 startothers(void) 1375 { 1384 code = P2V(0x7000); 1385 memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); 1386 1387 for(c = cpus; c < cpus+ncpu; c++){ 1388 if(c == cpus+cpunum()) // We’ve started already. 1389 continue; ... 1394 stack = kalloc(); 1395 *(void**)(code−4) = stack + KSTACKSIZE; 1396 *(void**)(code−8) = mpenter; 1397 *(int**)(code−12) = (void *) v2p(entrypgdir); 1398 1399 lapicstartap(c−>id, v2p(code));

We could choose any address, but 0x7c00 is convenient

Start other CPUs 1374 startothers(void) 1375 { 1384 code = P2V(0x7000); 1385 memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); 1386 1387 for(c = cpus; c < cpus+ncpu; c++){ 1388 if(c == cpus+cpunum()) // We’ve started already. 1389 continue; ... 1394 stack = kalloc(); 1395 *(void**)(code−4) = stack + KSTACKSIZE; 1396 *(void**)(code−8) = mpenter; 1397 *(int**)(code−12) = (void *) v2p(entrypgdir); 1398 1399 lapicstartap(c−>id, v2p(code));

Recap(): First stack

Recap: kalloc() – allocate page

Start other CPUs 1374 startothers(void) 1375 { 1384 code = P2V(0x7000); 1385 memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); 1386 1387 for(c = cpus; c < cpus+ncpu; c++){ 1388 if(c == cpus+cpunum()) // We’ve started already. 1389 continue; ... 1394 stack = kalloc(); 1395 *(void**)(code−4) = stack + KSTACKSIZE; 1396 *(void**)(code−8) = mpenter; 1397 *(int**)(code−12) = (void *) v2p(entrypgdir); 1398 1399 lapicstartap(c−>id, v2p(code));

Start other CPUs 1374 startothers(void) 1375 { 1384 code = P2V(0x7000); 1385 memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); 1386 1387 for(c = cpus; c < cpus+ncpu; c++){ 1388 if(c == cpus+cpunum()) // We’ve started already. 1389 continue; ... 1394 stack = kalloc(); 1395 *(void**)(code−4) = stack + KSTACKSIZE; 1396 *(void**)(code−8) = mpenter; 1397 *(int**)(code−12) = (void *) v2p(entrypgdir); 1398 1399 lapicstartap(c−>id, v2p(code));

entryother.S 1123 .code16 1124 .globl start 1125 start: 1126 cli 1127 1128 xorw %ax,%ax 1129 movw %ax,%ds 1130 movw %ax,%es 1131 movw %ax,%ss 1132 Disable interrupts Init segments with 0

entryother.S 1133 lgdt gdtdesc 1134 movl %cr0, %eax 1135 orl $CR0_PE, %eax 1136 movl %eax, %cr0 1150 ljmpl $(SEG_KCODE<<3), $(start32) 1151 1152 .code32 1153 start32: 1154 movw $(SEG_KDATA<<3), %ax 1155 movw %ax, %ds 1156 movw %ax, %es 1157 movw %ax, %ss 1158 movw $0, %ax 1159 movw %ax, %fs 1160 movw %ax, %gs Load GDT Switch to 32bit mode Long jump to start32 Load segments

entryother.S 1162 # Turn on page size extension for 4Mbyte pages 1163 movl %cr4, %eax 1164 orl $(CR4_PSE), %eax 1165 movl %eax, %cr4 1166 # Use enterpgdir as our initial page table 1167 movl (start−12), %eax 1168 movl %eax, %cr3 1169 # Turn on paging. 1170 movl %cr0, %eax 1171 orl $(CR0_PE|CR0_PG|CR0_WP), %eax 1172 movl %eax, %cr0 1173 1174 # Switch to the stack allocated by startothers() 1175 movl (start−4), %esp 1176 # Call mpenter() 1177 call *(start−8) entryother.S

1251 static void 1252 mpenter(void) 1253 { 1254 switchkvm(); 1255 seginit(); 1256 lapicinit(); 1257 mpmain(); 1258 }

Init segments 1616 seginit(void) 1617 { 1618 struct cpu *c; ... 1624 c = &cpus[cpunum()]; 1625 c−>gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0); 1626 c−>gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); 1627 c−>gdt[SEG_UCODE] = SEG(STA_X|STA_R, 0, 0x8000000, DPL_USER); 1628 c−>gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER); 1629 1630 // Map cpu, and curproc 1631 c−>gdt[SEG_KCPU] = SEG(STA_W, &c−>cpu, 8, 0); 1632 1633 lgdt(c−>gdt, sizeof(c−>gdt)); 1634 loadgs(SEG_KCPU << 3); 1635 1636 // Initialize cpu−local storage. 1637 cpu = c; 1638 proc = 0; 1639 }

Per-CPU variables Variables private to each CPU

Per-CPU variables 6913 extern struct cpu cpus[NCPU]; Variables private to each CPU Current running process Kernel stack for interrupts Hence, TSS that stores that stack 6913 extern struct cpu cpus[NCPU];

One catch: lapic[id] is slow

We need to save id of a CPU on each CPU We can use a register ...

We need to save id of a CPU on each CPU We can use a register … But it's wasteful

2300 // Per−CPU state 2301 struct cpu { 2302 uchar apicid; // Local APIC ID 2303 struct context *scheduler; // swtch() here to enter scheduler 2304 struct taskstate ts; // Used by x86 to find stack for interrupt 2305 struct segdesc gdt[NSEGS]; // x86 global descriptor table 2306 volatile uint started; // Has the CPU started? 2307 int ncli; // Depth of pushcli nesting. 2308 int intena; // Were interrupts enabled before pushcli? 2309 2310 // Cpu−local storage variables; see below 2311 struct cpu *cpu; 2312 struct proc *proc; // The currently−running process. 2313 };

2300 // Per−CPU state 2301 struct cpu { 2302 uchar apicid; // Local APIC ID 2303 struct context *scheduler; 2304 struct taskstate ts; 2305 struct segdesc gdt[NSEGS]; // x86 global descriptor table ... 2310 // Cpu−local storage variables; see below 2311 struct cpu *cpu; 2312 struct proc *proc; // The currently−running process. 2313 }; 2326 extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()] 2327 extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc

1251 static void 1252 mpenter(void) 1253 { 1254 switchkvm(); 1255 seginit(); 1256 lapicinit(); 1257 mpmain(); 1258 }

1260 // Common CPU setup code. 1261 static void 1262 mpmain(void) 1263 { 1264 cprintf("cpu%d: starting\n", cpu−>id); 1265 idtinit(); // load idt register 1266 xchg(&cpu−>started, 1); 1267 scheduler(); // start running processes 1268 }

Thank you