Hey Vedanta,
I see that folks have already suggested courses/books like nand2tetris, LLD3, etc. which is fantastic. I was in a similar situation few years back. I will try to structure a learning path for you in this email.
Few key suggestions:
- Jumping into the kernel itself by reading Robert Love’s book or any other linux kernel textbook will only give you a high level idea of the kernel. It very hard to make sense of the kernel today because every subsystem is so interconnected, it forms a circular dependency.
- Fundamentals of CPU architecture, memory, interrupts, I/O should be very strong before the kernel will start making sense.
Consider the following questions:
— Where does the kernel begin executing?
— How does the kernel binary get linked and how does it get into RAM before being executed? Who does it?
— What is the difference between privileged software vs. normal user applications? What is the difference deep down in the architecture?
— What is a virtual address? And why do we need virtual addressing?
— Who compiled the first compiler?
— How does code get linked? What is linking anyway?
— How does the scheduler know when to pull out a thread from CPU?
These are some very fundamental questions which go unaddressed if you directly jump into linux kernel. The books try to explain — I strongly believe a better approach is needed.
- Stick to one hardware architecture and understand it completely. I am heavily biased towards ARM64 and would suggest you the same — mostly because even a kid can read their documentation and make sense of it. It’s very well written.
- Learning things bottom up. The top down approach will keep you confused. Its like learning English, but starting with Shakespeare instead of the alphabet.
Courses:
- nand2tetris
— The focus is to start from transistors, logic gates, connect them to make complex digital logic like, multiplexers, demultiplexers, adders, flip-flops etc. These are then connected to make memory, CPU, memory-mapped display, etc.
— Part 2 of the course focuses on writing software for the hardware you have built in Part 1. They start with an assembly language of their own, write an assembler, a virtual machine, a compiler and finally an operating system.
- Build your own RTOS [1]
— You build your own tiny RTOS and a nice scheduler for it. It’s an aha-moment when you see your scheduler context switch and run different threads concurrently.
- Write your own x86 32-bit operating system [2]
— In this course, you will learn about writing a small boot loader and a full fledged kernel with userspace on x86. The biggest takeaway is that you will understand how virtual memory works and how the memory manager allocates, maps, and handles different virtual address spaces (for different processes).
After completing these three, you should have a very good idea of how software actually runs on a machine. Then, you are on your own. You can step into the linux kernel.
Start from arch/arm64/kernel/head.S and follow along and see how the linux kernel sets up memory, loads page tables, etc. etc. — it will take time but its very interesting.
In parallel, I would suggest you to write your own tiny kernel for ARM / x86. You should be able to emulate a Raspberry Pi 3 / 4 on QEMU.
If you prefer reading instead of watching courses, then Computer Systems by Randall Bryant [3] is a book you’ll love.
Hope this helps and all the best!
Yuvraj Sakshith
---