Mateo Notes

When we type:

./hello

it feels like something very simple happens.

We execute a file, and suddenly a program is running.

But from the operating system's point of view, there is a lot more going on.

This post is a small journey from a command in the shell to a running process.


1. The Shell

First, the shell receives our command:

./hello

The shell doesn't magically execute the file itself.

A typical Unix shell creates a new process and asks the operating system to replace that process's program image with the requested executable.

One important system call involved here is:

execve();

For example:

char *argv[] = {
    "./hello",
    NULL
};

execve("./hello", argv, NULL);

The interesting thing about execve() is that

Welcome to Mateo Notes.

This is the first test post of my personal technical blog.

I want to use this place to document what I learn while exploring systems programming, operating systems, Unix, FreeBSD, C/C++, networking, debugging, and computer architecture.


Why This Blog?

I have always been interested in what happens underneath the abstractions we use every day.

For example, when we run:

ls -la

it looks simple.

But underneath that command, the operating system has to create and manage a process, interact with the filesystem, access directory entries, perform system calls, and eventually write the result to a file descriptor.

That is the part I want to understand.


A Small C Program

Here is a simple example:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    printf("PID: %d\n", getpid());

    return 0;
}

We can compile it with:

cc -Wall -Wextra -O0 -g main.c -o main

and run it:

./main

The program prints its own process ID.

That tiny example already gives us several things to explore:

  • Processes
  • System calls
  • File descriptors
  • The C runtime
  • The kernel
  • Virtual memory
  • ELF binaries

What I'm Learning

Some of the topics I am currently exploring:

  1. Operating Systems
  2. Unix internals
  3. FreeBSD
  4. C and C++
  5. Networking
  6. GDB
  7. Memory management
  8. RISC-V
  9. Computer architecture

I am particularly interested in understanding how things work, rather than only learning how to use them.

Don't just learn the API. Understand what happens underneath it.


Virtual Memory

One of the topics I'm currently studying is virtual memory.

A process sees something approximately like this:

Process Virtual Address Space

┌─────────────────────┐
│       Stack         │
├─────────────────────┤
│                     │
│        Heap         │
├─────────────────────┤
│        Data         │
├─────────────────────┤
│        Text         │
└─────────────────────┘
          │
          ▼
      Page Tables
          │
          ▼
   Physical Memory

The interesting part is that the addresses used by a process are not simply physical RAM addresses.

The CPU and operating system work together to translate virtual addresses into physical addresses.

That abstraction is one of the foundations that makes modern multitasking systems possible.


Debugging

I also want to spend more time understanding programs through debuggers rather than treating them as magical tools.

For example:

gdb ./main

Then:

break main
run
disassemble main
info registers

Being able to move between:

C source
   ↓
Compiler
   ↓
Assembly
   ↓
Machine code
   ↓
CPU
   ↓
Operating system

is one of the things I find most interesting about systems programming.


What to Expect

This blog will mostly contain:

  • Technical notes
  • Experiments
  • Small projects
  • Unix and FreeBSD explorations
  • C/C++ experiments
  • Operating system concepts
  • Networking experiments
  • Debugging sessions
  • Things that I got wrong and eventually understood

I don't want this to be a collection of polished tutorials.

I'd rather document the process of figuring things out.


One More Thing

Most of the posts here will start with a question.

Something like:

What actually happens when a program calls read()?

Then I'll try to follow that question down the stack.

Maybe it starts in C.

Then assembly.

Then a system call.

Then the kernel.

Then a device.

And eventually, perhaps, hardware.

That's the kind of rabbit hole I want this blog to be about.

Welcome to Mateo Notes.