Getting Started with Systems Programming - Introduction
Have you ever gotten a Blue Screen of Death?
This is one of the most dreaded sights for any computer user. It signals entry to a mysterious land, a land of no return for your computer. Most of us despair when we see this on our machines, even the most seasoned engineers among us. We might not understand fully what’s going on when we get a BSoD, but we do know that there’s something fundamentally wrong with the computer. Some core part of how the machine operates is broken, and there’s not really much we can do about it except employ the age-old wisdom: turning it off and on again. For most folks that I’ve encountered on my engineering journey, the words systems programming conjures up similar emotions to seeing a BSoD. I know that this was certainly the case for me when I started learning about systems. In this series of posts, I’m going to try to share some of my systems knowledge, in hopes that it will inspire y’all to dig into systems programming a bit more!
First things first, I’m Jahz! I’m a senior computer science undergrad student at Georgia Tech. I’ve been introduced to systems programming through my classes at school, and I’m excited to share some of the knowledge I’ve gathered so far.
In my time taking systems classes at Tech, I’ve had to do my fair share of Googling around for help, as all good software engineers do. I don’t know if you’ve ever had to search for help on systems topics before, but let me tell you: a good tutorial or blog post on systems stuff is hard to find. Compared to content on, say, building a web app in React, there just isn’t much out there aimed at systems beginners. Most of the stuff I found was really dry and arcane, or just non-existent. After having to suffer through a lot of fruitless searches, I was determined to help the situation by creating some of my own systems content.
These posts are aimed at folks that are pretty familiar with basic programming concepts but haven’t dipped their toes into systems programming before. One of the biggest barriers in learning about systems stuff is the language barrier. Systems software is largely written in either C/C++ or assembly. These are big topics as well, and can merit their own post series. I’m going to try to keep these discussions as code-free as possible, but I will invariably have to include code at various points. If you’re not familiar with things like pointers, I’d suggest checking out <TODO: find a good C tutorial to link here>.
What the heck is systems programming anyway?
Systems programming is an umbrella term for programming that happens at the hardware-software interface. Hardware is the physical components of computing: processors, memory, devices like monitors and printers, and networking hardware. Software is our way of utilizing this hardware to accomplish tasks. We can think of computing as a set of layers, starting at the physical and working our way up:
- Silicon in computer components
- Operating Systems
- Web browsers
- Word processors
Systems programming takes up the middle part of these layers. It’s the glue that holds the world of applications (things that are useful to people) to the hardware (the stuff we need to actually be able to do those useful things). More specifically, systems programming covers things like operating systems, compilers, firmware, and networking software. Looking at the computing stack this way, we can see that systems software is really about layers of abstraction. I think of abstractions as hiding the hard work of a task behind a pretty looking façade. For instance, a car is a layer of abstraction (really it’s several) over transportation. Before cars, most people walked when they wanted to go somewhere. Walking takes a certain amount of effort, and walking long distances can be tedious. Cars seem to reduce the hard work of walking by taking the energy we would expend through walking and hiding it behind the hood of car. In the same way, systems software provides an abstraction over the hardware of the computer, so that applications don’t have to directly deal with the hardware themselves.
To move this analogy over to the computing world, think about opening a file on your computer. When you double click a Word document, Word can open that file and let you read and edit it as if it were a sheet of paper sitting on your desk. To you, the file seems like one whole, cohesive object. In reality, the data that makes up that document is split into chunks that are all in different places on your computer’s drive. Imagine having to edit files by going into the disk, finding these chunks, and changing individual bits! No one would want to use computers. The systems software in your computer creates a layer of abstraction over the disk, allowing Word to read the file out from the disk and display it on the screen as if it were one contiguous chunk of data. The systems software, in this case the operating system, does the dirty work for you.
Sounds kinda scary!
I totally feel you! Systems programming is often seen as a scary beast that is best left to crazy people who like suffering. A large part of why I want to write this content is to try and fight that stereotype. I don’t want to sugarcoat it: systems programming is hard. Coming from a higher level on the computing stack, it can be hard to readjust your paradigms of how computers work. While it is definitely a difficult area of computing to master, it’s not impossible! Systems aren’t just for genius, lone cowboy codeslingers that eat, live, and breath in binary. I firmly believe that anyone who is in the software business can pick up systems programming. In fact, I believe that a lot of folks could benefit in their everyday coding lives from knowing a little bit about systems. It’s been my experience that learning these concepts has made picking up things that are higher on the stack a little easier. Writing systems software has also increased my confidence in my programming ability as a whole. it can definitely be scary to dive into the world of the software/hardware interface, but I think it’s a process that you’ll find worthwhile.
If you want a deeper dive into the topics I’ll be covering, you can take a look at Computer Systems: An Integrated Approach to Architecture and Operating Systems, which is one of the textbooks at Georgia Tech. My series is going to be roughly based on this book, with some additional inspiration from the xv6 textbook, the textbook used at Georgia Tech’s OS class (originally created at MIT). I’ll be publishing this series over the course of this semester and year.
I’m very excited to be starting this series! It’ll be the first time I take on an extended writing project, so constructive feedback would be welcome! Let me know if there’s something in particular that you’d like me to cover, or any other ideas and thoughts you have.