How do I configure an ATA hard disk to start generating interrupts? - operating-system

RESOLVED
After much confusion and frustration, I finally got my hard disk to interrupt. :D It basically came down to the fact that I kept reading the status register instead of the alternate status register. A few other things were messed up to boot, but the point is my hard disk driver is finally starting to take shape. Now, for others I will leave the original post.
P.S. For further clarification, I didn't need to issue any sort of reset command. All I did was the following:
Select the device (didn't want to kill the Solaris OS on the other disk)
clear the nIEN bit in the DEVICE CONTROL register
issue an IDENTIFY DEVICE command***
Actually, I am not sure if the IDENTIFY DEVICE command is need because I left the lab happy before I could test the code without issuing the command. However, the main point is that I needed to be sure to read the alternate status register and have the nIEN bit cleared without the need for a reset. The BIOS apparently takes care of most stuff.
I am currently trying to write a disk driver for a hobby OS being developed at my school. I currently have routines to read/write data in the PCI configuration space and assembly routines to do port IO with the various registers defined by ATA/ATAPI-7. Now, my question is, specifically how will I get an IDE hard drive to start generating interrupts? I have been looking through all this documentation and is hasn't become clear to me what I am doing wrong.
Can someone explain exactly what causes an IDE hard drive to start generating interrupts? I already have an interrupts service routine ready to test, but am having difficulty getting the interrupts in the first place. Can this be accomplished through the ATA SOFT RESET?
Thanks!
UPDATE: Ok, I was able to get the secondary channel, an ATAPI CDROM to generate interrupts by setting the SRST bit in the DEVICE CONTROL register for a soft reset. This does not work for the hard disk on the primary channel. What I have noticed so far is that when I set the SRST bit for the HDD, it sets the BSY bit and leaves it set. From there I don't know what to do.

This reference should help you a fair bit: Kenos description of programming ATA/ATAPI.
The basic mechanism to enable interrupts is to clear nIEN in the DCR (Device Control Register):
nIEN: Drive Interrupt Enable bit. The enable bit for the drive interrupt to the host. When nIEN is 0 or the drive is selected the host interrupt signal INTRQ is enabled through a tri state buffer to the host. When nIEN is 1 or the drive is not selected the host interrupt signal INTRQ is in a high impedance state regardless of the presence or absence of a pending interrupt.
This www.ata-atapi.com is a good jumping-off point to find way more info about ATA/PATA/SATA/ATAPI than you want to know... Note that the official ATA-6/7/etc specs cost $$ from T13, though you can download current drafts of ATA-8 from them.
This link describes a few of the many ways ATA devices vary from the specs. (I used to write SCSI and ATA/ATAPI drivers for Commodore/Amiga, way back when, as well as help with qualifying drives - or more accurately, figuring out what idiocies drive makers had done.)

if this is just a hobby OS, why not use the BIOS interrupt (int 13h)? admittedly not as fast as direct disk access but safer for your hard drive (I've put a read head through a plate before messing with disk I/O).

Related

Re-program STM32F102 trouble

I am trying to make some custom firmware for a MIDI controller (AKAI LPD8).
There is an STM32F102R8T6 chip in the unit.
I am trying to reach it with a programmer to wipe it, but it seems to not be responsive.
Some information and thing I have tried:
The firmware that came with the unit works, so the chip is not broken
Removed the components connected to the programming pins (PA9-PA10 and PA13-PA14)
I am able to pull BOOT0 high and have it not run the main program, but I am however not able to get a life sign using either an ST-Link2(clone) connected to PA13/14, nor a USB to serial adapter connected to PA9/PA10, so I am not sure what mode it is in
The connection has been checked, and RX-TX etc is the correct way around (but also for the sake of trying it all, I reversed the connections as well...).
Tried both the STM32CubeProgrammer and stm32flash, but none connects.
I am actually not sure if AKAI have locked the chip in such a way that you cannot even do a full chip erase and use the chip for something new? The NRST pin is strangely not doing anything to the running of the firmware either when I try to pull it low.
Is there a way to reprogram these chips when they come off of a commercial product, or are they permanently locked?
Any solution/tips?
Many of the STM32 parts have "proprietary code read-out protection" (google PCROP) which but you might be lucky and they haven't enabled it in the option bytes. Read the documentation for that and the bootloader documentation and get a good idea of what you expect it to do if it is enabled and if it isn't.
If you have a scope, try watching the SWD/JTAG pins to see if there is any response from the device. (If you aren't even sure if it is in reset then scope the crystal if there is one).
If you haven't got a scope, you might be able to to verify what it is doing by seeing if it sets the pins and pull-resistors to how they would be expected to be in the bootloader mode, eg: UART TX should be high if it is enabled, even it it isn't transmitting anything. Put a strong pull-down (~1k) on there and see if it still reads high.
After hours of trying different ways of making it work (also tried the alternate mapping of the UART port), and probed the TX pin as suggested by Tom V to no avail, I have given up working on that specific chip and ordered an upgrade from the STM32F4 family instead to replace it with. A lot more power and useful peripherals.
A bit of a non-answer to the specific question. Frustrating to not have found out what was wrong (chip or approach) but being mindful of the sunk cost fallacy, I think it was best to just replace the chip with a fresh one and start development from there.

Stored Program Computer in modern computing

I was given this exact question on a quiz.
Question
Answer
Does the question make any sense? My understanding is that the OS schedules a process and manages what instructions it needs the processor to execute next. This is because the OS is liable to pull all sorts of memory management tricks, especially in main memory where fragmentation is a way of life. I remember that there is supposed to be a special register on the processor called the program counter. In light of the scheduler and memory management done by the OS I have trouble figuring out the purpose of this register unless it is just for the OS. Is the concept of the Stored Program Computer really relevant to how a modern computer operates?
Hardware fetches machine code from main memory, at the address in the program counter (which increments on its own as instructions execute, or is modified by executing a jump or call instruction).
Software has to load the code into RAM (main memory) and start the process with its program counter pointing into that memory.
And yes, if the OS wants to page that memory out to disk (or lazily load it in the first place), hardware will trigger a page fault when the CPU tries to fetch code from an unmapped page.
But no, the OS does not feed instructions to the CPU one at a time.
(Unless you're debugging a program by putting the CPU into "single step" mode when returning to user-space for that process, so it traps after executing one instruction. Like x86's trap flag, for example. Some ISAs only have software breakpoints, not HW support for single stepping.)
But anyway, the OS itself is made up of machine code that runs on the CPU. CPU hardware knows how to fetch and execute instructions from memory. An OS is just a fancy program that can load and manage other programs. (Remember, in a von Neumann architecture, code is data.)
Even the OS has to depend on the processing architecture. Memory today often is virtualized. That means the memory location seen by the program is not the real physical location, but is indirected by one or more tables describing the actual location and some attributes (e.g. read/write/execute allowed or not) for memory accesses. If the accessed virtual memory has not been loaded into main memory (these tables say so), an exception is generated, and the address of an exception handler is loaded into the program counter. This exception handler is by the OS and resides in main memory. So the program counter is quite relevant with today's computers, but the next instruction can be changed by exceptions (exceptions are also called for thread or process switching in preemptive multitasking systems) on the fly.
Does the question make any sense?
Yes. It makes sense to me. It is a bit imprecise, but the meanings of each of the alternatives are sufficiently distinct to be able to say that D) is the best answer.
(In theory, you could create a von Neumann computer which was able to execute instructions out of secondary storage, registers or even the internet ... but it would be highly impractical for various reasons.)
My understanding is that the OS schedules a process and manages what instructions it needs the processor to execute next. This is because the OS is liable to pull all sorts of memory management tricks, especially in main memory where fragmentation is a way of life.
Fragmentation of main memory is not actually relevant. A modern machine uses special hardware (and page tables) to deal with that. From the perspective of executing code (application or kernel) this is all hidden. The code uses virtual addresses, and the hardware maps them to physical addresses. (This is even true when dealing with page faults, though special care will be taken to ensure that the code and page table entries for the page fault handler are in RAM pages that are never swapped out.)
I remember that there is supposed to be a special register on the processor called the program counter. In light of the scheduler and memory management done by the OS I have trouble figuring out the purpose of this register unless it is just for the OS.
The PC is fundamental. It contains the virtual memory address of the next instruction that the CPU is to execute. For application code AND for OS kernel code. When you switch between the application and kernel code, the value in the PC is updated as part of the context switch.
Is the concept of the Stored Program Computer really relevant to how a modern computer operates?
Yes. Unless you are working on a special custom machine where (say) the program has been transformed into custom silicon.

Are the followings user-only or OS-only instructions?

I have these options in my homework. I will explain my reason and I hope someone can critique them?
Indicate whether the following CPU instructions are the user-only or the O/S only or both?
Execution of 'sleep' instruction that halts CPU execution
user-only because I've only seen programmers writing sleep
Loading the 'program counter' PC register with a new memory address
I think it's O/S only.
Reading of disk controller register
O/S only.
'trap' that generates interrupt
From what I understand trap is usually a user-program fault and since O/S is a software application, so probably BOTH
Loading of alarm timeout value into clock register
O/S only
Reading the processor status word PSW register
O/S only.
Loading the memory lower bounds register
O/S only
Adding the contents of two memory locations
both. O/S needs to do computation too.
I don't really understand how to make a distinction between user and O/S specific instructions. They are all essentially "user" programs..
Can someone verify these answers, tell me why I am wrong, and how to tackle these questions?
I don't really understand how to make a distinction between user and O/S specific instructions. They are all essentially "user" programs.
Here's the difference: Did you start a task to have that happen, or did it happen on its own?
Did you start a task to read from the hard drive, or did you merely instruct the OS to do so? (all device access is an OS instruction, for the most part)
Sometimes professors want you to say that "reading the hard drive is user initiated" but "preemptive multitasking by the OS is always OS initiated" or "user actions may remain in a limited state while waiting on a device to finish responding and the OS to return control in a pre-emptive multitasking OS"
These are how I interpret the answers, but if you can't find these answers in the coursework then adopting my answers won't help you any. Notice that I gave a short blurb after each to explain why I chose these things. I am not your professor and have no way to know what he/she intends, so be sure that you can understand my responses. Also, having programmed in ASM helps to answer some of these ...
Execution of 'sleep' instruction that halts CPU execution
O/S. Sleep is actually just a counter that says to skip execution for one or more cycles, and is most often modeled by an API call. This can allow the scheduler access to delay reloading the pre-empted task until many rounds later. Once again, many very basic platforms would require a NOP loop counter to even come close to emulating a sleep command.
Loading the 'program counter' PC register with a new memory address
O/S. The Program Counter register is intended to be used by the system to keep track of the current execution of a program, and during multi-process pre-emption may be used to save the current execution point of the program.
Reading of disk controller register
O/S. In general User commands do not interface the disk subsystem, although on older systems they may be accessed, often by direct register access. In more modern systems, the disk is accessed only by the O/S, and is only accessed by the User via API.
'trap' that generates interrupt
User, O/S. This is when we generate a request for the O/S to handle a situation for us, so we give up control to the internal kernel. It can also result in something returning a faulted condition.
Loading of alarm timeout value into clock register
O/S. These timers are often regarded as having system-only level access, as they are used to monitor the rest of the system. Will be generally protected in CPUs that support such protection (such as those that support ring-level execution prevention).
Reading the processor status word PSW register
User, O/S. Notably the PSW registers are system-level controlled ONLY. On rare occasion one may find a system which allows one, two or merely some of the PSW registers to be read by a user. Since these are status fields for program execution, they aren't normally required to be user readable.
Loading the memory lower bounds register
User, O/S. All memory register assignment is done through CPU commands which are directly received from the binary executable loaded into the CPUs registers. There are no restrictions (aside from changing execution ring level, in participating processors) which are particularly prevented from happening at the application level. Some device interaction may or may not be permitted, and often registers are how devices are interacted with on older hardware. Note that the base memory address may not be 0, and the O/S may intercept memory calls specifically to sandbox the application.
Adding the contents of two memory locations
User, O/S. This is a fundamental requirement of algorithm design, and is often one of the first and most basic commands designed into a CPU unit.

What prevents an OS to recover from a 'blue screen of death'?

If a program violates its instruction path and/or memory data the OS halts it with some message due to the program running in the 'virtual machine' like space of the OS and its unable to determine its next instruction.
The OS in tern is also a program, sharing the machine resources as any other program and can halt in a similar fashion but it's sometimes healthy enough to display some debugging info and blue screen. So as a programmer I'm thinking, if I can do that - emit debugging info and make the screen blue why wouldn't I be able to try to recover the OS altogether instead of requiring a cold reboot ? After all its the OS - it's supposed to be the rock solid foundation (not talking about Windows of course) of all software, if the space shuttle ran Windows then what would happen - it won't recover ?:)
So: is it only that MS hasn't taken care of trying everything to recover to the point that a reboot is not required or is it some other more deeper problem that has stop companies like MS to be unable to do that ?
It's nothing specific to Microsoft; Linux has a kernel panic mechanism, OS X has a kernel panic mechanism. I expect every non-toy operating system kernel has a panic mechanism of some sort when internal corruption is detected. The corruption could come from faulty hardware, faulty software, gamma rays hitting the memory boards just right, who knows.
The whole point behind the kernel panic is a recognition that something that shouldn't go wrong has gone wrong. What else might be invalid? Depending upon where the crash happened, it might not be safe to sync and unmount the filesystems because that might scribble corrupt data over good data on the drives.
Writing to the video card is a good way to inform the user of events (many systems have monitors attached, anyway) and writing to the video card isn't likely to corrupt on-disk data: it would take quite an error for the IOMMU or page tables to be so corrupted that they refer instead to on-disk files and most operating systems will refuse to write to block devices after a kernel panic to try to protect user data at all cost.
Consider what you could do to bring the system back up to a running state? You'd need to tear down all applications that might be associated with corrupted kernel data structures. You'd need to restart applications, in the right order, to bring system services back up. And a reboot is a very easy way to reliably do both those things.
You can't recover the OS for the same reasons a user-space program can't recover -- when certain types of errors are seen it means that your program is in an undefined state and therefore can't recover. Even if the problem in some sense isn't fatal (i.e. doesn't cause the program to immediately die), it's not safe to continue because things are or are likely corrupted.
For example, be it a user-space program or the OS kernel, say a buffer overrun or an messed up pointer causes the stack to be corrupted. How is the program supposed to recover from that? With a blown stack when the function that is currently executing ends, where will it return to? The return address is likely gone. Now what?
And it's not just Microsoft. Ever hear of a "kernel panic" in Unix?

How are Operating Systems "Made"?

Creating an OS seems like a massive project. How would anyone even get started?
For example, when I pop Ubuntu into my drive, how can my computer just run it?
(This, I guess, is what I'd really like to know.)
Or, looking at it from another angle, what is the least amount of bytes that could be on a disk and still be "run" as an OS?
(I'm sorry if this is vague. I just have no idea about this subject, so I can't be very specific. I pretend to know a fair amount about how computers work, but I'm utterly clueless about this subject.)
Well, the answer lives in books: Modern Operating Systems - Andrew S. Tanenbaum is a very good one. The cover illustration below.
The simplest yet complete operating system kernel, suitable for learning or just curiosity, is Minix.
Here you can browse the source code.
(source: cs.vu.nl)
Operating Systems is a huge topic, the best thing I can recommend you if you want to go really in depth on how a operating systems are designed and construced it's a good book:
Operating System Concepts
If you are truly curious I would direct you to Linux from Scratch as a good place to learn the complete ins and outs of an operating system and how all the pieces fit together. If that is more information than you are looking for then this Wikipedia article on operating systems might be a good place to start.
A PC knows to look at a specific sector of the disk for the startup instructions. These instructions will then tell the processor that on given processor interrupts, specific code is to be called. For example, on a periodic tick, call the scheduler code. When I get something from a device, call the device driver code.
Now how does an OS set up everything with the system? Well hardware's have API's also. They are written with the Systems programmer in mind.
I've seen a lot of bare-bones OS's and this is really the absolute core. There are many embedded home-grown OS's that that's all they do and nothing else.
Additional features, such as requiring applications to ask the operating system for memory, or requiring special privileges for certain actions, or even processes and threads themselves are really optional though implemented on most PC architectures.
The operating system is, simply, what empowers your software to manage the hardware. Clearly some OSes are more sophisticated than others.
At its very core, a computer starts executing at a fixed address, meaning that when the computer starts up, it sets the program counter to a pre-defined address, and just starts executing machine code.
In most computers, this "bootstrapping" process immediately initializes known peripherals (like, say, a disk drive). Once initialized, the bootstrap process will use some predefined sequence to leverage those peripherals. Using the disk driver again, the process might read code from the first sector of the hard drive, place it in a know space within RAM, and then jump to that address.
These predefined sequence (the start of the CPU, the loading of the disk) allows the programmers to star adding more and more code at the early parts of the CPU startup, which over time can, eventually, start up very sophisticated programs.
In the modern world, with sophisticated peripherals, advanced CPU architectures, and vast, vast resources (GBs or RAM, TB of Disk, and very fast CPUs), the operating system can support quite powerful abstractions for the developer (multiple processes, virtual memory, loadable drivers, etc.).
But for a simple system, with constrained resourced, you don't really need a whole lot for an "OS".
As a simple example, many small controller computers have very small "OS"es, and some may simply be considered a "monitor", offering little more than easy access to a serial port (or a terminal, or LCD display). Certainly, there's not a lot of needs for a large OS in these conditions.
But also consider something like a classic Forth system. Here, you have a system with an "OS", that gives you disk I/O, console I/O, memory management, plus the actual programming language as well as an assembler, and this fits in less than 8K of memory on an 8-Bit machine.
or the old days of CP/M with its BIOS and BDOS.
CP/M is a good example of where a simple OS works well as a abstraction layer to allow portable programs to run on a vast array of hardware, but even then the system took less than 8K of RAM to start up and run.
A far cry from the MBs of memory used by modern OSes. But, to be fair, we HAVE MBs of memory, and our lives are MUCH MUCH simpler (mostly), and far more functional, because of it.
Writing an OS is fun because it's interesting to make the HARDWARE print "Hello World" shoving data 1 byte at a time out some obscure I/O port, or stuffing it in to some magic memory address.
Get a x86 emulator and party down getting a boot sector to say your name. It's a giggly treat.
Basically... your computer can just run the disk because:
The BIOS includes that disk device in the boot order.
At boot, the BIOS scans all bootable devices in order, like the floppy drive, the harddrive, and the CD ROM. Each device accesses its media and checks a hard-coded location (typically a sector, on a disk or cd device) for a fingerprint that identifies the media, and lists the location to jump to on the disk (or media) where instructions start. The BIOS tells the device to move its head (or whatever) to the specified location on the media, and read a big chunk of instructions. The BIOS hands those instructions off to the CPU.
The CPU executes these instructions. In your case, these instructions are going to start up the Ubuntu OS. They could just as well be instructions to halt, or to add 10+20, etc.
Typically, an OS will start off by taking a large chunk of memory (again, directly from the CPU, since library commands like 'GlobalAlloc' etc aren't available as they're provided by the yet-to-be-loaded-OS) and starts creating structures for the OS itself.
An OS provides a bunch of 'features' for applications: memory management, file system, input/output, task scheduling, networking, graphics management, access to printers, and so on. That's what it's doing before you 'get control' : creating/starting all the services so later applications can run together, not stomp on each other's memory, and have a nice API to the OS provided services.
Each 'feature' provide by the OS is a large topic. An OS provides them all so applications just have to worry about calling the right OS library, and the OS manages situations like if two programs try to print at the same time.
For instance, without the OS, each application would have to deal with a situation where another program is trying to print, and 'do something' like print anyway, or cancel the other job, etc. Instead, only the OS has to deal with it, applications just say to the OS 'print this stuff' and the OS ensure one app prints, and all other apps just have to wait until the first one finishes or the user cancels it.
The least amount of bytes to be an OS doesn't really make sense, as an "OS" could imply many, or very few, features. If all you wanted was to execute a program from a CD, that would be very very few bytes. However, that's not an OS. An OS's job is to provide services (I've been calling them features) to allow lots of other programs to run, and to manage access to those services for the programs. That's hard, and the more shared resources you add (networks, and wifi, and CD burners, and joysticks, and iSight video, and dual monitors, etc, etc) the harder it gets.
http://en.wikipedia.org/wiki/Linux_startup_process you are probably looking for this.
http://en.wikipedia.org/wiki/Windows_NT_startup_process or this.
One of the most recent operating system projects I've seen that has a serious backing has been a MS Research project called Singularity, which is written entirely in C#.NET from scratch.
To get an idea how much work it takes, there are 2 core devs but they have up to a dozen interns at any given time, and it still took them two years before they could even get the OS to a point where it would bootup and display BMP images (it's how they use to do their presentations). It took much more work before they could even get to a point where there was a command line (like about 4yrs).
Basically, there are many arguments about what an OS actually is. If you got everyone agreed on what an OS specifically is (is it just the kernel? everything that runs in kernel mode? is the shell part of OS? is X part of OS? is Web browser a part of OS?), your question is answered! Otherwise, there's no specific answer to your question.
Oh, this is a fun one. I've done the whole thing at one point or another, and been there through a large part of the evolution.
In general, you start writing a new OS by starting small. The simplest thing is a bootstrap loader, which is a small chunk of code that pulls a chunk of code in and runs it. Once upon a time, with the Nova or PDP computers, you could enter the bootstrap loader through the front panel: you entered the instructions hex number by hex number. The boot loader than reads some medium into memory, and set the program counter to the start address of that code.
That chunk of code usualy loads something else, but it doesn't have to: you can write a program that's meant to run on the bare metal. That sort of program does something useful on its own.
A real operating system is bigger, and has more pieces. you need to load programs, put them in memory, and run them; you need to provide code to run the IO devices; as it gets bigger, you need to manage memory.
If you want to really learn how it works, find Doug Comer's Xinu books, and Andy Tannenbaum's newest operating system book on Minix.
You might want to get the book The Design and Implementation of the FreeBSD Operating system for a very detailed answer. You can get it from Amazon or this link to FreeBSD.org's site looks like the book as I remember it: link text
Try How Computers Boot Up, The Kernel Boot Process and other related articles from the same blog for a short overview of what a computer does when it boots.
What a computer does when its start is heavily dependent (maybe obvious?) on the CPU design and other "low-level stuff"; therefore it's kind of difficult to anticipate what your computer does when it boots.
I can't believe this hasn't been mentioned... but a classic book for an overview of operating system design is Operating Systems - Design and Implementation written by Andrew S Tanenbaum, the creator of MINIX. A lot of the examples in the book are geared directly towards MINIX as well.
If you would like to learn a bit more, OS Dev is a great place to start. Especially the wiki. This site is full of information as well as developers who write personal operating systems for a small project/hobby. It's a great learning resource too, as there are many people in the same boat as you on OSDev who want to learn what goes into an OS. You might end up trying it yourself eventually, too!
the operating system (OS) is the layer of software that controls the hardware. The simpler the hardware, the simpler the OS, and vice-versa ;-)
if the early days of microcomputers, you could fit the OS into a 16K ROM and hard-wire the motherboard to start executing machine code instructions at the start of the ROM address space. This 'bootstrap' process would then load the code for the drivers for the other devices like the keyboard, monitor, floppy drive, etc., and within a few seconds your machine would be booted and ready for use.
Nowadays... same principle, but a lot more and more complex hardware ;-)
Well you have something linking the startup of the chip to a "bios", then to a OS, that is usually a very complicated task done by a lot of services of code.
If you REALY want to know more about this i would recomend reading a book... about microcontrllers, especially one where you create a small OS in c for a 8051 or the like.. or learn some x86 assembly and create a very small "bootloader OS".
You might want to check out this question.
An OS is a program, just like any other application you write. The main purpose of this program is that it allows you to run other programs. Modern OSes take advantage of modern hardware to ensure that programs do not clash with one another.
If you are interested in writing your own OS, check out my own question here:
How to get started in operating system development
You ask how few bytes could you put on disk and still run as an OS? The answer depends on what you expect of your OS, but the smallest useful OS that I know of fits in 1.7 Megabytes. It is Tom's Root Boot disk and it is a very nice if small OS with "rescue" applications that fits on one floppy disk. Back in the days when every machine had a floppy drive and not every machine had a CD-ROM drive, I used to use it frequently.
My take on it is that it is like your own life. AT first, you know very little - just enough to get along. This is similar to what the BIOS provides - it knows enough to look for a disk drive and read information off of it. Then you learn a little bit more when you go to elementary school. This is like the boot sector being read into memory and being given control. Then you go to high school, which is like the OS kernel loading. Then you go to college (drivers and other applications.) Of course, this is the point at which you are liable to CRASH. HE HE.
Bottom line is that layers of more and more capability are slowly loaded on. There's nothing magic about an OS.
Reading through here will give you an idea of what it took to create Linux
https://netfiles.uiuc.edu/rhasan/linux/
Another really small operating system that fits on one disk is QNX (when I last looked at it a long time ago, the whole OS, with GUI interface, web browser, disk access and a built in web server, fit on one floppy drive).
I haven't heard too much about it since then, but it is a real time OS so it is designed to be very fast.
Actually, some people visit a 4-year college to get a rough idea on this..
At its core, OS is extremely simple. Here's the beginner's guide to WHAT successful OS are made to do:
1. Manage CPU using scheduler which decides which process (program's running instance) to be scheduled.
2. Manage memory to decide which all processes use it for storing instruction(code) and data(variables).
3. Manage I/O interfaces such as disk drives, alarms, keyboard, mouse.
Now, above 3 requirements give rise to need for processes to communicate(and not fight!), to interact with outside world, help applications to do what they want to do.
To dig deeper into HOW it does that, read Dinosaur book :)
So, you can make OS as small as you want to as long as you manage to handle all hardware resources.
When you bootup, BIOS tells CPU to start reading bootloader(which loads first function of OS which resides at fixed address in memory--something like main() of small C program). Then this creates functions and processes and threads and starts the big bang!
Firstly, reading reading and reading about, what is OS; then what are the uses/ Types/ nature / objective/ needs/ of the different OS's.
Some of the links are as follows; newbie will enjoy these links:
Modern OS - this gives Idea about general OS.
Start of OS - this gives basics of what it really takes to MAKE OS, how we can make it and how one can modify a present open source code of OS by himself.
Wiki OS - Gives idea about the different Os's used in different fields and uses of it(Objects / features of OS.)
Let's see in general what OS contains (Not the sophisticatedLinux or Windows)
OS need a CPU and to dump a code in it you need a bootloader.
OS must be have the objectives to fullfill and those objectives mustbe defined in a wrapper which is called Kernel
Inside you could have scheduling time and ISR's (Depends on the objective and OS you need to make)
OS development is complicated. There are some websites like osdev or lowlevel.eu (german) dedicated to the topic. There are also some books, that others have mentioned already.
I can't help but also reference the "Write your own operating system" video series on youtube, as I'm the one who made it :-)
See https://www.youtube.com/playlist?list=PLHh55M_Kq4OApWScZyPl5HhgsTJS9MZ6M