Add BIOS disclaimer
This commit is contained in:
@@ -67,9 +67,6 @@ Minimal operating systems to learn low level programming.
|
||||
1. [UEFI](uefi/)
|
||||
1. Misc
|
||||
1. [hajji](hajji/)
|
||||
1. Tests
|
||||
1. [PRINT_BYTES](test_print_bytes.S)
|
||||
1. [PRINT_BYTES](test_pit_sleep.S)
|
||||
1. Theory
|
||||
1. [Modes of operation](modes-of-operation.md)
|
||||
1. [Segmentation](segmentation.md)
|
||||
@@ -81,4 +78,8 @@ Minimal operating systems to learn low level programming.
|
||||
1. [PIC](pic.md)
|
||||
1. [Debug](debug.md)
|
||||
1. [Bibliography](bibliography.md)
|
||||
1. Tests
|
||||
1. [PRINT_BYTES](test_print_bytes.S)
|
||||
1. [PRINT_BYTES](test_pit_sleep.S)
|
||||
1. [TODO](TODO.md)
|
||||
1. [ring](ring.md)
|
||||
|
||||
10
bios.md
10
bios.md
@@ -1,5 +1,9 @@
|
||||
# BIOS
|
||||
|
||||
Old, non-standardized, limited API that allows you to do quick and dirty IO.
|
||||
|
||||
If you are making a serious OS, use it as little as possible.
|
||||
|
||||
<https://en.wikipedia.org/wiki/BIOS>
|
||||
|
||||
<http://wiki.osdev.org/BIOS>
|
||||
@@ -67,12 +71,6 @@ Standardized by: <https://en.wikipedia.org/wiki/Distributed_Management_Task_Forc
|
||||
|
||||
TODO: how is it obtained at the low level?
|
||||
|
||||
## UEFI
|
||||
|
||||
<https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface>
|
||||
|
||||
<https://github.com/tqh/efi-example>
|
||||
|
||||
## SeaBIOS
|
||||
|
||||
<http://www.seabios.org/SeaBIOS>
|
||||
|
||||
17
ring.md
Normal file
17
ring.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Ring
|
||||
|
||||
IA-32 implements a hardware protection privilege system.
|
||||
|
||||
Rings are implemented together with the segmentation system.
|
||||
|
||||
There are in total 4 privilege levels, also called rings, from 0 to 3, 0 being the one with the highest privilege.
|
||||
|
||||
Most operating systems use only 2: kernel space and user space, usually with values 0 and 3. This is the case for Linux.
|
||||
|
||||
For each ring, a certain set of operations is allowed by the processor.
|
||||
|
||||
Rings are useful for OS programmers. The OS lets user programs run a restricted set of operations limiting the amount of damage that a badly working or badly intentioned program can do. Obviously this only works because user programs are then in a state in which they cannot modify their own privilege levels without the OS intervening.
|
||||
|
||||
Certain operations such are only allowed if certain privileges are given.
|
||||
|
||||
Privilege control is only available on protected mode, and is managed by segmentation and paging.
|
||||
141
segmentation.md
141
segmentation.md
@@ -1,7 +1,146 @@
|
||||
# Segmentation
|
||||
|
||||
This is about protected mode segmentation, which coverts liner to global addresses.
|
||||
TODO this section is a mess. Organize and slit it up.
|
||||
|
||||
Described on the AMD64 manual vol. 2 Chapter 4 - Segmentation.
|
||||
|
||||
Makes the transition from logical to linear addresses. Linear addresses are then converted to physical addresses (those that go to RAM wires) by the paging circuits:
|
||||
|
||||
(logical) ------------------> (linear) ------------> (physical)
|
||||
segmentation paging
|
||||
|
||||
Segmentation does not exist anymore in x86-64 64-bit mode: only in compatibility mode.
|
||||
|
||||
This feature was initially meant to be used to implement process virtual memory spaces, but this usage has been mostly supplanted by a later implemented feature called paging. This is probably why it was dropped in x86-64.
|
||||
|
||||
The main difference between paging and segmentation is that the size of pages if fixed, while the size of segments can vary and is indicated inside the segment descriptor.
|
||||
|
||||
Besides address translation, the segmentation system also manages of other features, such as the privilege level of execution (ring) functionality which is still widely used, and compatibility mode.
|
||||
|
||||
In Linux 32-bit for example, only two segments are used at all times: one at ring 0 for the kernel, and one another at privilege 3 for all user processes. TODO draw.
|
||||
|
||||
## Hardware implementation
|
||||
|
||||
Like paging, the segmentation transformation needs to happen on every memory read and write. For this reason, it is implemented *by the hardware*.
|
||||
|
||||
The processor manual says something like:
|
||||
|
||||
- when segmentation is turned on
|
||||
- I will look for segmentation information (local and global descriptor tables) at the RAM physical address at my register X, which can be read and set by the `gdtr`, `ldtr`, `lgdt` and `lldt` instructions.
|
||||
- the local and global descriptor tables must have to have the following format
|
||||
- using that information on RAM, I will decide how to do the address translation and every other function of the segmentation system
|
||||
|
||||
It is then OS to set up and manage those RAM data structures and CPU registers to make the CPU do what it wants.
|
||||
|
||||
## Global descriptor table
|
||||
|
||||
RAM data structure that holds segment information.
|
||||
|
||||
The segment information data structure is called a *segment descriptor*.
|
||||
|
||||
Each segment descriptor is identified and retrieved via a *segment selector* structure.
|
||||
|
||||
### Local descriptor table
|
||||
|
||||
TODO vs global?
|
||||
|
||||
## Segment selector
|
||||
|
||||
A segment selector is a 16 bit structure that identifies the current segment descriptor and the current privilege level.
|
||||
|
||||
It has the following fields:
|
||||
|
||||
- index: 13 bits to identify the Segment descriptor within the current table.
|
||||
|
||||
There can therefore be up to 2^13 segment descriptors on a table.
|
||||
|
||||
The current table is determined by the values of `gdtr` and `ldtr` registers and by the TI bit of the segment selector.
|
||||
|
||||
- `RPL`: Request privilege level.
|
||||
|
||||
The privilege level of the code that will execute a Code segment.
|
||||
|
||||
- `TI`: 1 bit table indicator. If set, indicates that this is a local descriptor table.
|
||||
|
||||
Otherwise, it is a global descriptor table.
|
||||
|
||||
## Segment descriptor
|
||||
|
||||
Segment descriptors are kept in RAM, and are used by the hardware to translate logic to linear addresses.
|
||||
|
||||
It is up to the OS to set up and maintain segment descriptors on the RAM, and to inform the hardware of its location via the `gdtr` and `ldtr` registers The OS can modify those registers via the `lgdt` and `lldt` instructions.
|
||||
|
||||
Segment descriptors are kept inside tables which contain many contiguous segment descriptors called either global descriptor table or local descriptor table.
|
||||
|
||||
Each segment descriptor is 8 bytes long, and contains information such as the following.
|
||||
|
||||
- BASE: 32 bit start address and end address of the segment
|
||||
|
||||
- LIMIT: 20 bit segment length. This is multiplied by $2^12$ if G is set so the maximum length is 4GB ($2^32$).
|
||||
|
||||
Minimum length is 4 Kb.
|
||||
|
||||
- G: granularity flat. If set, LIMIT is in multiples of $2^12$ bytes, else multiples of 1 byte.
|
||||
|
||||
- DPL: 2 bit privilege level.
|
||||
|
||||
Compared to the privilege level of the Segment Selector to determine if users have or not permission to take certain actions ( the rings are based on this )
|
||||
|
||||
- Type: 4 bit type field. Some of the types are:
|
||||
|
||||
- Code: indicates a code segment. It is on this case the permissions to take actions are checked.
|
||||
|
||||
- Data:
|
||||
|
||||
- TSSD: task state segment descriptor. The segment contains saved register values (between process sleeps)
|
||||
|
||||
- LDTD: the segment contains a local descriptor table
|
||||
|
||||
- S: system
|
||||
|
||||
If set, indicates that the RAM of that segment contains important structures such as Local descriptor table.
|
||||
|
||||
The current segment descriptor is determined by the current segment selector and the values of the `gdtr` and `ldtr` registers.
|
||||
|
||||
## Segment registers
|
||||
|
||||
Segment registers contain segment selectors
|
||||
|
||||
There are 6 segment registers.
|
||||
|
||||
3 have special meanings:
|
||||
|
||||
- CS: code segment
|
||||
- SS: TODO
|
||||
- DS: data segment
|
||||
|
||||
And the other three don't and are free for programmer use.
|
||||
|
||||
- ES
|
||||
- FG
|
||||
- GS
|
||||
|
||||
Segment selectors can be put into those segment registers via `mov` instructions.
|
||||
|
||||
Each segment selector has an associated read only register which contains the corresponding segment descriptor to that selector.
|
||||
|
||||
Segment descriptors are pulled into dedicated processor registers automatically when a segment register changes value.
|
||||
|
||||
This allows to read segment descriptors from RAM only once when segments change, and access them directly from the CPU the following times.
|
||||
|
||||
TODO which of those segments are used at each time?
|
||||
|
||||
## Segment descriptor types
|
||||
|
||||
TODO what is the difference between types?
|
||||
|
||||
## Example of address translation
|
||||
|
||||
TODO very important. One example, two programs running. Logical to linear address translation.
|
||||
|
||||
## Linux
|
||||
|
||||
TODO How Linux uses segments.
|
||||
## GDT
|
||||
|
||||
Table in memory that gives properties of segment registers.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Successor for BIOS.
|
||||
|
||||
<https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface>
|
||||
|
||||
Made by Intel, mostly MIT open source, but vendors do modify it.
|
||||
|
||||
Matthew Garrett says it is huge: larger than Linux without drivers. Like BIOS, it is a "mini-OS".
|
||||
@@ -15,6 +17,7 @@ TODO get a hello world program working:
|
||||
- http://www.rodsbooks.com/efi-programming/hello.html Best source so far: allowed me to compile the hello world! TODO: how to run it now on QEMU and real hardware?
|
||||
- https://fedoraproject.org/wiki/Using_UEFI_with_QEMU
|
||||
- https://wiki.ubuntu.com/UEFI/OVMF
|
||||
- https://github.com/tqh/efi-example
|
||||
|
||||
Running without image gives the UEFI shell, and a Linux kernel image booted fine with it: http://unix.stackexchange.com/a/228053/32558 , so we just need to generate the image.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user