Nytro Posted July 17, 2017 Report Posted July 17, 2017 Writing a Simple Operating System — from Scratch by Nick Blundell School of Computer Science, University of Birmingham, UK Draft: December 2, 2010 Copyright c 2009–2010 Nick Blundell Contents Contents ii 1 Introduction 1 2 Computer Architecture and the Boot Process 3 2.1 The Boot Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2 BIOS, Boot Blocks, and the Magic Number . . . . . . . . . . . . . . . . 4 2.3 CPU Emulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.3.1 Bochs: A x86 CPU Emulator . . . . . . . . . . . . . . . . . . . 6 2.3.2 QEmu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.4 The Usefulness of Hexadecimal Notation . . . . . . . . . . . . . . . . . . 6 3 Boot Sector Programming (in 16-bit Real Mode) 8 3.1 Boot Sector Re-visited . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.2 16-bit Real Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.3 Erm, Hello? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.3.1 Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.3.2 CPU Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.3.3 Putting it all Together . . . . . . . . . . . . . . . . . . . . . . . 11 3.4 Hello, World! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.4.1 Memory, Addresses, and Labels . . . . . . . . . . . . . . . . . . 13 3.4.2 ’X’ Marks the Spot . . . . . . . . . . . . . . . . . . . . . . . . . 13 Question 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.4.3 Defining Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.4.4 Using the Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Question 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.4.5 Control Structures . . . . . . . . . . . . . . . . . . . . . . . . . 17 Question 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.4.6 Calling Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.4.7 Include Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.4.8 Putting it all Together . . . . . . . . . . . . . . . . . . . . . . . 21 Question 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.4.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 ii CONTENTS iii 3.5 Nurse, Fetch me my Steth-o-scope . . . . . . . . . . . . . . . . . . . . . 22 3.5.1 Question 5 (Advanced) . . . . . . . . . . . . . . . . . . . . . . . 23 3.6 Reading the Disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.6.1 Extended Memory Access Using Segments . . . . . . . . . . . . 23 3.6.2 How Disk Drives Work . . . . . . . . . . . . . . . . . . . . . . . 24 3.6.3 Using BIOS to Read the Disk . . . . . . . . . . . . . . . . . . . 27 3.6.4 Putting it all Together . . . . . . . . . . . . . . . . . . . . . . . 28 4 Entering 32-bit Protected Mode 30 4.1 Adapting to Life Without BIOS . . . . . . . . . . . . . . . . . . . . . . . 31 4.2 Understanding the Global Descriptor Table . . . . . . . . . . . . . . . . 32 4.3 Defining the GDT in Assembly . . . . . . . . . . . . . . . . . . . . . . . 35 4.4 Making the Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 4.5 Putting it all Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 5 Writing, Building, and Loading Your Kernel 41 5.1 Understanding C Compilation . . . . . . . . . . . . . . . . . . . . . . . . 41 5.1.1 Generating Raw Machine Code . . . . . . . . . . . . . . . . . . 41 5.1.2 Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 5.1.3 Calling Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 46 5.1.4 Pointers, Addresses, and Data . . . . . . . . . . . . . . . . . . . 47 5.2 Executing our Kernel Code . . . . . . . . . . . . . . . . . . . . . . . . . 49 5.2.1 Writing our Kernel . . . . . . . . . . . . . . . . . . . . . . . . . 50 5.2.2 Creating a Boot Sector to Bootstrap our Kernel . . . . . . . . . 50 5.2.3 Finding Our Way into the Kernel . . . . . . . . . . . . . . . . . 53 5.3 Automating Builds with Make . . . . . . . . . . . . . . . . . . . . . . . . 54 5.3.1 Organising Our Operating System’s Code Base . . . . . . . . . 57 5.4 C Primer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 5.4.1 The Pre-processor and Directives . . . . . . . . . . . . . . . . . 59 5.4.2 Function Declarations and Header Files . . . . . . . . . . . . . . 60 6 Developing Essential Device Drivers and a Filesystem 62 6.1 Hardware Input/Output . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 6.1.1 I/O Buses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 6.1.2 I/O Programming . . . . . . . . . . . . . . . . . . . . . . . . . . 63 6.1.3 Direct Memory Access . . . . . . . . . . . . . . . . . . . . . . . 65 6.2 Screen Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 6.2.1 Understanding the Display Device . . . . . . . . . . . . . . . . . 65 6.2.2 Basic Screen Driver Implementation . . . . . . . . . . . . . . . . 65 6.2.3 Scrolling the Screen . . . . . . . . . . . . . . . . . . . . . . . . . 69 6.3 Handling Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 6.4 Keyboard Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 6.5 Hard-disk Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 6.6 File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 7 Implementing Processes 71 7.1 Single Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 7.2 Multi-processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 CONTENTS iv 8 Summary 72 Bibliography 73 Download: http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf 1 Quote