Presentation is loading. Please wait.

Presentation is loading. Please wait.

3. 32-Bits Protected Mode ENGI 3655 Lab Sessions.

Similar presentations


Presentation on theme: "3. 32-Bits Protected Mode ENGI 3655 Lab Sessions."— Presentation transcript:

1 3. 32-Bits Protected Mode ENGI 3655 Lab Sessions

2 Richard Khoury2 Textbook Readings  Segmentation ◦ Section 8.6  Pentium Segmentation ◦ Section 8.7.1

3 Richard Khoury3 16 Bits  We have this line at the beginning of our bootloaders [BITS 16]  Why? ◦ Obviously, because our code is 16 bits ◦ But our processors are 32 bits, so again, why? ◦ Because our CPU is in 16-bits Real Mode

4 Richard Khoury4 A Bit of History  In real mode, any program has direct access to the computer resources ◦ Including all addresses in memory, the hardware and the BIOS interrupts, no protection whatsoever  The slightest mistake in a program causes the computer to crash  That’s the way all user programs were done originally

5 Richard Khoury5 A Bit of History  Soon, people realised that programmers cannot be trusted with that power  Needed some control ◦ Memory protection ◦ Multitasking while keeping all programs safe from each other ◦ Hardware-enforced protection and limits on what user programs can do  CPU Protected Mode ◦ As opposed to Real Mode

6 Richard Khoury6 A Bit of History  In the mean time, memory was becoming cheaper and cheaper, while programs needed more and more of it  8086 CPU was connected to 20 bit memory address bus ◦ 2 20 ≈ 1 MB main memory (conventional memory) ◦ But with 16-bit registers, only the first 64k were easily accessible directly ◦ Higher memory regions required awkwardly adjusting the segment registers ◦ That was another limitation in real mode

7 Richard Khoury7 A Bit of History  Over time, memory address bus was expanded to 24 bits, then 32 bits (today 64 bits) ◦ 2 32 ≈ 4 GB (extended memory) ◦ New 32-bit CPU extended registers allowed programs to access the entire 4GB range in one operation 16 bits8 bits ahal ax eax

8 Richard Khoury8 A Bit of History  Intel 8086/80186 ◦ 1979/1982 ◦ 16 bits with a 20-bit bus, real mode only  Intel 80286 ◦ 1982 ◦ 16 bits with a 24-bit bus ◦ Protected mode, but with too many limitations  Intel 80386 ◦ 1986 ◦ 32 bits ◦ Fully-functional protected mode ◦ Still used in many aerospace systems  Intel 80486 ◦ 1989 ◦ Internal cache  Intel Pentium (80586) ◦ 1993 ◦ 32 bits with a 64-bit bus

9 Richard Khoury9 16 Bits  Operating systems ◦ Runs in 32 bits protected mode to benefit from up to 4GB of main memory, virtual memory, paging, safe multitasking, and hardware-enforced user/kernel protection rings  However, Intel designed its 80x86 to be backward compatible ◦ They all start in 16-bit real mode, like the 8086 ◦ Therefore, our bootloader runs in 16-bit real mode ◦ It is part of the stage-2 bootloader’s function to switch the CPU to 32-bit protected mode

10  Enable memory protection & segmentation ◦ Set up the Global Descriptor Table  Enable 32-bit memory addressing ◦ Activate Gate A20  Read the Kernel into memory ◦ I’ll give you a free one  Enter Protected Mode ◦ Switch the CPU to Protected Mode and jump to the Kernel In This Lab Richard Khoury10

11 Richard Khoury11 Memory Protection  In protected mode, our program cannot access memory directly like it did in real mode  Instead, memory will be divided in segments ◦ Each segment has clear boundaries and a privilege setting  Information on the segments is kept in the Global Descriptor Table (GDT) ◦ Your program accesses memory through the GDT ◦ The OS double-checks in the CPU’s GDT that the program has the correct privileges and that the address is in the segment

12 Richard Khoury12 Global Descriptor Table  Bootloader must set it up before entering protected mode  Descriptor is a 64-bit (8 bytes) data structure  Null Descriptor ◦ All zeros  Code Descriptor ◦ This memory area contains executable code  Data Descriptor ◦ This memory area contains data

13 Richard Khoury13 Descriptors  Bits 0-15: Segment limit (low 16 bits)  Bits 16-39: Base address, start of segment (low 24 bits)  Bit 40: Access bit for virtual memory  Bits 41-43: Descriptor type ◦ Bit 41: Read/Write bit  0: Read only (Data Segments); Execute only (Code Segments)  1: Read and write (Data Segments); Read and Execute (Code Segments) ◦ Bit 42: Expansion direction (Data segments), conforming (Code Segments) ◦ Bit 43: Executable segment  0: Data Segment  1: Code Segment

14 Richard Khoury14 Descriptors  Bit 44: Descriptor Bit ◦ 0: System Descriptor ◦ 1: Code or Data Descriptor  Bits 45-46: Descriptor Privilege Level ◦ 00: Ring 0, Highest (kernel) ◦ 01: Ring 1 ◦ 10: Ring 2 ◦ 11: Ring 3, Lowest (user)  Bit 47: Segment is in memory (Virtual Memory)

15 Richard Khoury15 Descriptors  Bits 48-51: Segment limit (high 4 bits)  Bits 52-53: Reserved (should be 0)  Bit 54: Segment type ◦ 0: 16 bit ◦ 1: 32 bit  Bit 55: Granularity of the segment ◦ 0: Byte (1 byte) ◦ 1: Page (4kB) (that is 4096B, or 1000h)  Bits 56-63: Base address (high 8 bits)

16 Descriptor Implementation  Eventually, we can divide the memory into segments for each program ◦ Each memory access will be checked against the segment base, size, and priority level  But to begin, the 80x86 requires a flat memory model ◦ Null descriptor (all zeros) ◦ Kernel-mode code descriptor ◦ Kernel-mode data descriptor ◦ User-mode code descriptor ◦ User-mode data descriptor

17  Our initial segments ◦ Cover entire 4GB memory range  Base 0x0, limit 0xFFFFF, granularity 4kB  Note: Size of a segment is: base + (limit + 1)*granularity = 1 0000 0000  Note: Final limit address is: size – 1 = FFFF FFFF ◦ Do not use virtual memory  VM access bit = 0; VM segment in memory bit = 1 ◦ Not read-only ◦ 32-bit segments types ◦ Expansion direction bit = 0 Descriptor Implementation Richard Khoury17

18  You cannot define 64 bits at once  But you can define bytes (8 bits) and words (16 bits)  You can write in hex or binary  Order matters! ◦ The first word (16 bits) are before the next byte ◦ The right-hand bits of the byte are before the left- hand bits Descriptor Implementation Richard Khoury18 dw FFFFh db 11001111b

19 Lab, Part 1  Write the five descriptors we need ◦ In GDT.inc  Later, our OS will switch between user and kernel mode by changing which memory segment we point to

20 Richard Khoury20 Global Descriptor Table  To load the GDT into a CPU register, we need to define pointers to it ◦ Put labels gdt_data: and end_of_gdt: at the beginning and end of the GDT ◦ Define a pointer with the size minus one and the start of the GDT toc: dw end_of_gdt - gdt_data - 1 dd gdt_data ; base of GDT  The GDT is loaded into a special register in the CPU, the GDTR, using a special “load GDT” instruction lgdt [toc]

21 Richard Khoury21 More History  The original 8086 had a 20-line address bus ◦ Lines A0 to A19  The bus was expanded to 24 lines on the 80286, then 32 lines on the 80386 ◦ Adding lines A20 to A23/A31  To maintain backward compatibility, these have to be deactivated at boot-up ◦ Intel added a logic gate on line A20 to control it ◦ We’ll have to activate Gate A20 to be able to use all available memory

22 Richard Khoury22 Enabling Gate A20  Intel needed to add a hardware gate and a pin somewhere to control it  The keyboard controller happened to have a free pin  Therefore, the way to control Gate A20 and enable higher memory is through the keyboard ◦ I’m not even kidding here

23 Richard Khoury23 Keyboard Controller  Our bootloader will need to send commands to the keyboard controller  The keyboard controller uses two 8-bit ports in either read or write mode  0x60 data input/output port ◦ Read output buffer ◦ Write input buffer  0x64 command/status port ◦ Read status register ◦ Send command to controller

24 Keyboard Controller  0x64 read mode: Status register  Bit 0: Output Buffer Status ◦ 0: Output buffer empty, don’t read ◦ 1: Output buffer full, ready to read  Bit 1: Input Buffer Status ◦ 0: Input buffer empty, can be written ◦ 1: Input buffer full, don’t write  Bit 2: System flag ◦ 0 on power on, 1 after keyboard self test  Bit 3: Command Data ◦ 0/1 = last write was data/command  Bit 4: Keyboard Locked ◦ 0/1 = locked/not locked  Bit 5: Auxiliary Output buffer full ◦ 0/1 = OK/timeout  Bit 6: Timeout ◦ 0/1 = OK/timeout  Bit 7: Parity error ◦ 0/1 = OK/parity error

25 Keyboard Controller  0x64 write mode: send command to controller  0xAD ◦ Disable Keyboard  0xAE ◦ Enable Keyboard  0xD0 ◦ Read Output Port  0xD1 ◦ Write Input Port

26 Keyboard Controller  0x60 input/output port: 8 bits  Bit 0: System Reset  Bit 1: A20 ◦ 0: A20 disabled ◦ 1: A20 enabled  Bits 2-3: Undefined  Bit 4: Input buffer full  Bit 5: Output buffer empty  Bit 6: Keyboard Clock  Bit 7: Keyboard Data

27 Enabling Gate A20  Activating A20 can be done through four commands to the keyboard controller ◦ Disable keyboard ◦ Read output port ◦ (Set bit #1 to 1) ◦ Write input port ◦ Enable keyboard  Lab, part 2: do this

28 Useful Functions  IN ◦ Transfer byte from a controller port to the AL register ◦ IN al, port#  OUT ◦ Transfer byte from the AL register to a controller port ◦ OUT port#, al  TEST ◦ Compare a register to a given value without changing either of them ◦ TEST al, # ◦ Will clear the CF flag if they are different, or set it if they are identical ◦ Can then be followed by a jump, like JNZ or JZ

29 Useful Functions  Before each write, you should check that the input buffer is empty and can be written ◦ Read 0x64 and test input buffer status  All other bits will be 0 ◦ Loop if not ready to write  Before each read, you should check that the output buffer is full and ready to read ◦ Read 0x64 and test output buffer status  All other bits will be 0 ◦ Loop if not ready to read

30 Richard Khoury30 Entering Protected Mode  Now the GDT is loaded and Gate A20 is activated  We can finally switch to Protected Mode

31 Richard Khoury31 Entering Protected Mode  Protected Mode is a mode of operation of the processor  Behaviour of processor is controlled by the Control Registers (CR)  There are five CR in the 80x86 ◦ CR0 controls a number of general behaviours ◦ CR1 is reserved by Intel ◦ CR2 controls the Page Fault Linear Address ◦ CR3 controls memory paging, and includes the Page Directory Base Register ◦ CR4 controls behaviour while in protected mode  Which one should we look at?

32 Richard Khoury32 CR0  32-bit register primary control register  Bit 0: Protected Mode Enable (PE) ◦ 0/1 = Real mode/Protected mode  Bit 1: Monitor co-processor (MP) ◦ Controls the operation of the WAIT & FWAIT instructions  Bit 2: Emulation (EM) ◦ 0/1 = floating point units activated/deactivated  Bit 3: Task Switched (TS) ◦ Set to 1 when processor switches to another task, to allow saving context  Bit 4: Extension Type (ET) ◦ 0/1 = coprocessor is 80287/80387

33 Richard Khoury33 CR0  Bit 5: Numeric Error (NE) ◦ 0 - Enable standard error reporting ◦ 1 - Enable internal x87 FPU error reporting  Bits 6-15 : Unused  Bit 16: Write Protect (WP)  Bit 17: Unused  Bit 18: Alignment Mask (AM) ◦ 0/1 = Alignment Check Disabled/Enabled  Bits 19-28: Unused  Bit 29: Not Write-Through (NW)  Bit 30: Cache Disable (CD)  Bit 31: Paging (PG) ◦ 0/1 = Memory Paging Disabled/Enabled ◦ When enabled, CR3 is used

34 Richard Khoury34 Entering Protected Mode  Bit 0: Protected Mode Enable (PE) ◦ 0/1 = Real mode/Protected mode ◦ At booting, that bit is 0, it needs to be switched to 1 to enter protected mode mov eax, cr0 or eax, 1 mov cr0, eax  Before we do, we need to disable interrupts cli ◦ We cannot re-enable them after; protected mode does not allow BIOS interrupts

35 Richard Khoury35 Reading the Kernel  The final task of the bootloader is to read the OS kernel into memory and jump to it  We will write the kernel next week ◦ For now, use “kernel.bin” from the website

36 Richard Khoury36 Reading the Kernel  We already know how to find files on a FAT12 disk and how to read them into memory ◦ BIOS Interrupt 13h  We’ll need to add this ability to our second- stage bootloader  However, BIOS interrupts are not usable from protected mode ◦ We’ll do it in real mode

37 Richard Khoury37 Reading the Kernel  Next, we want to put the kernel at 1MB in memory ◦ Right after the end of conventional memory accessible by 20-bit real mode ◦ Beginning of extended memory ◦ But that area is not accessible in real mode! ◦ We’ll have to do that in protected mode  So we have a problem ◦ We can only read the disk in real mode and access the memory in protected mode

38 Richard Khoury38 Stage 2 Bootloader Structure  Install GDT  Enable Gate A20  Read Kernel into Lower Memory  Enter Protected Mode  Copy Kernel to 1MB in Memory  Jump to Kernel

39 Richard Khoury39 Reading the Kernel  Reading the Kernel from disk to lower memory is done as before ◦ Use FAT-handling functions from lab 2 included in “FAT12.inc” ◦ Notice that our LoadFile function kept a count of sectors read popecx incecx pushecx  Copy “kernel.bin” to 0x3000 (unused region of conventional memory)

40 Richard Khoury40 Reading the Kernel  After we’re in Protected Mode, we want to copy it to 1MB in memory (address 0x100000) moveax, dword [ImageSize] movzxebx, word [bpbBytesPerSector] mulebx movebx, 4 divebx cld movesi, IMAGE_RMODE_BASE movedi, IMAGE_PMODE_BASE movecx, eax repmovsd

41 Richard Khoury41 Reading the Kernel  Compute size to copy (in double-words) in ECX ◦ The size of the kernel in sectors is stored in ImageSize after our FAT12 function ◦ The size of a sector in bytes is known from the BPB ◦ A double-word is two words, or four bytes ◦ CX=(size of kernel in sectors) * (bytes per sector) / 4 ◦ MOVZX : copy a 16-bit source to a 32-bit destination, fill with 0

42 Richard Khoury42 Reading the Kernel  Copy! ◦ Set copy direction from left to right ◦ Move origin in DS:SI and destination in ES:DI ◦ movsd moves double-words from DS:SI to ES:DI ◦ rep repeats it for CX times

43 Richard Khoury43 Reading the Kernel  Once the copying is done, simply jump to the kernel’s memory position  Only jump allowed in Protected Mode is Descriptor:Address far jump jmp CODE_DESC:0x100000  And that’s the end of the bootloader!

44 Lab Assignment  New files: ◦ Gdt.inc, which contains the declaration of the GDT and the function to load it ◦ A20.inc, which contains the function to enable the A20 line ◦ Stage-2 Bootloader that calls these functions ◦ A compiled Kernel

45 Richard Khoury45 Lab Assignment  Write the five GDT descriptors  Write the function to make the keyboard controller activate line A20  With this, our second-stage bootloader is complete!


Download ppt "3. 32-Bits Protected Mode ENGI 3655 Lab Sessions."

Similar presentations


Ads by Google