Linux – How Linux GUI Works at the Lowest Level

guihardwarelinuxlinux-kernelsystem-calls

I'm basically trying to figure out how one would go about making a GUI from absolute scratch with nothing but the linux kernel and programming in C.

I am not looking to create a GUI desktop environment from scratch, but I would like to create some desktop applications and in my search for knowledge, all the information I have been able to find is on GUI APIs and toolkits. I would like to know, at the very least for my understanding of the fundamentals of how linux GUI is made, how one would go about making a GUI environment or a GUI appllication without using any APIs or toolkits.

I am wondering if for example:

  1. existing APIs and toolkits work via system calls to the kernel (and the kernel is responsible at the lowest level for constructing a GUI image in pixels or something)

  2. these toolkits perform syscalls which simply pass information to screen drivers (is there a standard format for sending this information that all screen drivers abide by or do GUI APIs need to be able to output this information in multiple formats depending on the specific screen/driver?) and also if this is roughly true, does the the raw linux kernel usually just send information to the screen in the form of 8-bit characters?

I just really want to understand what happens between the linux kernel, and what I see on my screen (control/information flow through both software and hardware if you know, what format the information takes, etc). I would so greatly appreciate a detailed explanation, I understand this might be a dousie to explain in sufficient detail, but I think such an explanation would be a great resource for others who are curious and learning. For context I'm a 3rd year comp sci student who recently started programming in C for my Systems Programming course and I have an intermediate(or so I would describe it) understanding of linux and programming. Again Thank you to anyone who helps me out!!!

Best Answer

How it works (Gnu/Linux + X11)

Overview

It looks something like this (not draws to scale)

┌───────────────────────────────────────────────┐
│                       User                    │
│     ┌─────────────────────────────────────────┤
│     │             Application                 │
│     │            ┌──────────┬─────┬─────┬─────┤
│     │            │      ... │ SDL │ GTK │ QT  │
│     │            ├──────────┴─────┴─────┴─────┤
│     │            │            xLib            │
│     │            ├────────────────────────────┤
├─────┴───┬────────┴──┐         X11             │
│   Gnu   │ Libraries │        Server           │
│   Tools │           │                         │
├─────────┘           │                         │ 
├─────────────────────┤                         │
│   Linux (kernel)    │                         │
├─────────────────────┴─────────────────────────┤
│                    Hardware                   │
└───────────────────────────────────────────────┘

We see from the diagram that X11 talks mostly with the hardware. However it needs to talk via the kernel, to initially get access to this hardware.

I am a bit hazy on the detail (and I think it changed since I last looked into it). There is a device /dev/mem that gives access to the whole of memory (I think physical memory), as most of the graphics hardware is memory mapped, this file (see everything is a file) can be used to access it. X11 would open the file (kernel uses file permissions to see if it can do this), then X11 uses mmap to map the file into virtual memory (make it look like memory), now the memory looks like memory. After mmap, the kernel is not involved.

X11 needs to know about the various graphics hardware, as it accesses it directly, via memory.

(this may have changes, specifically the security model, may no longer give access to ALL of the memory.)

Linux

At the bottom is Linux (the kernel): a small part of the system. It provides access to hardware, and implements security.

Gnu

Then Gnu (Libraries; bash; tools:ls, etc; C compiler, etc). Most of the operating system.

X11 server (e.g. x.org)

Then X11 (Or Wayland, or ...), the base GUI subsystem. This runs in user-land (outside of the kernel): it is just another process, with some privileges. The kernel does not get involved, except to give access to the hardware. And providing inter-process communication, so that other processes can talk with the X11 server.

X11 library

A simple abstraction to allow you to write code for X11.

GUI libraries

Libraries such as qt, gtk, sdl, are next — they make it easier to use X11, and work on other systems such as wayland, Microsoft's Windows, or MacOS.

Applications

Applications sit on top of the libraries.

Some low-level entry points, for programming

xlib

Using xlib, is a good way to learn about X11. However do some reading about X11 first.

SDL

SDL will give you low level access, direct to bit-planes for you to directly draw to.

Going lower

If you want to go lower, then I am not sure what good current options are, but here are some ideas.

Links

X11

https://en.wikipedia.org/wiki/X_Window_System

Modern ways

Writing this got my interest, so I had a look at what the modern fast way to do it is. Here are some links:

https://blogs.igalia.com/itoral/2014/07/29/a-brief-introduction-to-the-linux-graphics-stack/

Related Question