I am currently reading a manual dedicated to OS development. The first part of the book describes how to write a boot sector, which is followed by a more dense text devoted to kernel development. Also, I have not been questioning myself a lot about the code structure until I have encountered following instruction sequence:
lgdt; load global descriptor table
mov eax, cr0; switch adressing mode and paging control via cr0
or eax, 0x1
mov cr0, eax
Actually, I have always been persuaded that all this stuff related to memory paging, the concept of kernel, protection rings was just a fancy idea born somewhere deep in some OS designer's mind. However, the existence of these instructions shows that GDT and everything that goes together is dictated by the CPU design. So, basically, according to my understanding, there is no conceptual difference between *nix and Windows (I mean mainstream OS). If my premise is correct, I would like to ask several questions.
1) If OS is written accordingly to CPU architecture, ie following the same design rules established since the dawn of ages, why OS developer job openings are often tagged as "R&D engineering"? Besides using 64-bit registers, what kind of novelty can be introduced into OS development?
2) Is there any way to build an OS which doesn't have any of aforementioned features and still can use all the capacities of CPU, ie not to be restricted to 16-bit instruction set? What about Kolibri OS or Menuet OS? Besides being written on ASM, do these OS conceptually differ from MS Windowes or *nix? Do they also need to establish GDT, enter protected mode, etc?
3) Who influences who? Gates calls to Intel designers and says he needs a GDT feature in CPU? Or electrical engineers from Intel call Gates and point him that he has no choice but have to live all his life with GDT and paging? In general how do CPU designers interact with software community?
Related
I'm interested in the details of how operating systems work and perhaps writing my own.
From what I've gathered, the BIOS/UEFI is supposed to handle setting up the hardware, and do things like memory-mapping (or IO ports for) the graphics card and other IO devices like audio and ethernet.
My question is, how does the kernel know how to access and (re)configure these devices when it's passed control from the bootloader? Are there just conventions like 'the graphics card is always memory mapped from X to Y address space'? Are you at the mercy of a hardware manufacturer writing a driver for an operating system which knows how the hardware will be initialized?
That seems wrong, so maybe the kernel code includes instructions which somehow iterate through all the bus-connected devices. But what instructions can accomplish that? Is the PCI(e) controller also a memory-mapped device? How do you begin querying and setting up the system?
My primary reference has been the Intel 64 Architectures Software Developer's Manual, which has excellent documentation on how the CPU works, but doesn't describe how the system is setup.
I never wrote a firmware so I don't really know how that works in general. You probably have some memory detection done like an actual memory iteration that is done and some interrogation of PCI devices that are memory mapped in RAM. You also probably have some information in the Developer's manuals as to how you should get some information about memory and stuff like that.
In the end, the kernel doesn't need to bother about that because the firmware takes care to do all that and to provide temporary drivers before the kernel is set up completely.
The firmware passes information to the kernel using the ACPI tables so that is the convention you are looking for. The UEFI firmware launches the /efi/boot/bootx64.efi EFI app from the hard-disk automatically. It calls the main function of that app often called the bootloader. When you write that application, often with frameworks such as EDK2 or GNU-EFI, you can thus use the temporary drivers to get some information like the location of the RSDP which points to all other ACPI tables.
The ACPI convention specifies a language that is AML which, when your kernel interprets, tells it all about hardware. You thus have all the required information there to load drivers and such.
PCI (which is everything nowadays) is another thing. It works with memory mapped IO but the ACPI tables (the MCFG) is helpful to find the beginning of the configuration space for PCI devices that take the form of memory mapped registers.
As to graphics cards, you probably don't want to start with those. They are complex and, at first, you should probably stick to the framebuffer returned by UEFI and at least write a driver for xHCI which is the PCI host controller responsible to interact with USB including keyboards and mouses.
We had a question in the exam whether a desktop computer is a multiprocessor or not. We are having a discussion now whether the BigO pc from Origin uses a single microprocessor or it uses more than one.
This question is really too broad for SO (for future reference); but Ill provide some insight that will hopefully improve your understanding. Your question is really, really broad in general and since the term microprocessor is a bit general and not all the technical information about all the parts of modern PCs is publicly available, its hard to give an exact number, mostly because alot of the components and subsystems of a modern desktop PC will have some kind of processor; generally these are microcontrollers but they are still processors running some firmware/software to do whatever functionality is required by that subsystem.
Certainly, none of the modern PCs (like the one you mention assuming its this one: https://www.originpc.com/gaming/desktops/big-o/) would be consider single processor system. Everything from desktops to laptops to smart phones these days all have at least 2-4 physical processors (ie, cores) as part of the application SoC; these all have mulitple main cores. So when you read about how this system has an Intel i7-9700K, that "processor" is really made up for 8 of the same x86-64 processors all in one. Its these cores that run all your applications and operating systems; but there are many little processors running their own code to do various other functions. For example, on Intel CPUs, there is a small processor that starts up when the computer first powers on and enables various management and security features (https://en.wikipedia.org/wiki/Intel_Management_Engine). Likewise, theres processors in many of the subsystems, like the audio subsystem for controlling low-level audio features has a small microcontroller/DSP, the graphics system can have tens or more of small processors depending on how you count the cores in the integrated GPU. And all of these as contained inside the package of the i7; there are even more on the motherboard and external components. Depending on what you count, there can be 100s of small processors in a modern computer system.
In the past, the main processor was a single core unit that really only had one microprocessor in it; the term "processor" and "CPU" have kind of held over so you might say that a desktop has an Intel i7 for a processor despite the fact the chip itself contains many main processors/cores and numerous subprocessors/microcontrollers. So while you might say that particular desktop has a single "processor" (as there are systems that can install more than 1 Intel/AMD SoCs, these are usually for high-end workstations or servers, also called multisocketed), note the difference between multiple processors and multiple sockets on the motherboard.
So, to directly answer your questions, it depends what is meant by processor. If the question is, can I fit multiple i7s (ie, is the system multisocketed), then no. If the question is, does a modern PC has multiple processors in terms of CPU cores, then yes. If the question is to count all the processing units on the system, including all the little microprocessors doing their particular job, then its really hard to say but there are alot of them.
since we know that operating system works in protected mode
and BIOS works in a Real mode ( 16 bit). so when an interrupt is called from
either Operating System or application program, does CPU switch mode back and forth everytime?
In general; hardware is capable of doing lots of things at once (playing sounds while generating 3D graphics while sending data to network while transferring data to multiple disks while waiting for user input while all CPUs are busy doing actual processing); and BIOS functions are not capable of allowing more than one thing to happen at time (e.g. will waste 100% of CPU time waiting for a hard disk controller to transfer data while the CPU does nothing and while nothing else can use any other BIOS service for anything).
For this reason alone, BIOS services are not usable and not used by any modern OS (except briefly during boot).
Of course it's not the only reason - no IO prioritisation, no support for hot-plug of any kind, no support for power management, no support for system management (e.g. https://en.wikipedia.org/wiki/S.M.A.R.T. ), no support for GPU, no support for any sound card (other than "PC speaker beep"), no support for networking (excluding PXE), no support for IO APICs, etc. Ironically, out of all of the problems, "BIOS services are designed for real mode" is the least important problem because it's the only problem that an OS can work around.
Instead, each OS has native drivers that don't have any of these limitations.
Note: this is partly why it's relatively easy for modern operating systems to support UEFI (where none of the BIOS services exist at all) - for most, they replace the boot loader/boot code and don't need to change much else.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
I have an AT90USB162 AVR chip which I want to run a multitasking RTOS, so I am evaluating possible RTOS for using with my AVR chip. Which multitasking RTOS's are supported by AVR? Maybe QNX? (Is it possible to run a QNX kernel on an AVR microchip?).
Thanks in advance.
The Atmel AT90USB162 is an 8-bit AVR RISC-based microcontroller -- QNX would be a stretch, and AVR is not in their BSP directory
Micrium supports AVR with uC/OS-II
FreeRTOS also supports AVR
When you say "RTOS", I presume you mean pre-emptive multi-tasking? I'm guessing (since this is an 8-bit AVR) you don't need a filesystem, network stack, etc.?
If you're looking for a tiny, pre-emptive multi-tasking kernel, you might want to check out the Quantum Platform - I've used it on very resource-constrained platforms like AVR & MSP430. Co-workers have used it on 8-bit 8051 and HC11 variants as well.
The QP's preemptive kernel (QK) is a run-to-completion kernel, which reduces its stack (RAM) requirements and makes context switching less resource-intensive (no TCBs, less context to save & restore).
There is a QP/C variant, which is "small", and a QP-nano variant, which is "tiny". Since those terms are absolutely meaningless without numbers, the QP-nano page has a comparison of kernel types & their typical sizes. For example (minimum figures provided): typical RTOS, 10K ROM, 10K RAM; QP/C - 8K ROM, 1K RAM; QP-nano - 2K ROM, 100 bytes of RAM.
The good thing is that all the code is available so you can download & try it & see for yourself.
QNX - not a chance! QNX is a relatively large and sophisticated OS for 32bit devices with MMU, providing not only kernel level scheduling but also file systems, fault-tolerant networking, POSIX API, GUI etc. Its most significant feature is its support for memory protection - each thread runs in its own virtual memory segment, so only runs on devices with appropriate hardware support.
What features do you want from your OS? On an 8 bit device it is only reasonable to expect basic priority based pre-emptive scheduling and IPC. Other services such as networking, filesystem, USB etc. are usually add-ons from the RTOS vendor or must be integrated yourself from third-party code.
The obvious choice if you want to spend no money is FreeRTOS. It is competent, though in some ways unconventional architecturally, even if fairly conventional at the API level. In my tests on ARM it had slower context switch times that other kernels I compared it with others I tested, but that may not be the case on AVR, and would only be an issue if you require real-time response times in order of a few microseconds. AVR has a rather large register set, so context switches are typically expensive in any case.
Atmel have a list of third-party support including RTOS at http://www.atmel.com/products/AVR/thirdparty.asp#. They list the following:
CMX Systems, Inc: CMX-RTX, CMX-Tiny+ (Add-ons: CMX-MicroNet, CMX-FFS)
FreeRTOS.org: FreeRTOS
Micriµm, Inc: µC/ OS-II
Nut/OS: RTOS and TCP/IP stack with a Posix-like API.
SEGGER: embOS
I have personal experience of CMX-Tiny+ (on dsPIC), embOS (on ARM), and FreeRTOS (on ARM), and uC/OS-II. They are all competent, uC-OS-II has the minor restriction of only allowing a single task at each priority level (no round-robin scheduling), but consequently probably faster context switches. In the case of embOS I have, successfully integrated third-party file-system and USB code, though the vendor has their own add-ons for these as well.
Though not a direct answer to your question, being 8 bit controller with limited resource, think of the advantage before committing to an OS Layer, the advantage of an OS layer will be beneficiary only when the project has to handle major subsystems that are tedious to code and maintain ex. file system, graphics, audio, networking, etc.
Since most of the suppliers provide integrated development environment and standard libraries and more over you can write code with high level languages like C, C++, for simple controls task sticking to your own frame work will be much more manageable
Athomthreads is a lightweight RTOS supported by AVR. It supports:
Preemptive scheduler with 255 priority levels
Round-robin at same priority level
Semaphore
Mutex
Message Queue
Timers
It is open source and has about 1k lines of code. By comparision, the demo project for AVR build with Eclipse produces a .bin file of 96 to 127 kb. Of course FreeRTOS has more features (like memory management, including dynamic memory) and better security. But if you only need multi-threading atomthreads is nice.
Here is a comprehensive comparison between multiple RTOSs.
I am trying to write a very thin hypervisor that would have the following restrictions:
runs only one operating system at a time (ie. no OS concurrency, no hardware sharing, no way to switch to another OS)
it should be able only to isolate some portions of RAM (do some memory translations behind the OS - let's say I have 6GB of RAM, I want Linux / Win not to use the first 100MB, see just 5.9MB and use them without knowing what's behind)
I searched the Internet, but found close to nothing on this specific matter, as I want to keep as little overhead as possible (the current hypervisor implementations don't fit my needs).
What you are looking for already exists, in hardware!
It's called IOMMU[1]. Basically, like page tables, adding a translation layer between the executed instructions and the actual physical hardware.
AMD calls it IOMMU[2], Intel calls it VT-d (please google:"intel vt-d" I cannot post more than two links yet).
[1] http://en.wikipedia.org/wiki/IOMMU
[2] http://developer.amd.com/documentation/articles/pages/892006101.aspx
Here are a few suggestions / hints, which are necessarily somewhat incomplete, as developing a from-scratch hypervisor is an involved task.
Make your hypervisor "multiboot-compliant" at first. This will enable it to reside as a typical entry in a bootloader configuration file, e.g., /boot/grub/menu.lst or /boot/grub/grub.cfg.
You want to set aside your 100MB at the top of memory, e.g., from 5.9GB up to 6GB. Since you mentioned Windows I'm assuming you're interested in the x86 architecture. The long history of x86 means that the first few megabytes are filled with all kinds of legacy device complexities. There is plenty of material on the web about the "hole" between 640K and 1MB (plenty of information on the web detailing this). Older ISA devices (many of which still survive in modern systems in "Super I/O chips") are restricted to performing DMA to the first 16 MB of physical memory. If you try to get in between Windows or Linux and its relationship with these first few MB of RAM, you will have a lot more complexity to wrestle with. Save that for later, once you've got something that boots.
As physical addresses approach 4GB (2^32, hence the physical memory limit on a basic 32-bit architecture), things get complex again, as many devices are memory-mapped into this region. For example (referencing the other answer), the IOMMU that Intel provides with its VT-d technology tends to have its configuration registers mapped to physical addresses beginning with 0xfedNNNNN.
This is doubly true for a system with multiple processors. I would suggest you start on a uniprocessor system, disable other processors from within BIOS, or at least manually configure your guest OS not to enable the other processors (e.g., for Linux, include 'nosmp'
on the kernel command line -- e.g., in your /boot/grub/menu.lst).
Next, learn about the "e820" map. Again there is plenty of material on the web, but perhaps the best place to start is to boot up a Linux system and look near the top of the output 'dmesg'. This is how the BIOS communicates to the OS which portions of physical memory space are "reserved" for devices or other platform-specific BIOS/firmware uses (e.g., to emulate a PS/2 keyboard on a system with only USB I/O ports).
One way for your hypervisor to "hide" its 100MB from the guest OS is to add an entry to the system's e820 map. A quick and dirty way to get things started is to use the Linux kernel command line option "mem=" or the Windows boot.ini / bcdedit flag "/maxmem".
There are a lot more details and things you are likely to encounter (e.g., x86 processors begin in 16-bit mode when first powered-up), but if you do a little homework on the ones listed here, then hopefully you will be in a better position to ask follow-up questions.