0
$\begingroup$

I'm a programmer, let's start by that. The question may sound really broad, and in fact it is. I'll list some things that I know, and some other things I've doubts about under the form of questions.

My current understanding is the following:

You have a CPU. This CPU can have multiple cores. Each core runs in parallel. Ok. This implies that at any given time t, we have different core states for all cores. I also know about the booting of a general computer. Looking for operating systems on the non-volatile memory and mapping it onto ram. Then you have RAM filled only with kernel code. These things are just instructions CPU is executing to get everything set up.

I have a question that just popped in my mind right now:

At this stage for example, do we only have one core executing these set-up instructions?

Anyhow continuing this discussion, now that the operating is in memory, cpu gives it control. Meaning up to the point where the OS wasn't loaded, CPU alone had no idea of what a process even is, is it only conceptualized by the operating system? Does the operating system has an actual C-like STRUCT for processes to conceptualize them? Or modern CPUs are somehow built so that the concept of a process coexists even without referring to OS?

Operating System is just a software, often called kernel, so it has actual executable code. Fine. This means that the CPU will execute it. But When? We also have processes which are user-written programs, executed as well. How does the operating system even keep track of these processes? Like come on there has to be some code executing somewhere right? I know operating systems have source codes, so they are actually concrete software running. What is the relationship between Operating System and the CPU? How are processes even executing in parallel? I've read about scheduling, but concretely speaking what is that? Is it an actual piece of code that's being executed on the kernel space at times DECIDED by the cpu and not by the operating system? Because if a user-written process is executing, then in no way the operating system can actually stop its execution, unless there is some internal hardware mechanism that actually stop executions of processes and then gives the operating system the privilege to run to decide what to do next. I have really no idea of how it all works.

As you may see my brain has a lot of concepts but they are all hanging and I know deep inside my soul they are all interconnected, but for some reason I AM NOT seeing this link. It all seems too abstract.

What I'm hoping for is either a mind-refresher comment to tie these things all together inside my brain, or suggestion of a good textbook that in a very PRACTICAL way talks about operating systems and hardware, most of them that I found aren't very practical or at least I don't have the patience to learn things starting from abstract explanations.

$\endgroup$
12
  • $\begingroup$ If you don't understand after reading books on the topic, how can we help you ? $\endgroup$ Apr 19 at 9:21
  • 1
    $\begingroup$ Did you try to read a book on Operating Systems from start to finish? For example Operating System Concepts by Silberschatz, Galvin, Greg Gagne ... you say "I don't have the patience to learn things starting from abstract explanations" but it's the fastest way to learn (perhaps the only way?!?) to really understand how things work. And you should also start with a simple model: 1CPU (no cores, no threads) + RAM. There are more specific books like "Understanding the linux kernel", but I doubt that you can learn things from it without a more general/abstract solid background. $\endgroup$
    – Vor
    Apr 19 at 9:23
  • $\begingroup$ @YvesDaoust the books that I've read are all too much filled with abstraction and don't give you much of actual code $\endgroup$
    – gmmk
    Apr 19 at 9:25
  • 1
    $\begingroup$ Please ask only one question per post. If you have multiple questions, they can be asked separately. $\endgroup$
    – D.W.
    Apr 19 at 9:27
  • $\begingroup$ @Vor Not exactly from start to finish, but usually well-written books should keep the reader hooked. Most of the books that I've encountered didn't keep me hooked, they were like I said a little too abstract. Like I understand abstraction is really powerful, I like to abstract things too, but only after I've understood it the easy way. I swear to god If I can't find books like that, I'mma make one myself after I figure it all out. $\endgroup$
    – gmmk
    Apr 19 at 9:28

1 Answer 1

2
$\begingroup$

First off: an OS is nothing magical. It's code like yours or mine. I've written one (a small one), you can too. Waste of time though, since Linux already exists and it does more than you or I could write.

You have a CPU. It runs instructions. It doesn't know about processes. It doesn't even know about functions. Or lines of code. Or the screen. It just does one instruction after another, forever.

Cores are CPUs. You think have a 4-core CPU, you actually have 4 CPUs in one chip.


Booting

The CPU is hard-wired so it starts by running code from the BIOS chip on your motherboard and that chip is hard-wired so the CPU can directly run code from it without loading. Well, one of them is. The other 3 are hard-wired to do nothing. That's how you can still run MS-DOS (maybe) and waste 3/4 of the CPUs you paid for.

The BIOS code looks at all your hard drives, your CD drive, your USB ports, finds a signature that says "hey this drive has an OS on it", loads that and jumps to the address it just loaded. The old-school MBR system is just the first 512 bytes of any drive, ending with hex codes 55 AA to say that it's bootable. Since it's only 510 bytes you normally put here a program that loads more bytes. The more modern ChatGPT system is more complex and the BIOS loads all the bytes you want, not just the first 510. No point going into detail here.

With either MBR or GPT, once the BIOS loads these bytes and then jumps to their address, the computer is all yours to do as you wish. Usually what it just loaded is another loader which loads the operating system, but that's a historical accident, not something necessary. (Well, it's necessary in MBR if your operating system is more than 510 bytes big, which is the historical accident)

You have 1 CPU running whatever code you like, and 3 CPUs still asleep. For the time being, let's see what you can do with just 1 CPU.

What code do you like? It can be anything. Use your imagination. But let's say you want to make something like Linux but more basic. Linux has a whole lot of parts. You asked about one specifically. You asked about the scheduling.


Scheduling

There's a little magic trick to scheduling that makes it all understandable. The magic trick is that CPUs are extremely forgetful. See, the CPU contains a bunch of registers - which is to say very small memory circuits, the hardware equivalent of variables - different ones depending on which kind of CPU you have, but on x86 you have registers like eax, ecx, edx, ebx (yeah the order is ACDB, don't ask what Intel were smoking), esp, eip, cs, ds, es, and a bunch more. Some of them are general-purpose; some have very specific purposes. And those are the only things the CPU can remember. No, it can't remember the current process ID. No, it can't remember what it was doing 2 instructions ago. No, it can't remember whether it's been running this loop for 50000 iterations or whether the loop counter started at 50000. It's Last Thursdayism on a microscopic scale.

So if you want to swap threads all you have to do is save all the data in the registers into memory (you could call that place struct thread) and load them from somewhere else in memory (a different struct thread) back into the registers. Now the CPU continues running the second thread just as if it had been doing it all along. This is called a context switch. In fact, you can already do this in your own program without OS help - on Linux there's a supported library function called swapcontext.

Keeping track of which thread is currently running is your problem, not the CPU's.

But how does it happen without the thread calling swapcontext? Enter: interrupts. One of the ways that hardware talks to the CPU is by signalling an "interrupt request" which tells the CPU to stop what it's doing and run some OS code - it makes the CPU do an automatic context switch.

The details vary depending on the CPU type. x86 CPUs have quite complicated interrupts, so let's talk about ARM which is much simpler. When an ARM CPU is running some code ("user code") and gets an interrupt request, it only does a few simple steps:

  1. it notes the current instruction address (in ARM terms that's PC or R15)
  2. it activates the "interrupt mode" bit in the CPU status register
  3. it stores the current instruction address in register R14_irq which is only used in interrupt mode
  4. it jumps to the instruction at address 0x00000018 (which is hard-wired)

Of course, there's also a return from interrupt instruction which does the opposite. Of course, the operating system will have made sure that address 0x00000018 has OS code, so the operating system now has control of the CPU and can run whatever code it likes.

Clearly it's not a full context switch. Only the current instruction address is saved and updated. But that's enough for the OS code to do the rest of it. It isn't possible to context switch the register R14_irq properly, because the old value in that register got overwritten. Nobody notices, though, because user code can't touch that register, and OS code deliberately doesn't touch it except when it's processing an interrupt.

One hardware device that creates interrupts is a timer, like an alarm clock. The OS sets the alarm clock before it starts running code from a process. When the alarm clock rings, it makes an interrupt and then the CPU is running OS code once again, even if the process got into an infinite loop.

An OS can run multiple processes on one CPU by cycling through them and setting short alarms (few milliseconds, or less). Of course, the OS also knows which processes don't want to run (which is most of them, most of the time) and skips over those.

Other than timers, interrupts are also used for all sorts of hardware, especially inputs like mice and keyboards so that the OS can do something immediately when you press a key.


Multiple processors. What about the other 3 CPUs? Actually that one's easy - you use the main CPU to send them some specific signal (just like you send signals to disk drives or keyboards) that tells them to turn on and what code address to start from.

$\endgroup$
2
  • $\begingroup$ Wow, this answer is very illuminating. Such a crude explanation of how things really work. You really brightened up my messy ideas, now I have more direction. I think creating a hardware simulator from scratch even on an already existing operating system can help me understand even more. Thanks you really helped me a lot. $\endgroup$
    – gmmk
    Apr 19 at 15:39
  • 1
    $\begingroup$ Note that a lot of the explanations in the answer are very specific to PCs. PCs are very messy devices. I read somewhere that the engineers who designed the PC 45 years ago said if they had known that the cheap one-off product they were creating would be copied and cloned and become the standard for practically every computer in the world for (now approaching) 50 years, they would have made a lot of decisions differently. For example, when it comes to the boot process and low-level hardware interaction, OpenFirmware is far superior to the BIOS and even UEFI. $\endgroup$ Apr 19 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.