|
2 months ago | |
---|---|---|
LICENSE | 2 months ago | |
README.md | 2 months ago | |
makefile | 2 months ago |
a linux distribution for people who like to breathe manually.
this repository contains documentation and helper scripts only. a working linux distribution with overlayfs support (preferably alpine linux) and an internet connection are required to bootstrap lix os. no images or binaries supplied.
lix os uses the lix package manager to construct a musl-based linux distribution from source code. it is entirely composed of simple, short-as-possible, POSIX-compliant shell scripts. packages are built in chroots constructed from package directories stacked on top of each other using overlayfs. only dependencies explicitly listed in a package's 'deps' file are accessible during the package's build process. there is no concept of "indirect dependencies." packages are made available to the user by soft-linking package directory contents into the system root. packages can be added to or removed from the system root without uninstalling the packages entirely.
lix os is the work of a single maintainer and follows the same "use fewer packages" ethos that kiss linux does. it also tries to use the smallest packages possible in order to create a more readily audited codebase. some exceptions are made in the name of usefulness and self-hosting. generally, suckless utilities are preferred to bsd utilities, and bsd utilities are preferred to gnu utilities due to the preferred in each case generally having a smaller, easier to understand codebase. this does mean lix os's versions of common linux utilities may have fewer options than one may be used to, but many of these missing options are either not commonly used or can be compensated for with a short shell script or function.
in the opinion of lix os' maintainer, it would be ideal if everyone knew and understood every line of code executing on their machines. while a perfect realisation of this dream is unlikely, lix hopes to make the problem less intractable. lix os will never ship binaries.
lix os is an experimental linux distribution. it may not work. it may catch on fire. it may be abandoned at a moment's notice for another experiment. it will not stop you from doing something stupid and destroying your system. it is not and probably never will be "production ready."
nonetheless, the original author currently uses it daily, and it may serve the needs of others as well.
lix helps lix os maintain system hygiene by:
all changes during the patching, configuration, building, and installation
phases go into overlays maintained by lyr
. this helps keep the source code in
src
's repository pristine and makes it very simple to activate and deactivate
packages. it also makes it easy to see what packages have supplied each file in
one's system root.
lix os is simple. if one disagrees with a decision, one should fork away. it should never take more than a single person to maintain a lix os-based distribution and all its packages.
there are some blockers to achieving a fully statically linked system.
smartcard support is not possible at this time without dynamic linking. in particular, 'scdaemon' from gnupg loads 'libpcsclite.so' at runtime. there is not yet a way to make it statically link the library instead. accordingly, the executables provided by the 'gnupg' package in lix os are linked statically and do not support smartcards, while the executables in the 'gnupg-dynamic' and 'pcsc-lite' packages are linked dynamically and do support smartcards.
both x11 and wayland have dependencies which use meson as their build system. meson requires core python3 modules which use dynamic loading (e.g., ctypes), which means python3 must be dynamically linked in order to use the meson build system. the default python3 package is statically linked and does not contain many "core" modules due to their dependency on the 'dlopen' function. if a gui is desired, the 'python3-dynamic' package will have to be built.
removing the meson dependency is possible. oasis linux has pioneered this approach. the best approach would probably be to either port the packaging or the build system from oasis linux. preferably the latter, since doing so would better enable collaboration between our projects, but in theory a lua script could also be written to translate oasis linux packaging into shell scripts for those unwilling to learn the lua-based build system.
mesa and wayland also tend to not work well when statically linked. in theory it should be possible to statically link these components, but in practice it seems to result in segmentation faults. there is probably a way to fix this problem, but in the meantime a graphical desktop will require dynamic linking.
the kbd
package, which supplies console utilities like setfont
, requires
gettext
, and gettext
will not build statically due to symbol collisions
during while linking. this is also probably fixable, but it would be better to
remove the gettext
dependency entirely if possible.
because it should be possible to quantify all of a program's possible states at compile time, barring hardware-level shenanigans, from source code. a user should never be put in the position where they are surprised by a change in a program's behavior because a dynamically loaded library was updated. this seems analogous to lexical versus dynamic scoping in programming languages.
there are ways to achieve these sorts of guarantees without sacrificing dynamic loading, but they are more complicated than simply linking statically.
also, no dynamic loader means no dynamic loader vulnerabilities.
below is the "official path," but please try other ways and report back.
it is assumed that each step is executed from the same directory. e.g., ~
.
if one prefers to use the linux kernel which contains propietary firmware blobs,
replace references to linux-libre
below with linux-kernel
.
create an alpine linux installation. leave the target device untouched as it will need to be formatted and partitioned.
install the bootstrap dependencies:
apk add build-base coreutils cmake git curl rsync cryptsetup autoconf automake libtool flex bison ncurses-dev
install a command-line text editor and set the EDITOR variable. (optional)
e.g., apk add vim && export EDITOR='vim'
(n.b.: if this step is skipped, vi
will be used.)
(n.b.: in a later step, libraries get moved. if this breaks the text
editor, try another one. if all else fails, vi
is known to work in alpine
linux and comes installed by default.)
clone the lix-os repository and its subrepositories, and install them.
git clone http://git.fuwafuwaqtlkkxwc.onion/yafox/lix-os
cd lix-os
make
make install
create a bootstrap layer
mkdir bootstrap
./lix-os/utilities/mkbootstrap.sh bootstrap
supply a linux kernel configuration file (strongly recommended but optional)
mkdir linux-mnt
lix --bootstrap=bootstrap pull linux-libre
lix --bootstrap=bootstrap mount linux-mnt linux-libre
linux-mnt/mnt/src/.config
(n.b.: many distributions have their own kernel configuration files which
can be borrowed. lix os' maintainer keeps a public collection of examples
in the linux-confs repository.)lix umount linux-mnt linux-libre
rmdir linux-mnt
prepare the destination device.
build lix os
"$utilsdir/bootstrap.sh" bootstrap
(n.b.: some packages will require interactive configuration via text
editor. if a package fails, bootstrapping can be resumed from the same
point later by passing the name of the package as a second argument. e.g.,
"$utilsdir/bootstrap.sh" bootstrap <failing package>
. this script just
loops over the dependencies of the lix-os
package, add
s them, and then
up
s them in the lix-os
chroot. it's a short script. don't be afraid
to examine and modify it.)copy lix os to the target medium
mkdir -p lix-os-tgt/boot
lix-os-tgt
lix-os-tgt/boot
lix-os-tgt
."$utilsdir/install.sh" lix-os-tgt
(n.b.: this script copies the contents of the lix-os chroot and the src
and lyr
repos in /usr/var to the target directory given, then chroots
in to the target directory and replaces all the real files with softlinks
to the appropriate targets in the lyr
repository via lix up -f
.)make last-minute configuration changes to boot-related partitions
lix-os-tgt/boot/grub/grub.cfg
to point to the
correct partitions.at this point, if one wishes to skip using symlinks to link installed packages into the system root instead of having them copied from the package chroots, one may skip to the last step.
unmount boot-related partitions
umount lix-os-tgt/boot
lix up
or lix dn
anything with files related to booting.
linux-libre
, lix-os-bootloader
, and lix-os-initramfs
immediately
come to mind as such packages.)convert everything else to symlinks
"$utilsdir/softlink.sh" lix-os-tgt
clean up and reboot into lix os
lix-os-tgt
.rmdir lix-os-tgt/boot lix-os-tgt
if all has gone well and the system is booting, make a backup of your kernel
and initramfs. mount the boot partition and copy vmlinux
to vmlinux.bak
and initramfs.igz
to initramfs.igz.bak
. this will allow for recovery by
changing boot parameters to boot with the backup files if one misconfigures
one's kernel or initramfs in the future.
the contents of the initramfs file can be examined and modified using the
lix mount
command, the same as every other lix package.
lix os tries to be compositional in its architecture, which should make it easier to replace components as desired. this flexibility comes at the expense of having all files relevant to a package in a single location. an earlier iteration of lix os (called 'mu os' in ignorance of the other linux distribution by that same name) opted for a tighter integration of parts, which was nice in some ways but which also tended toward creating a monolith.
ideally the lix package manager should be composed of simple tools that behave in a clear, consistent manner and which have no notions about each other.
there are also a number of helpful scripts in the lix-os-utilities
repository.
for example, the versions
utility, which itself also depends on vercmp
and
shsort
, may be useful for keeping a lix os system up to date. versions
returns a sorted list of available package versions pulled directly from each
project maintainer's website and/or its mirrors. lix does not use it directly,
but the author does use it periodically to update src
packages.
it would be nice to create something like nix os that captures changed state rather than requiring state be constructed from a configuration file in a domain-specific language.
the development of lix os was inspired and aided by the examples set by the following projects: