Programmers and segmentation in operating systems - operating-system

I'm learning that segmentation in operating systems is based on dividing different segments (for a program, these could represent a symbol table, the source text, the stack...) into units that start at logical memory address 0. This is the virtual address that the MMU (?) uses to get the real in addition to the offset.
An apparent benefit of segmentation is that, since each segment starts at address 0, multiple processes can take advantage of a single segment simultaneously (an example is the shared library).
However, I don't see how else segmentation can benefit programmers. What would be some examples?
Thanks!

Segmentation provides NO benefit to programmers. Segmentation is a kludge that developed to overcome architectural limits. The 16-bit PDP-11 computers could only address 64K of memory. The use of a segmentation allowed the programmer to map memory in and out of the address space to access more memory.
The 8086 chip was retrograde. IBM set the computer industry back by years using it for the PC rather than 68000. The 8086 used segments to reduce the size of instructions. Rather than using 32-bits for an address, instructions could use am offset from a segment register.
In 64-bit mode, the abomination of segments in the Intel processors finally goes away.

Related

Why does registers exists and how they work together with cpu?

So I am currently learning Operating Systems and Programming.
I want how the registers work in detail.
All I know is there is the main memory and our CPU which takes address and instruction from the main memory by the help of the address bus.
And also there is something MCC (Memory Controller Chip which helps in fetching the memory location from RAM.)
On the internet, it shows register is temporary storage and data can be accessed faster than ram for registers.
But I want to really understand the deep-down process on how they work. As they are also of 32 bits and 16 bits something like that. I am really confused.!!!
I'm not a native english speaker, pardon me for some perhaps incorrect terminology. Hope this will be a little bit helpful.
Why does registers exists
When user program is running on CPU, it works in a 'dynamic' sense. That is, we should store incoming source data or any intermediate data, and do specific calculation upon them. Memory devices are needed. We have a choice among flip-flop, on-chip RAM/ROM, and off-chip RAM/ROM.
The term register for programmer's model is actually a D flip-flop in the physical circuit, which is a memory device and can hold a single bit. An IC design consists of standard cell part (including the register mentioned before, and and/or/etc. gates) and hard macro (like SRAM). As the technology node advances, the standard cells' delay are getting smaller and smaller. Auto Place-n-Route tool will place the register and the related surrounding logic nearby, to make sure the logic can run at the specified 3.0/4.0GHz speed target. For some practical reasons (which I'm not quite sure because I don't do layout), we tend to place hard macros around, leading to much longer metal wire. This plus SRAM's own characteristics, on-chip SRAM is normally slower than D flip-flop. If the memory device is off the chip, say an external Flash chip or KGD (known good die), it will be further slower since the signals should traverse through 2 more IO devices which have much larger delay.
how they work together with cpu
Each register is assigned a different 'address' (which maybe not open to programmer). That is implemented by adding address decode logic. For instance, when CPU is going to execute an instruction mov R1, 0x12, the address decode logic sees the binary code of R1, and selects only those flip-flops corresponding to R1. Then data 0x12 is stored (written) into those flip-flops. Same for read process.
Regarding "they are also of 32 bits and 16 bits something like that", the bit width is not a problem. Both flip-flops and a word in RAM can have a bit width of N, as long as the same address can select N flip-flops or N bits in RAM at one time.
Registers are small memories which resides inside the processor (what you called CPU). Their role is to hold the operands for fast processor calculations and to store the results. A register is usually designated by a name (AL, BX, ECX, RDX, cr3, RIP, R0, R8, R15, etc.) and has a size which is the number of bits it can store (4, 8, 16, 32, 64, 128 bits). Other registers have special meanings, and their bits control the state or provide information about the state of the processor.
There are not many registers (because they are very expensive). All of them have a capacity of only a few kilobytes, so they can't store all the code and data of your program, which can go up to gigabytes. This is the role of the central memory (what you call RAM). This big memory can hold gigabytes of data and each byte has its address. However, it only holds data when the computer is turned on. The RAM reside outside of the CPU Chip and interacts with him via Memory Controller Chip which stands as interface between CPU and RAM.
On top of that, there is the hard drive that stores your data when you turn off your computer.
That is a very simple view to get you started.

advantages of segmentation in 8086 microprocessor

what are the advantages of segmentation in 8086 microprocessor?
Not getting the importance of segmentation. Is it for managing more memory?
The instruction set used in 8086 is a 16-bit instruction set. This means that a register can only store values in the range 0x0000 to 0xFFFF, and instructions mostly only did 16-bit operations (16-bit addition, 16-bit subtraction, etc). If a register contains an address/pointer, then it would've worked out to a maximum of 64 KiB of address space (some for ROMs, some for RAM) and this wasn't enough for the market at the time.
Segmentation was a way to allow the 16-bit CPU to support a larger address space. Essentially, combining two 16-bit registers together, so that addresses/pointers could be much larger. Unfortunately (likely, to avoid "unnecessary at the time" costs of having more address lines on the CPU's bus), instead of using two 16-bit registers as a 32-bit address, Intel did an "address = segment * 16 + offset" thing to end up with a 20-bit address, giving the 8086 a 1 MiB address space.
Later (early 1980s) there was a push towards "protected objects" where "objects" (in object oriented programming) could be given access controls and limits that are enforced/checked by hardware, and around the same time there were "virtual memory" ideas floating around. These ideas led to the ill-fated iAPX 432 CPU; but also led to the idea of associating protection (attributes and limits) to the segments that 8086 already had, which resulted in the "protected mode" introduced with 80286 (and extended in 80386).
Essentially; the original reason for (advantage of) segments was to increase the address space (without the cost of a 32-bit instruction set, etc); and things like protection and memory management were retro-fitted afterwards (and then barely used by software before being abandoned in favour of paging).
Answer
Memory size is divided into segments of various sizes.
A segment is just area in memory.
Process of dividing memory in this way is called segmentation.
data ----> bytes -----> specific address.
8086 has 20 lines address bus.
2^20 bytes = 1Mb
4 types of Segments
Code Segment
Data Segment
Stack Segment
Extra Segment
Each of these segments are addressed by an address stored in corresponding segment address.
registers are 16 bit in size.
store base address of corresponding segments and store upper 16 bits.

Kernel high memory

In Operating System Design the kernel is most always mapped to a high virtual memory address, thus gaining control of the upper memory part. The space left below is for applications running in user space, as described in an excellent way in "Linux 3/1 virtual address split".
What I'd like to know is, why is this design decision made or why the kernel does not use the lower part of memory? This is not really clear to me, or maybe I've overseen something.
Edit: This question regards virtual addresses and not physical.
Some advantages of/reasons for such a design:
Applications don't need to care about the size and location of the kernel and may pretend they're the only ones in the memory, starting at around 0 and spanning upwards, with minimal or no code and data relocations. Applications are hence easier to design and implement and they may be less likely to have bugs related to mememory management.
Applications may use smaller/shorter addresses/pointers and hence save some memory.
In the x86 CPU, 16-bit and 32-bit address spaces start at virtual address 0 and end at around 1MB (for real and virtual 8086 modes), 16 MB (16-bit protected mode on i80286+) and 4 GB (32-bit mode, unreal mode). Placing the kernel at lower addresses will reduce the range of addresses available to applications (ex: 16-bit app in 32-bit mode or 32-bit app in 64-bit mode) and/or complicate their memory management. Moving the kernel to the top of the virtual address space generally makes sense on the x86.
There may be other reasons, usually platform-specific. On some platforms there may be little to no difference between the two options. Yet on others the preferred kernel location may be at the lower virtual addresses. Details matter.

Paging or segmentation for virtual memory, which is better?

Most OSes use paging for virtual memory. Why is this? Why not use segmentation? Is it just because of a hardware issue? Is one better than the other in certain cases? Basically, if you had to choose one over the other, which one would you want to use and why?
Let's assume it's an x86 for argument's sake.
OS like windows and Linux use a combination of both segmentation and paging. The virtual memory of a process is first divided into segments and then each segment consists of a lot of pages. The OS first goes to the specific segment and in that segment it then locates the particular page to access an address
Taken from :operating systems concepts by galvin
one of the issues..
Segmentation permits the physical address space of a process to be non-
contiguous. Paging is another memory-management scheme that offers this
advantage. However, paging avoids external fragmentation and the need for compaction, whereas segmentation does not.
Segmentaion problem:
The problem arises because, when code fragments
or data residing in main memory need to be swapped out, space must be found
on the backing store. The backing store has the same fragmentation problems
but access is much slower, so compaction is impossible.
Paging solves it by:
The basic method for implementing paging involves breaking physical memory into fixed-sized blocks called frames and breaking logical memory into
blocks of the same size called pages.The backing store is divided into fixed-sized blocks that are the same size as the memory frames or clusters of multiple frames.
Since pages-frames-The backing store all are divided into same size so it doesn't lead to external fragmentation. But may have internal fragmentation.
So pagesize must be chosen correctly
Operating Systems concepts
Note, that Single-Address-Space Operating Systems sometimes use segmentation to isolate processes.

Segmentation in Linux : Segmentation & Paging are redundant?

I'm reading "Understanding Linux Kernel". This is the snippet that explains how Linux uses Segmentation which I didn't understand.
Segmentation has been included in 80 x
86 microprocessors to encourage
programmers to split their
applications into logically related
entities, such as subroutines or
global and local data areas. However,
Linux uses segmentation in a very
limited way. In fact, segmentation
and paging are somewhat redundant,
because both can be used to separate
the physical address spaces of
processes: segmentation can assign a
different linear address space to each
process, while paging can map the same
linear address space into different
physical address spaces. Linux prefers
paging to segmentation for the
following reasons:
Memory management is simpler when all
processes use the same segment
register values that is, when they
share the same set of linear
addresses.
One of the design objectives of Linux
is portability to a wide range of
architectures; RISC architectures in
particular have limited support for
segmentation.
All Linux processes running in User
Mode use the same pair of segments to
address instructions and data. These
segments are called user code segment
and user data segment , respectively.
Similarly, all Linux processes running
in Kernel Mode use the same pair of
segments to address instructions and
data: they are called kernel code
segment and kernel data segment ,
respectively. Table 2-3 shows the
values of the Segment Descriptor
fields for these four crucial
segments.
I'm unable to understand 1st and last paragraph.
The 80x86 family of CPUs generate a real address by adding the contents of a CPU register called a segment register to that of the program counter. Thus by changing the segment register contents you can change the physical addresses that the program accesses. Paging does something similar by mapping the same virtual address to different real addresses. Linux using uses the latter - the segment registers for Linux processes will always have the same unchanging contents.
Segmentation and Paging are not at all redundant. The Linux OS fully incorporates demand paging, but it does not use memory segmentation. This gives all tasks a flat, linear, virtual address space of 32/64 bits.
Paging adds on another layer of abstraction to the memory address translation. With paging, linear memory addresses are mapped to pages of memory, instead of being translated directly to physical memory. Since pages can be swapped in and out of physical RAM, paging allows more memory to be allocated than what is physically available. Only pages that are being actively used need to be mapped into physical memory.
An alternative to page swapping is segment swapping, but it is generally much less efficient given that segments are usually larger than pages.
Segmentation of memory is a method of allocating multiple chunks of memory (per task) for different purposes and allowing those chunks to be protected from each other. In Linux a task's code, data, and stack sections are all mapped to a single segment of memory.
The 32-bit processors do not have a mode bit for disabling
segmentation, but the same effect can be achieved by mapping the
stack, code, and data spaces to the same range of linear addresses.
The 32-bit offsets used by 32-bit processor instructions can cover a
four-gigabyte linear address space.
Aditionally, the Intel documentation states:
A flat model without paging minimally requires a GDT with one code and
one data segment descriptor. A null descriptor in the first GDT entry
is also required. A flat model with paging may provide code and data
descriptors for supervisor mode and another set of code and data
descriptors for user mode
This is the reason for having a one pair of CS/DS for kernel privilege execution (ring 0), and one pair of CS/DS for user privilege execution (ring 3).
Summary: Segmentation provides a means to isolate and protect sections of memory. Paging provides a means to allocate more memory that what is physically available.
Windows uses the fs segment for local thread storage.
Therefore, wine has to use it, and the linux kernel needs to support it.
Modern operating systems (i.e. Linux, other Unixen, Windows NT, etc.) do not use the segmentation facility provided by the x86 processor. Instead, they use a flat 32 bit memory model. Each user mode process has it's own 32 bit virtual address space.
(Naturally the widths are expanded to 64 bits on x86_64 systems)
Intel first added segmentation on the 80286, and then paging on the 80386. Unix-like OSes typically use paging for virtual memory.
Anyway, since paging on x86 didn't support execute permissions until recently, OpenWall Linux used segmentation to provide non-executable stack regions, i.e. it set the code segment limit to a lower value than the other segment's limits, and did some emulation to support trampolines on the stack.