I noticed that a framebuffer doesn't always exist on some systems. In these cases, how does bash print to the screen (assuming it ever uses fb devices at all)? Since there's no framebuffer device, does this mean that bash knows how every graphics card out there works and can directly write to their registers, or does it use some other API?
Shells are command-line utilities - they read input and write output. Typically interactive shells are open on terminal devices - which are generally kernel-buffered serial-mode character devices - something like
| pipes but with extra stuff like modem control and i/o interpretation modes. Some other program reads and interprets data written to terminal devices for display and writes its its standard input into the end of the terminal device which the shell reads.
This is a terminal emulator. At least - that is the typical configuration. A terminal might be an actual terminal - like a big, humming, glowing piece of hardware replete with vacuum tubes the size of your head, or perhaps it is a room-sized printer around which you should take special care of where you rest your hands lest you lose them.
But typically a terminal emulator is a program that understands a more or less standard protocol for text configuration and can translate the shell's i/o into something which might be drawn to a screen. The linux kernel comes with the kernel virtual consoles - which are built-in display ports and to which it connects its built-in terminal emulator.
xterm is another kind of terminal emulator - one which draws to a framebuffer by way of the
However it is done, though, the shell is quite a ways removed from the process.
bash does not print to a screen nor framebuffer device directly. It just writes its output to a simple file descriptor.
Second, linux supports both graphics mode consoles and text mode consoles. So, when your configuration does not use framebuffer driver then the text mode console is activated. There is a good article at wikipedia on the topic.