Add BIOS disclaimer

This commit is contained in:
Ciro Santilli
2015-12-02 19:25:32 -02:00
parent 873c26a4ed
commit 893fdba02c
5 changed files with 168 additions and 10 deletions

View File

@@ -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
View File

@@ -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
View 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.

View File

@@ -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.

View File

@@ -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.