CHS (Cylinder-head-sector) https://www.partitionwizard.com/help/what-is-chs.html There're just stacked platters. Tracks: Each platter is divided into tracks that are concentric circles named *tracks* Cylinder: All the concentric tracks with same radius on all platters are vertically stacked into a cylinder. So, the cylinder value is the number of tracks on one side of each platter Head: every platter has 2 sides, so 2 heads Sector: segment of track, normally 512 bytes hard disk capacity = cylinder number × head number × sector number × 512 bytes. ================================================================================================== Carry bit and overflow bit http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt In signed arithmetic, watch the overflow flag to detect errors, the carry flag tells you nothing interesting. In unsigned arithmetic, watch the carry flag to detect errors, the overflow flag tells you nothing interesting. ================================================================================================== 16-bit Read mode For backward compatibility, it is important that CPUs boot initially in 16-bit real mode, requiring modern operating systems explicitly to switch up into the more advanced 32-bit (or 64-bit) protected mode, but allowing older operating systems to carry on, blissfully unaware that they are running on a modern CPU. =================================================================================================== Segments in 16-bit Real mode: eg. to store the value of ax at the address 0x4fe56 " mov bx, 0x4000 mov es, bx mov [es:0xfe56], ax " (es is a segment register) es multiplied by 16 and the offset (0xfe56) is added in 32-bit protected mode: a segment register becomes an index to a particular segment descriptor (SD) in the GDT (Global Descriptor Table) A segment descriptor is an 8-byte structure that defines the following properties of a protected-mode segment: • Base address (32 bits), which defines where the segment begins in physical memory • Segment Limit (20 bits), which defines the size of the segment • Various flags, which affect how the CPU interprets the segment, such as the privilige level of code that runs within it or whether it is read- or write-only. the CPU requires that the first entry in the GDT purposely be an invalid null descriptor (i.e. a structure of 8 zero bytes) =================================================================================================== I/O Ports https://github.com/cirosantilli/x86-bare-metal-examples/tree/b4e4c124a3c3c329dcf09a5697237ed3b216a318#5-in-and-out-instructions https://stackoverflow.com/a/3215958 https://www.felixcloutier.com/x86/out https://www.felixcloutier.com/x86/in eg. out al, dx (Input byte from I/O port in DX into AL) In Intel architecture systems the registers of device controllers are mapped into an I/O address space, that is seperate from the main memory address space Both RAM/ROM and IO devices are connected to the same address, data and control lines. For example, the serial port for COM1 is addressed starting at (hex) 03F8. But there's almost certainly memory at the same address. To distinguish between the two, one of the control lines called "M/#IO" asserts whether the CPU wants to talk to memory (line=high) or an I/O device (line=low). The IN instruction reads from an I/O device, OUT writes. **When you use the IN or OUT instructions, the M/#IO is not asserted (held low), so memory doesn't respond and the I/O chip does. ** For the memory-oriented instructions, M/#IO is asserted so CPU talks to the RAM, and IO devices stay out of the communication. image: https://i.stack.imgur.com/ra1Km.jpg Not all instruction sets have dedicated instructions such as in and out for IO. In ARM for example, everything is done by writing to magic memory addresses. The dedicated in and out approach is called "port-mapped IO", and the approach of the magic addresses "memory-mapped IO" From an interface point of view, I feel that memory mapped is more elegant: port IO simply creates a second addresses space =================================================================================================== Paging Paging is used to implement processes virtual address spaces on modern OS. With virtual addresses the OS can fit two or more concurrent processes on a single RAM in a way that: -both programs need to know nothing about the other -the memory of both programs can grow and shrink as needed -the switch between programs is very fast -one program can never access the memory of another process Page Directory -> Page Table -> Page entry https://stackoverflow.com/questions/18431261/how-does-x86-paging-work Each page table has 2^10 = 1K page directory entries Page faults occur if either a page directory entry or a page table entry is not present. https://stackoverflow.com/questions/24358105/do-modern-oss-use-paging-and-segmentation Modern OSes "do not use" segmentation. Its in quotes because they use 4 segments: Kernel Code Segment, Kernel Data Segment, User Code Segment and User Data Segment. What does it means is that all user's processes have the same code and data segments (so the same segment selector). The segments only change when going from user to kernel. So, all the path explained on the section 3.3. occurs, but they use the same segments and, since the page tables are individual per process, a page fault is difficult to happen. =================================================================================================== Segmentation Paging uses fixed size pages, segmentation uses variable sized segments The x86-64 architecture does not use segmentation in long mode (64-bit mode). https://unix.stackexchange.com/questions/469253/does-linux-not-use-segmentation-but-only-paging Linear Adress is created by adding logical address to the base of segment, CS,DS,ES,SS,FS or GS. eg. like mov rsi,[gs:rax] While the segmentation system (in 32-bit protected mode on an x86) is designed to support separate code, data and stack segments, in practice all the segments are set to the same memory area. That is, they start at 0 and end at the end of memory(*). That makes the logical addresses and linear addresses equal. This is called a "flat" memory model, and is somewhat simpler than the model where you have distinct segments and then pointers within them. In particular, a segmented model requires longer pointers, since the segment selector has to be included in addition to the offset pointer. (16-bit segment selector + 32 bit offset for a total of 48 bit pointer; versus just a 32-bit flat pointer.) So basically x86 segmentation is used for TLS(Thread Local Storage), and for the mandatory x86 osdev stuff that the hardware requires you to do. However, there is one thing that segmentation can do that paging can't, and that's set the ring level. A ring is a privilege level - zero being the most privileged, and three being the least. Processes in ring zero are said to be running in kernel-mode, or supervisor-mode, because they can use instructions like sti and cli, something which most processes can't. Normally, rings 1 and 2 are unused. They can, technically, access a greater subset of the supervisor-mode instructions than ring 3 can. Some microkernel architectures use these for running server processes, or drivers. =================================================================================================== Linear Address and Physical Address Linear Adress is created by adding logical address to the base of segment, CS,DS,ES,SS,FS or GS. eg. like mov rsi,[gs:rax] Linear address is generated after before page table mapping. Physical addres is generated before after page table mapping(ie paging). (logical) ------------------> (linear) ------------> (physical) segmentation paging When Paging is enabled, the page tables are used to translate linear address to physical address. On the Other Hand, Physical Address is nothing but, the address value that appears on pins of processor during a memory read/memory write operations. =================================================================================================== The Interrupt Descriptor Table The processor can register 'signal handlers' (interrupt handlers) that deal with the interrupt, then return to the code that was running before it fired. The Interrupt Descriptor Table tells the processor where to find handlers for each interrupt. It is very similar to the GDT. It is just an array of entries, each one corresponding to an interrupt number. There are 256 possible interrupt numbers, so 256 must be defined. The processor will sometimes need to signal your kernel. Something major may have happened, such as a divide-by-zero, or a page fault. To do this, it uses the first 32 interrupts https://web.archive.org/web/20160327011227/http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html =================================================================================================== 8259 PIC The 8259 Programmable Interrupt Controller (PIC) is one of the most important chips making up the x86 architecture. Without it, the x86 architecture would not be an interrupt driven architecture. The function of the 8259A is to manage hardware interrupts and send them to the appropriate system interrupt. This allows the system to respond to devices needs without loss of time (from polling the device, for instance). It is important to note that APIC has replaced the 8259 PIC in more modern systems, especially those with multiple cores/processors. =================================================================================================== IRQ External interrupts I understand it that IRQ are interrupt request from PIC to CPU, and ISR are internal CPU interrupts (like exceptions) The low-level concepts behind external interrupts are not very complex. All devices that are interrupt-capable have a line connecting them to the PIC (programmable interrupt controller). The PIC is the only device that is directly connected to the CPU's interrupt pin. It is used as a multiplexer, and has the ability to prioritise between interrupting devices. =================================================================================================== PSE (Page Size Extension) In traditional 32-bit protected mode, x86 processors use a two-level page translation scheme, where the control register CR3 points to a single 4 KiB-long page directory, which is divided into 1024 × 4-byte entries that point to 4 KiB-long page tables, similarly consisting of 1024 × 4-byte entries pointing to 4 KiB-long pages. Enabling PSE (by setting bit 4, PSE, of the system register CR4) changes this scheme. The entries in the page directory have an additional flag, in bit 7, named PS (for page size). This flag was ignored without PSE, but now, the page-directory entry with PS set to 1 does not point to a page table, but to a single large 4 MiB page. The page-directory entry with PS set to 0 behaves as without PSE. ===================================================================================================