distros
alpine linux
The small and simple linux distro.
void linux
Good for when you can't use musl.
debian
Old, reliable, but cluttered.
fedora
Gnome + some other stuff.
arch linux
Good beginner distro.
gobo linux
A very interesting rethinking of the filesystem.
lineage os
Fork of android without as much awfulness.
postmarket os
Linux on phones!
packaging
fpm
Generate packages easily for several distros.
void packaging
Pretty simple system, but unfortunately uses github also sometimes musl can complicate compiling poorly made software.
printing
cups
Common Unix Printing System
power saving
The main tools to checkout are tlp (a daemon) and powertop (an info utility).
command line arguments
View the arguments used to launch the current kernel:
cat /proc/cmdline
Update arguments using your boot loader.
Configure and view kernel parameters with sysctl:
sysctl -a
framebuffer color themeing
You can actually theme the linux console itself with some kernel parameters:
vt.default_red=0x07,0xdc,0x85,0xb5,0x26,0xd3,0x2a,0xee,0x00,0xcb,0x58,0x65,0x83,0x6c,0x93,0xfd vt.default_grn=0x36,0x32,0x99,0x89,0x8b,0x36,0xa1,0xe8,0x2b,0x4b,0x6e,0x7b,0x94,0x71,0xa1,0xf6 vt.default_blu=0x42,0x2f,0x00,0x00,0xd2,0x82,0x98,0xd5,0x36,0x16,0x75,0x83,0x96,0xc4,0xa1,0xe3
It also seems like you can specify the numbers in base10 on newer kernels:
/sys/module/vt/parameters cat default_blu
0,0,0,0,170,170,170,170,85,85,85,85,255,255,255,255
Much of the information online talks about using escape codes, which is quite obviously flawed as the colors will be reset to their "defaults" with certain commands, it wont apply to all VTs and there's no way to have it take effect immediately.
meltdown mitigations
You can turn them off with mitigations=off
.
watchdog
The Linux kernel can reset the system if serious problems are detected. This can
be implemented via special watchdog hardware, or via a slightly less reliable
software-only watchdog inside the kernel. Either way, there needs to be a daemon
that tells the kernel the system is working fine. If the daemon stops doing
that, the system is reset. For a desktop system this daemon / system isn't
needed because you can just restart the computer yourself. You can turn it off
with nowatchdog
.
performance
Measuring the performance of a program, generating flame graphs, and so forth is
generally done with the tool of perf
:
https://perf.wiki.kernel.org/index.php/Tutorial
There are various TUI and GUI tools for it.
OOM (out of memory)
https://github.com/rfjakob/earlyoom
The default OOM killer on linux is designed for maximum stability. The absolute last thing it will do is kill a process, instead it will switch everything to swap and empty every buffer. This means if a program goes out of control with memory usage your whole system locks up. There's a userspace daemon called earlyoom killer which is more appropriate for destkop usage.
swap
create swap file
dd if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
Finally, add the swapfile to your /etc/fstab
/swapfile none swap defaults 0 0
swappiness
A value between 0-200 (or 100 on kernels <5.8) how likely the kernel is to use
swap
. A value of 100 means the IO is considered equal on both. Most systems
have a default of 60, which is quite a bit too high.
sysctl vm.swappiness
You can change it in /etc/sysctl.conf
:
vm.swappiness=10
LD_PRELOAD
If you set LD_PRELOAD to the path of a shared object, that file will be loaded
before any other library (including libc.so). Note that you should use an
absolute path as it's often run from a program with a different working
directory. So you could run ls with a custom malloc
implementation for
example:
LD_PRELOAD=/path/to/my/malloc.so /bin/ls
Sometimes you need to use this to overwrite an non-global function (easy to
check with objdump). Instead, you must override the library loading function
dlopen
and forward most calls to the original dlpopen
calls, until you
encounter the library you're actually looking to overwrite. Another thing to
note is that memory containing an executable can't normally be injected. (That
would be a massive security hole). You must first change the protections at
runtime with mprotect
. Here's an example of a binary patch for Papers Please.
void patch_function(void* ptr, size_t offset) {
char* func = reinterpret_cast<char*>(ptr);
func += offset;
const long page_size = sysconf(_SC_PAGESIZE);
int result = mprotect(page_round_down(func, page_size), 1, PROT_READ | PROT_WRITE | PROT_EXEC);
if(result) {
fprintf(stderr, "result %d %d\n", result, errno);
return;
}
func[0] = 0xc3; // the actual patching
mprotect(page_round_down(func, page_size), 1, PROT_READ | PROT_EXEC);
}
using dlopen_t = void* (*)(const char*, int);
extern "C"
void* dlopen(const char* filename, int flags) {
static dlopen_t real_dlopen = nullptr;
if(!real_dlopen)
real_dlopen = reinterpret_cast<dlopen_t>(dlsym(RTLD_NEXT, "dlopen"));
void* handle = real_dlopen(filename, flags);
if(!filename || filename != "././lime.ndll"s) {
return handle;
}
void* func = dlsym(handle, "SDL_SemWait");
if(!func) {
fprintf(stderr, "could not find symbol: %s\n", symbol);
return handle;
}
patch_function(func, 43952);
return handle;
}
This code is from this incredible writeup: https://blog.jhm.dev/posts/papers-please/