cloudos handbook
installing cloudos 1.0 on x86_64.
1. about cloudos
cloudos is a minimal linux that you build yourself. after installation the system has only a console.
| parameter | value |
|---|---|
| architecture | x86_64 |
| libc | glibc |
| init | openrc |
| kernel | vanilla from kernel.org |
| bootloader | limine |
| filesystems | ext4 and btrfs |
| packages | only from source, the command cloudpkg |
1.1 what you need
| what | guideline |
|---|---|
| cpu | x86_64. arm is not supported |
| ram | from 2 gb, for building the kernel and packages 4 gb or more is better |
| disk | from 10 gb, for building packages 20 gb or more is better |
| boot | uefi or legacy bios |
| network | wired, address by dhcp |
| media | a usb stick with the cloudos live iso |
the numbers are approximate, there are no hard checks.
1.2 what is inside stage 3
stage 3 is built from scratch following lfs 12.4 (sysv variant) and extended with everything needed for installation and building packages. versions are given for cloudos 1.0.
| part | what is inside |
|---|---|
| toolchain | gcc 15.2.0, glibc 2.42, binutils 2.45, python 3.13.7 |
| init | openrc 0.63, /sbin/init points to openrc-init |
| devices and console | udev, agetty on tty1 |
| log | sysklogd |
| network | dhcpcd 10.1.0, curl 8.15.0, git 2.51.0, ca-certificates |
| permissions | opendoas 6.8.2 instead of sudo |
| editor | nano 8.4 |
| disks | dosfstools 4.2, btrfs-progs 6.16.1, ext4 from e2fsprogs |
| boot | dracut-ng for initramfs. stage 3 has no kernel or bootloader |
1.3 what the system does not have
- graphics and desktop environments. after installation there is only a console
- man pages. help is this handbook and the key
--help - an ssh server and a firewall
- sudo. doas is used instead
- users other than root, locales and swap. you create them yourself
- a bootloader and a kernel. you build the kernel and install the bootloader through the package manager
1.4 installation order
- boot from the live iso, check the network and boot mode
- partition the disk and create the filesystems
- download and unpack stage 3
- enter chroot and set up the build
- build the kernel
- make the initramfs, fstab and install limine
- set a password, enable services and reboot
- set up the system after the first boot
1.5 how to use the handbook
at the top of the left panel there is a switch between uefi and bios. choose your mode and only the needed commands will remain in the handbook. the choice is remembered in the browser.
search opens with the button in the header or with the keys ctrl + k. every command block has a copy button at the top right.
commands contain placeholders, replace them with your own values:
| placeholder | what to put |
|---|---|
/dev/sda, /dev/sda1, /dev/sda2 | your disk and partitions from lsblk. nvme has different names, see appendix a |
ROOT_UUID | uuid of the root partition from blkid |
ESP_UUID, BOOT_UUID | uuid of the /boot partition from blkid |
6.18.10 | kernel version, if you build a different one |
2. preparation
boot from the cloudos live iso and check the network.
dhcpcd
ping -c1 github.com
determine the boot mode.
[ -d /sys/firmware/efi ] && echo uefi || echo bios
2.1 date and time
if the system date is wrong, https certificates will fail verification and downloads will fail with confusing errors. check the date:
date
if it differs a lot from the real one, set it manually (format year-month-day hour:minutes:seconds):
date -s "YYYY-MM-DD HH:MM:SS"
2.2 disks
look at the disks and partitions. the disk name you need is then used everywhere instead of /dev/sda.
lsblk -f
sata and usb disks are called sda, sdb, nvme is nvme0n1, virtual vda. you can tell which one is the live iso stick by its size.
2.3 network
check that the interface is visible and got an address:
ip link
ip addr
if there is no address, run dhcpcd again for the needed interface (see the name in ip link):
dhcpcd eth0
only wired network is set up out of the box. wifi is not configured in the live iso.
2.4 if sites do not open
github, kernel.org and some mirrors may be unavailable from your network. then download the file on another device and move it with a usb stick:
mkdir -p /mnt/usb
mount /dev/sdb1 /mnt/usb
ls /mnt/usb
instead of /dev/sdb1 put the partition of your second usb stick from lsblk. there are mirrors for the kernel, see 7.3.
3. disk and filesystems
3.1 partitioning
cfdisk /dev/sda
| mode | table | partitions |
|---|---|---|
| uefi | gpt | sda1 512 mb, type efi system. sda2 the rest |
| bios | dos | sda1 512 mb, bootable flag, this is /boot. sda2 the rest |
3.2 filesystems
for uefi the /boot partition is formatted as fat32:
mkfs.fat -F32 /dev/sda1for bios the /boot partition is always fat32:
mkfs.fat -F32 /dev/sda1format the root partition as ext4:
mkfs.ext4 /dev/sda2
or as btrfs:
mkfs.btrfs /dev/sda2
3.3 mounting
mkdir -p /mnt/cloudos
mount /dev/sda2 /mnt/cloudos
mkdir -p /mnt/cloudos/boot
mount /dev/sda1 /mnt/cloudos/boot
3.4 example layout
| partition | size | type | mount point | filesystem |
|---|---|---|---|---|
| sda1 | 512 mb | efi system | /boot | fat32 |
| sda2 | the rest | linux filesystem | / | ext4 or btrfs |
| partition | size | flag | mount point | filesystem |
|---|---|---|---|---|
| sda1 | 512 mb | bootable | /boot | fat32 |
| sda2 | the rest | - | / | ext4 or btrfs |
if you need a swap partition, make it the third, not the first. more about swap in 10.7. swap can also be a file after installation, then a separate partition is not needed.
3.5 checking
make sure everything is mounted as it should be:
lsblk -f
findmnt /mnt/cloudos
findmnt /mnt/cloudos/boot
the root should be on the second partition, /boot on the first. if one of the commands printed nothing, the partition is not mounted.
4. stage 3
stage 3 is a ready base cloudos system without a kernel and bootloader. the files are in the releases section of the repository.
github.com/wh1laye/cloudos-repo/releases
cloudos-stage3-1.0-x86_64.tar.xz
cloudos-stage3-1.0-x86_64.tar.xz.sha256
4.1 verification (can be skipped)
sha256sum -c cloudos-stage3-1.0-x86_64.tar.xz.sha256
4.2 unpacking
tar xpvf cloudos-stage3-1.0-x86_64.tar.xz --xattrs-include='*.*' --numeric-owner -C /mnt/cloudos
4.3 downloading
download straight onto the root partition, the live system has little memory:
cd /mnt/cloudos
curl -LO https://github.com/wh1laye/cloudos-repo/releases/download/cloudos/cloudos-stage3-1.0-x86_64.tar.xz
curl -LO https://github.com/wh1laye/cloudos-repo/releases/download/cloudos/cloudos-stage3-1.0-x86_64.tar.xz.sha256
then do the verification from 4.1 and the unpacking from 4.2. run the unpacking from the same folder where the archive is.
4.4 after unpacking
the archive is no longer needed, delete it so it does not take space:
rm /mnt/cloudos/cloudos-stage3-1.0-x86_64.tar.xz*
ls /mnt/cloudos
the list should contain bin, boot, etc, usr, var and other system folders. if the folder is empty, the archive was unpacked to the wrong place.
5. entering chroot
mount --types proc /proc /mnt/cloudos/proc
mount --rbind /sys /mnt/cloudos/sys
mount --make-rslave /mnt/cloudos/sys
mount --rbind /dev /mnt/cloudos/dev
mount --make-rslave /mnt/cloudos/dev
cp --dereference /etc/resolv.conf /mnt/cloudos/etc/
chroot /mnt/cloudos /bin/bash
source /etc/profile
5.1 what the commands do
| command | why |
|---|---|
mount --types proc | gives the system in chroot access to process information |
mount --rbind /sys, /dev | passes devices and sysfs from the live system inside |
--make-rslave | so that unmounting inside chroot does not affect the live system |
cp --dereference /etc/resolv.conf | carries over dns settings, without them there will be no site names inside chroot |
chroot /mnt/cloudos /bin/bash | makes /mnt/cloudos the root and starts bash in it |
source /etc/profile | pulls in the cloudos paths and environment variables |
5.2 prompt
so you do not forget you are in chroot, change the prompt:
export PS1="(cloudos chroot) $PS1"
5.3 entering again
if you rebooted the live iso or left chroot, mount the partitions again and repeat the entry. you do not need to unpack the archive again:
mount /dev/sda2 /mnt/cloudos
mount /dev/sda1 /mnt/cloudos/boot
mount --types proc /proc /mnt/cloudos/proc
mount --rbind /sys /mnt/cloudos/sys
mount --make-rslave /mnt/cloudos/sys
mount --rbind /dev /mnt/cloudos/dev
mount --make-rslave /mnt/cloudos/dev
cp --dereference /etc/resolv.conf /mnt/cloudos/etc/
chroot /mnt/cloudos /bin/bash
source /etc/profile
you enter the system the same way for repair if it stopped booting, see 14.9.
5.4 leaving
exit
umount -R /mnt/cloudos
if unmounting says target is busy, close all terminal windows where you were in chroot and repeat.
6. build setup
build flags are set in one file, /etc/cloudpkg/make.conf:
CC="gcc"
CFLAGS="-O2 -march=native"
MAKEOPTS="-j$(nproc)"
USE=""
for clang set CC="clang". then update the recipe list:
cloudpkg sync
6.1 locales
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
localedef -i en_US -f UTF-8 en_US.UTF-8
echo "LANG=en_US.UTF-8" > /etc/locale.conf
6.2 build flags
| parameter | what it means |
|---|---|
CC | compiler: gcc or clang |
CFLAGS | compilation flags. -O2 is ordinary optimization |
-march=native | code for the cpu of this machine. faster, but will not run on an older cpu |
-march=x86-64 | generic code, will run on any x86_64 |
MAKEOPTS | make parameters. -j is the number of parallel jobs |
USE | package feature switches, empty by default |
if you build on the same machine where you will work, leave -march=native. if you later move the disk to another computer, change it to -march=x86-64. stage 3 itself is built with generic flags.
6.3 parallel build
-j$(nproc) starts as many jobs as the cpu has threads. with little ram the build may fail with the message killed. then reduce the number:
MAKEOPTS="-j2"
6.4 gcc 15 and build errors
gcc 15 uses the c23 standard by default, and some old packages do not build with it. typical signs: errors about bool, true, false or function declarations without arguments. in that case return the previous standard:
CC="gcc -std=gnu17"
change the value CC in /etc/cloudpkg/make.conf and repeat the package installation.
7. kernel
the kernel is taken from kernel.org and configured by hand
cd /usr/src
curl -LO https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.18.10.tar.xz
tar xf linux-6.18.10.tar.xz
cd linux-6.18.10
make menuconfig
make -j$(nproc)
make modules_install
cp arch/x86/boot/bzImage /boot/vmlinuz-6.18.10
7.1 what to enable in menuconfig
in make menuconfig search opens with the key /, there you can find any option by name. a kernel without the needed drivers will not boot, so check at least these items. an asterisk [*] means built into the kernel, M means a module.
| option | why |
|---|---|
DEVTMPFS, DEVTMPFS_MOUNT | the /dev directory, needed by udev |
BLK_DEV_INITRD | booting with initramfs |
RD_GZIP, RD_XZ, RD_ZSTD | unpacking initramfs. enable all three so you do not have to guess how dracut compressed it |
EXT4_FS, BTRFS_FS | the root filesystem. enable built in, not as a module |
VFAT_FS, FAT_FS, NLS_CODEPAGE_437, NLS_ISO8859_1 | the /boot partition on fat32 |
TMPFS, PROC_FS, SYSFS | basic virtual filesystems |
BLK_DEV_NVME | nvme disks |
ATA, SATA_AHCI, BLK_DEV_SD | sata disks |
USB_XHCI_HCD, USB_XHCI_PCI, USB_HID | usb ports and keyboard |
NET, INET, PACKET, UNIX | network. without PACKET dhcpcd will not work |
| network card driver | for example E1000E for intel, R8169 for realtek. find out your card with the command lspci in the live iso |
INOTIFY_USER, SIGNALFD, TIMERFD, EPOLL, FHANDLE | udev needs this |
CGROUPS | openrc needs this |
VT, VT_CONSOLE, FRAMEBUFFER_CONSOLE, DRM_SIMPLEDRM | console output to the screen without a video card driver |
firmware, which stage 3 does not have. without a driver the console still works through DRM_SIMPLEDRM.a convenient start: if the live iso is built with support for /proc/config.gz, take its config as a base and add to it:
zcat /proc/config.gz > .config
make olddefconfig
make menuconfig
7.2 what the build commands do
| command | why |
|---|---|
make menuconfig | kernel configuration, the result is written to the file .config |
make -j$(nproc) | kernel build, takes from several minutes to an hour depending on the cpu |
make modules_install | installs the modules into /lib/modules/6.18.10, they are needed by dracut |
cp arch/x86/boot/bzImage | puts the kernel itself into /boot |
save the config and the symbol map, they will be useful when updating the kernel:
cp .config /boot/config-6.18.10
cp System.map /boot/System.map-6.18.10
7.3 kernel mirrors
if cdn.kernel.org does not open, download the same archive from a mirror:
curl -LO https://mirrors.aliyun.com/linux-kernel/v6.x/linux-6.18.10.tar.xz
curl -LO https://mirrors.ustc.edu.cn/kernel.org/linux/kernel/v6.x/linux-6.18.10.tar.xz
paths on mirrors sometimes change. if the link does not work, open the mirror directory in the browser and find the file by hand.
7.4 another kernel version
in all commands replace 6.18.10 with your version. the file names in /boot, in initramfs and in limine.conf must match.
8. bootloader
8.1 initramfs
cloudpkg install dracut
dracut --kver 6.18.10 /boot/initramfs-6.18.10.img
8.2 fstab
partition uuids are shown by blkid. the file /etc/fstab for uefi:
UUID=ROOT_UUID / ext4 defaults 0 1
UUID=ESP_UUID /boot vfat defaults 0 2
for bios:
UUID=ROOT_UUID / ext4 defaults 0 1
UUID=BOOT_UUID /boot vfat defaults 0 2
if the root is on btrfs, replace ext4 in the first line with btrfs.
8.3 limine
cloudpkg install limine
the file /boot/limine.conf is the same for uefi and bios:
timeout: 5
/CloudOS
protocol: linux
path: boot():/vmlinuz-6.18.10
cmdline: root=UUID=ROOT_UUID rw
module_path: boot():/initramfs-6.18.10.img
installation for uefi:
mkdir -p /boot/EFI/BOOT
cp /usr/share/limine/BOOTX64.EFI /boot/EFI/BOOT/BOOTX64.EFIinstallation for bios, put it on the partition:
cp /usr/share/limine/limine-bios.sys /boot/
limine bios-install /dev/ (your disk name /dev/sda1 /dev/sdb1 /dev/nvme0n1)8.4 check before rebooting
look at what is in /boot:
ls -l /boot
there should be vmlinuz-6.18.10, initramfs-6.18.10.img, limine.conf and the folder EFI/BOOT with the file BOOTX64.EFI.
there should be vmlinuz-6.18.10, initramfs-6.18.10.img, limine.conf and limine-bios.sys.
compare the uuids in the configs with the real ones:
blkid
grep UUID /etc/fstab /boot/limine.conf
the uuid of the root partition in limine.conf and in fstab must match the output of blkid. most failed first boots are due to a typo here.
8.5 writing to nvram (uefi only, optional)
this step is not needed in bios mode.
the file BOOTX64.EFI in EFI/BOOT the firmware finds by itself, and that is enough. if you want a separate boot menu entry, create it with this command from the live iso (not from chroot):
efibootmgr --create --disk /dev/sda --part 1 --loader '\EFI\BOOT\BOOTX64.EFI' --label CloudOS
for an nvme disk: --disk /dev/nvme0n1 --part 1. in the firmware settings disable secure boot, limine without a signature will not boot.
8.6 several kernels
before updating the kernel add a second entry to /boot/limine.conf, and do not delete the old one. if the new kernel does not boot, you pick the old one in the menu:
timeout: 5
/CloudOS
protocol: linux
path: boot():/vmlinuz-NEW
cmdline: root=UUID=ROOT_UUID rw
module_path: boot():/initramfs-NEW.img
/CloudOS (old kernel)
protocol: linux
path: boot():/vmlinuz-OLD
cmdline: root=UUID=ROOT_UUID rw
module_path: boot():/initramfs-OLD.img
instead of NEW and OLD put the kernel versions.
8.7 grub instead of limine
if you prefer grub, install it instead of limine (inside chroot, after the kernel and initramfs are installed):
cloudpkg sync
cloudpkg install sys-boot/grub
for uefi:
grub-install --target=x86_64-efi --efi-directory=/boot --boot-directory=/boot --removablefor bios:
grub-install --target=i386-pc --boot-directory=/boot /dev/sdathe config is written by hand to /boot/grub/grub.cfg:
set timeout=5
menuentry "CloudOS" {
search --no-floppy --fs-uuid --set=root ESP_UUID
linux /vmlinuz-6.18.10 root=UUID=ROOT_UUID rw
initrd /initramfs-6.18.10.img
}
blkid (the /boot partition and the root partition). with btrfs add the rootflags=subvol=@ parameter to the linux line. the install wizard on the site does all of this for you.9. finishing
enable the network and the log, set the root password:
cloudpkg install dhcpcd
cloudpkg install syslog-ng
rc-update add dhcpcd default
rc-update add syslog-ng default
passwd
leave chroot, unmount and reboot:
exit
umount -R /mnt/cloudos
reboot
9.1 checking services
before rebooting make sure the services are added:
rc-update show
the list should contain dhcpcd and the log at the level default.
9.2 first boot
after the reboot remove the usb stick and choose the disk in the boot menu if it was not chosen by itself. the prompt will appear login: on tty1. enter root and the password you set with the command passwd.
then set up the system, it is described in chapter 10.
cloudpkg sync updates the recipe tree, cloudpkg install name builds from source, cloudpkg doctor checks the setup.10. first boot
after installation the system has only a console and root. this chapter is about what is worth doing right away.
10.1 login
at the prompt login: , enter root and the password you set in chapter 9. if you did not set one, the password is empty, set it right away with the command passwd.
10.2 user and doas
working as root all the time is unsafe. create a regular user and allow the wheel group to use doas:
grep wheel /etc/group || groupadd wheel
useradd -m -G wheel -s /bin/bash name
passwd name
echo "permit :wheel" > /etc/doas.conf
chmod 0400 /etc/doas.conf
instead of name put your own. after that, commands as root are run like this:
doas cloudpkg install nano
if you do not want to type the password every time, replace the rule with permit nopass :wheel. this is more convenient, but safer with a password.
10.3 computer name
echo "cloudos" > /etc/hostname
echo 'hostname="cloudos"' > /etc/conf.d/hostname
rc-update add hostname boot
if the service hostname is already enabled, the last command will report that and change nothing. instead of cloudos you can write any name in latin letters.
10.4 time zone
ls /usr/share/zoneinfo
ln -sfv /usr/share/zoneinfo/Europe/Moscow /etc/localtime
instead of Europe/Moscow choose your zone from the list. check the result with the command date.
10.5 network
dhcpcd gets the address and dns automatically. check:
ip addr
ping -c1 github.com
if you need a permanent address, add to /etc/dhcpcd.conf (see the interface name in ip link):
interface eth0
static ip_address=192.168.1.50/24
static routers=192.168.1.1
static domain_name_servers=1.1.1.1 8.8.8.8
then restart the service: rc-service dhcpcd restart.
10.6 openrc services
| command | what it does |
|---|---|
rc-status | shows the running services |
rc-update show | shows the services and the runlevels they are enabled on |
rc-update add name default | enables the service at boot |
rc-update del name default | disables autostart |
rc-service name start | starts the service now |
rc-service name stop | stops it |
rc-service name restart | restarts it |
rc-service name status | shows the status |
levels: boot for what is needed early (for example the computer name), default for ordinary services.
10.7 swap
swap is not required, but it helps when building big packages with little ram. the easiest way is a file.
for ext4:
dd if=/dev/zero of=/swapfile bs=1M count=4096 status=progress
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
for btrfs (also works for ext4):
btrfs filesystem mkswapfile --size 4g /swapfile
swapon /swapfile
so that swap turns on by itself, add a line to /etc/fstab:
/swapfile none swap defaults 0 0
a swap partition is made like this: mkswap /dev/sda3, swapon /dev/sda3 and a fstab line with UUID=... instead of /swapfile.
11. packages and cloudpkg
all packages in cloudos are built from source. this is done by the manager cloudpkg. its recipes are taken from gentoo.
11.1 commands
| command | what it does |
|---|---|
cloudpkg sync | updates the recipe list |
cloudpkg install name | builds and installs a package together with its dependencies |
cloudpkg remove name | removes a package |
cloudpkg upgrade | updates installed packages to newer versions |
cloudpkg clean | cleans downloaded sources and temporary build files |
11.2 how the installation goes
- the package recipe and its dependency list are read
- the sources are downloaded through curl
- sha256 is checked
- the package is built with your flags from
/etc/cloudpkg/make.conf - the result is installed into the system
a build takes time and disk space. big packages such as compilers build for a long time, this is normal.
11.3 examples
cloudpkg sync
cloudpkg install limine
cloudpkg install dracut
cloudpkg install nano
11.4 if a package failed to build
- read the last lines with
error - if the error is about the c standard, set
CC="gcc -std=gnu17", see 6.4 - if the build fails with
killed, reduce-jinMAKEOPTS - try
cloudpkg syncand repeat, maybe the recipe is already fixed - write on the forum in the questions section, attaching the last 10-15 lines of output
12. maintenance
12.1 updating packages
cloudpkg sync
cloudpkg upgrade
cloudpkg clean
12.2 updating the kernel
a new version is installed next to the old one. do not delete the old kernel until you are sure the new one boots.
- download and unpack the new kernel into
/usr/src, as in chapter 7 - take the old config as a base and pull in the new options:
cd /usr/src/linux-NEW
cp /boot/config-OLD .config
make olddefconfig
- build and install:
make -j$(nproc)
make modules_install
cp arch/x86/boot/bzImage /boot/vmlinuz-NEW
cp .config /boot/config-NEW
dracut --kver NEW /boot/initramfs-NEW.img
- add a second entry to
/boot/limine.conf, as in 8.6, and reboot - if everything works, the old files can be deleted:
rm /boot/vmlinuz-OLD /boot/initramfs-OLD.img /boot/config-OLD
rm -r /lib/modules/OLD
instead of NEW and OLD put the versions, for example 6.18.10.
12.3 backup
a full copy of the system in one archive with the same keys as when unpacking stage 3. save it to another disk or usb stick:
tar cpf /mnt/usb/cloudos-backup.tar.xz --xattrs-include='*.*' --numeric-owner --one-file-system -I xz /
btrfs has snapshots, they are faster and take less space, see appendix b.
12.4 freeing space
df -h
cloudpkg clean
du -sh /usr/src/* /var/* 2>/dev/null
the old kernel folders in /usr/src can be deleted if you have their configs saved in /boot.
13. what next
cloudos is installed minimal. everything else you add as needed.
| what | how |
|---|---|
| sound | you install pipewire yourself through cloudpkg install, if there is a recipe for it |
| graphics and desktop | none by default. install the components by hand from recipes, you will need a video card driver in the kernel and firmware files |
| ssh server | none by default. install the package and enable the service through rc-update add |
| firewall | none by default |
| other editors and utilities | through cloudpkg install |
| man pages | are not installed. use command --help and this handbook |
13.1 other locales
in chapter 6.1 one locale was created. to add another, for example russian:
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
echo "LANG=ru_RU.UTF-8" > /etc/locale.conf
in the kernel console cyrillic may display incorrectly without a separate font, so for the console it is safer to keep en_US.UTF-8.
13.2 help and feedback
- questions and discussion on the forum
- new versions and images on the releases page
- bugs and suggestions in issues on github
14. errors and fixes
click the error text to see the cause and what to do. if your error is not in the list, use search.
14.1 live iso, network and time
ping: connect: network is unreachable or no reply
the interface did not get an address. check the cable, then:
ip link
dhcpcd eth0
take the interface name from ip link. if the interface is not in the list, the live iso has no driver for your network card.
ping by ip works, by name does not (temporary failure in name resolution)
dns is not set up. in the live iso it comes from dhcpcd. inside chroot check that this was done: cp --dereference /etc/resolv.conf /mnt/cloudos/etc/.
certificate verify failed or ssl certificate problem
almost always a wrong date. set it with 2.1 and repeat. if that does not help, download the file on another device and move it with a usb stick.
curl: (6) could not resolve host or (7) failed to connect
no network or the site is unavailable from your network. check ping against another site. for github and kernel.org see 2.4.
14.2 partitioning and filesystems
mount: unknown filesystem type or wrong fs type
the partition is not formatted or you specified the wrong partition. check lsblk -f: in the column FSTYPE there must be a filesystem. if empty, repeat the formatting from 3.2.
mount: special device does not exist
wrong partition name. nvme ones are called nvme0n1p1, not nvme0n11, see appendix a.
mkfs.fat: command not found or mkfs.btrfs: command not found
the live iso lacks the needed tool. dosfstools and btrfs-progs must be part of the image, check that you have an up-to-date iso.
cfdisk does not see the disk
the live iso has no driver for the disk controller. for a virtual machine choose a sata or nvme disk, not a non-standard controller.
14.3 downloading and unpacking
sha256sum: WARNING: 1 computed checksum did NOT match
the file was not downloaded fully or is corrupted. delete the archive and download again. make sure the .sha256 file and the archive are in the same folder and the names match.
tar: Unexpected EOF in archive or xz: file format not recognized
the archive is truncated. download again and compare the size with the one shown on the releases page.
tar: No space left on device
there was not enough space on the partition or the archive was in the live iso's ram. download straight into /mnt/cloudos, as in 4.3, and check the partition size with the command df -h /mnt/cloudos.
14.4 chroot
chroot: failed to run command '/bin/bash': No such file or directory
stage 3 is not unpacked or unpacked into another folder. run ls /mnt/cloudos/bin. if the folder is empty, go back to 4.2.
mount: /mnt/cloudos/proc: mount point does not exist
the same thing, stage 3 is not unpacked, so the proc, sys, dev folders do not exist yet.
sites do not open inside chroot
copy the dns settings again: cp --dereference /etc/resolv.conf /mnt/cloudos/etc/ (run outside chroot).
umount: target is busy
some program is still using the files. close all terminals where you were in chroot and repeat umount -R /mnt/cloudos.
14.5 building packages
errors about bool, true, false, prototype
an old package does not build with the c23 standard enabled in gcc 15. add to make.conf CC="gcc -std=gnu17", see 6.4.
gcc: fatal error: Killed signal terminated program cc1
not enough ram. reduce -j in MAKEOPTS or enable swap, see 10.7.
sha256 does not match when downloading sources
the file at the source may have changed or was downloaded with an error. run cloudpkg sync and repeat the installation. if the error repeats, write about it on the forum.
No space left on device during the build
out of space. run cloudpkg clean and check df -h. for building packages it is better to have 20 gb or more.
14.6 kernel
make menuconfig: Unable to find the ncurses libraries
the system has no ncurses with headers. install the package through cloudpkg or use make config (slow) or move a ready .config.
dracut: Cannot find module directory /lib/modules/6.18.10
you did not run make modules_install or the version in the command does not match the one you built. run ls /lib/modules and use the version you have.
make: *** No rule to make target ...
you ran make not in the kernel source folder. go to /usr/src/linux-6.18.10 and repeat.
14.7 booting
after the reboot no bootable device or another system boots right away
check that the file /boot/EFI/BOOT/BOOTX64.EFIexists, that partition 1 has type efi system and that secure boot is off in the firmware. choose the disk in the boot menu manually (usually the key f12 or esc at power on).
check that the /boot partition is marked with the flag bootable and that the command limine bios-install was run for the right disk or partition. in the firmware settings enable legacy or csm mode.
limine shows the menu, but the kernel does not start (file not found)
the path in limine.conf does not match the file name. check ls /boot and fix path: and module_path:.
Kernel panic: VFS: Unable to mount root fs on unknown-block
the kernel did not find the root partition. the most common causes:
- wrong
ROOT_UUIDincmdline, compare withblkid - the kernel has no disk driver (
BLK_DEV_NVMEorSATA_AHCI) or filesystem (EXT4_FS,BTRFS_FS) - the
module_pathwith initramfs is not specified inlimine.conf
boot from the live iso, enter chroot (14.9), fix it and rebuild.
dracut: waits for the root device and drops to the dracut console
initramfs did not find the root. compare the uuid, and also check that the disk driver and the root filesystem are built into the kernel.
empty screen after choosing the limine entry
most likely the console is not output. enable in the kernel DRM_SIMPLEDRM, FRAMEBUFFER_CONSOLE, VT_CONSOLE, see 7.1. video card drivers without firmware files can give a black screen, then do not enable them.
Kernel panic: No init found
the root mounted, but there is no /sbin/initin it. check that stage 3 is fully unpacked and that the root partition is the right one.
14.8 after booting
login incorrect
wrong password or it was not set. boot from the live iso, enter chroot and set the password again with the command passwd.
no network after booting
check rc-status. if dhcpcd is not running, run rc-update add dhcpcd default and rc-service dhcpcd start. if the interface is not in ip link, the kernel has no driver for the card.
doas: Operation not permitted
the user is not in the wheel group or there is no file /etc/doas.conf. check with 10.2: id name must show the group wheel.
setlocale: LC_ALL: cannot change locale
the specified locale was not created. create it with the command localedef from 6.1 or change LANG to an existing one.
the service does not start: rc-service ... start
look at the output of the command and the log. the list of the service with an error is given by rc-status --crashed.
14.9 emergency system access
if the system does not boot, it can almost always be repaired from the live iso:
- boot from the live iso and check the network
- mount the partitions and enter chroot per 5.3
- fix the config, rebuild initramfs with the command
dracut --kver 6.18.10 /boot/initramfs-6.18.10.img --forceor fixlimine.conf - leave chroot, unmount and reboot
14.10 how to report an error
so that you get help quickly, attach:
- which chapter of the handbook you were doing and on which command it failed
- the lines with
erroror the last 10-15 lines of output - boot mode (uefi or bios), disk name (sda or nvme) and the root filesystem
- the output of
dmesg | tail -50, if the error is after booting
14.11 installer wizard and grub
no disk /dev/sda or no partitions (wizard script message)
the script could not find the disk or the partitions. check the disk name and that partitions have the right names (nvme adds the letter p: nvme0n1p1):
lsblk
partprobe /dev/sdaif the name differs, fix the disk field in the wizard and copy the script again.
the wizard script exits immediately and does not ask for yes
the script was not run from a terminal (through a pipe or with replaced input), so it cannot read your answer. run it directly:
bash /root/cloudos-s1.shlimine not found in the live system or grub not found in the live system
the live image does not include the chosen bootloader. pick the other one in the wizard, or install the bootloader from the handbook inside chroot (8.7 for grub). check what the live system has:
ls /usr/share/limine
command -v grub-installcurl: (22) The requested URL returned error: 404 when downloading stage 3
the file name or the release tag has changed. open the releases page, copy the exact file name and put it at the top of the script (the STAGE variable), then run the script again.
curl: (28) connection timed out when downloading the kernel in step 2
the mirror is unreachable. the script tries three addresses in turn. if none answers, download linux-6.18.10.tar.xz in a browser (with a vpn), put it into /mnt/cloudos/usr/src and run step 2 again: the download will be skipped.
menuconfig: Your display is too small to run Menuconfig
the terminal is too small. you need at least 80 columns and 19 rows. enlarge the window or reduce the font and run step 2 again.
grub-install: error: cannot find EFI directory
the /boot partition is not mounted, or the live image was booted in bios mode instead of uefi. check:
ls /sys/firmware/efi
mountpoint /mnt/cloudos/bootif the efi folder is missing, reboot in uefi mode (in the firmware settings); if /boot is not mounted, mount the partition and retry.
grub-install: warning: this GPT partition label contains no BIOS Boot Partition
you are installing grub in bios mode on a gpt disk. for bios cloudos uses a dos (mbr) table. recreate the partitions in bios mode (the wizard does this itself) or add a small bios boot partition (type ef02) and repeat the grub install.
grub: error: no such partition and the grub rescue prompt
grub could not find its files. in the rescue prompt type (use your own partition):
ls
set root=(hd0,msdos1)
set prefix=(hd0,msdos1)/grub
insmod normal
normalafter booting, log in and reinstall grub as in 8.7. for uefi use gpt1 instead of msdos1.
grub> prompt instead of the menu (no grub.cfg)
grub is installed but there is no config. boot the system by hand (use your own version and partition), then create /boot/grub/grub.cfg as in 8.7:
ls
set root=(hd0,msdos1)
linux /vmlinuz-6.18.10 root=/dev/sda2 rw
initrd /initramfs-6.18.10.img
bootgrub: error: file '/vmlinuz-6.18.10' not found
the version in grub.cfg does not match the kernel file. look at what is in /boot and fix the names in the config:
ls /boot
nano /boot/grub/grub.cfgefibootmgr: EFI variables are not supported on this system
the system was booted in bios mode. reboot in uefi mode. the bootloader itself installs without efibootmgr: an nvram entry is optional.
14.12 cloudpkg and portage
cloudpkg: no mirror answered
the tree snapshot was not downloaded. turn on a vpn and repeat cloudpkg sync, or download portage-latest.tar.xz (the snapshots folder on any gentoo mirror) in a browser, put it into /var/cache/distfiles and run sync again.
!!! Invalid Repository Location (not a dir): '/var/db/repos/gentoo'
the recipe tree has not been downloaded yet. run:
cloudpkg sync
cloudpkg doctorcloudpkg doctor shows НЕТ for the profile (make.profile)
the profile link is created after the first sync. create it by hand:
ln -sfn /var/db/repos/gentoo/profiles/default/linux/amd64/23.0 /etc/portage/make.profileemerge: command not found or ModuleNotFoundError: No module named 'portage'
portage is not installed or is broken. run the auto-setup script from the repository or reinstall it:
python3 -m pip install --force-reinstall --index-url https://mirrors.aliyun.com/pypi/simple/ portagecloudpkg: root rights required
install, remove, upgrade and clean work only as root. log in as root or use doas:
doas cloudpkg install nameemerge: there are no ebuilds to satisfy ...
there is no such package or the name is incomplete. find the exact name with the category:
cloudpkg search name
cloudpkg install category/nameif the tree is old, run cloudpkg sync first.
The following keyword changes are necessary to proceed (masked by ~amd64)
the needed version exists only in the testing branch. if you accept a less tested version, add the -t flag:
cloudpkg install -t category/nameemerge wants to rebuild glibc, gcc or bash (blocked packages, slot conflict)
portage does not know these packages are already built by hand. declare the package in /etc/portage/profile/package.provided (one line per package, with a version):
echo "sys-libs/glibc-2.42" >> /etc/portage/profile/package.provided
cloudpkg install -p namethe version must not be lower than the one the package requires.
Fetch failed for ... or Digest verification failed
the sources were not downloaded or were downloaded corrupted. clean the cache and retry. if a mirror does not answer, change the order of addresses in GENTOO_MIRRORS in /etc/portage/make.conf:
cloudpkg clean
cloudpkg install name* ERROR: ... failed (compile phase)
the package failed to build. the path to the build log is in the message (the build.log file). show the last lines:
tail -n 30 /var/tmp/portage/category/name/temp/build.loga common cause is the new gcc 15. make.conf already has CC="gcc -std=gnu17", check that the line is in place. attach the last 15 lines when you report an error.
15. cheat sheet
15.1 disks
| command | what it does |
|---|---|
lsblk -f | disks, partitions, filesystems, uuid |
blkid | uuid and filesystem type of partitions |
fdisk -l | partition tables in detail |
cfdisk /dev/sda | disk partitioning menu |
mount /dev/sda2 /mnt/cloudos | mount a partition |
umount -R /mnt/cloudos | unmount everything recursively |
findmnt | what is mounted where |
df -h | free space on partitions |
du -sh folder | how much a folder takes |
15.2 network
| command | what it does |
|---|---|
ip link | list of network interfaces |
ip addr | interface addresses |
ip route | routes and gateway |
dhcpcd eth0 | get an address on an interface |
ping -c1 github.com | check connectivity and names |
curl -LO link | download a file |
15.3 system
| command | what it does |
|---|---|
dmesg | tail -50 | latest kernel messages |
free -h | memory and swap |
top | processes and load |
uname -r | version of the running kernel |
lsmod | loaded kernel modules |
lspci | pci devices, shows the network and video card |
date | date and time |
reboot, poweroff | reboot and shutdown |
15.4 files and archives
| command | what it does |
|---|---|
tar xf archive.tar.xz | unpack an archive |
tar cf archive.tar.xz folder -I xz | create an xz archive |
cp -a what where | copy preserving permissions |
nano file | open the editor. save ctrl + o, exit ctrl + x |
grep text file | find a line in a file |
15.5 btrfs
| command | what it does |
|---|---|
btrfs filesystem df / | space used by data types |
btrfs subvolume list / | list of subvolumes |
btrfs subvolume snapshot -r source target | read-only snapshot of a subvolume |
btrfs scrub start / | data integrity check |
15.6 cloudpkg
| command | what it does |
|---|---|
cloudpkg sync | update recipes |
cloudpkg install name | install a package |
cloudpkg remove name | remove a package |
cloudpkg upgrade | update packages |
cloudpkg clean | clean the build cache |
openrc services are collected in the table 10.6.
16. questions and answers
why is cloudos built by hand, is there an installer
the idea is to understand every step and control the whole system. the installation goes like in gentoo: partitioning, stage 3, chroot, kernel, bootloader.
if you do not want to type commands one by one, use the install wizard on the site: it builds a script for your disk. understanding the steps is still useful.
which bootloader is used, is there grub
limine and grub are supported. limine is installed by default: it is fast and configured with one file. grub is described in 8.7, and the install wizard can install either of the two.
why openrc and not systemd
openrc is simple, without extra dependencies and fits a minimal system. init in cloudos is openrc-init.
can it be installed on arm
no, only x86_64 is supported, in uefi and legacy bios modes.
what is the root password after unpacking stage 3
the password is empty. set it in chapter 9 with the command passwd.
why are there no man pages
they were removed to make the system smaller. help is the handbook and the key --help of the commands.
can sudo be used
doas is used instead, it is simpler and smaller. the rules are in /etc/doas.conf, see 10.2.
how to install a graphical environment
there is none by default. it has to be built by hand through cloudpkg, and the kernel will need a video card driver with firmware files, see chapter 13.
what license
the project's own parts are under mit, you must keep the author's name and the project name. package recipes are based on gentoo and stay under gpl-2.
where to get the live iso
the image is prepared after the stage 3 release and will appear on the releases page. until then you can use any live linux with the set of utilities from 1.1.
what does beta in the release name mean
the system works, but the project is young: cloudpkg and the live iso are still in development. more on the news page.
appendix a. disk names
the partition name depends on the disk type. for nvme the letter is added before the partition number: p.
| disk type | disk | first partition | second partition |
|---|---|---|---|
| sata, usb | /dev/sda | /dev/sda1 | /dev/sda2 |
| nvme | /dev/nvme0n1 | /dev/nvme0n1p1 | /dev/nvme0n1p2 |
| virtual (virtio) | /dev/vda | /dev/vda1 | /dev/vda2 |
if you install on nvme, replace /dev/sda1 with /dev/nvme0n1p1 and /dev/sda2 with /dev/nvme0n1p2 in all commands.
appendix b. btrfs with subvolumes
optional. subvolumes allow fast system snapshots and rollbacks. described for the layout from 3.4.
b.1 creating subvolumes
mkfs.btrfs /dev/sda2
mount /dev/sda2 /mnt/cloudos
btrfs subvolume create /mnt/cloudos/@
btrfs subvolume create /mnt/cloudos/@home
umount /mnt/cloudos
b.2 mounting
mount -o subvol=@ /dev/sda2 /mnt/cloudos
mkdir -p /mnt/cloudos/boot /mnt/cloudos/home
mount /dev/sda1 /mnt/cloudos/boot
mount -o subvol=@home /dev/sda2 /mnt/cloudos/home
b.3 fstab and bootloader
UUID=ROOT_UUID / btrfs subvol=@,noatime 0 0
UUID=ROOT_UUID /home btrfs subvol=@home,noatime 0 0
UUID=ESP_UUID /boot vfat defaults 0 2
in /boot/limine.conf in the line cmdline add the subvolume parameter:
cmdline: root=UUID=ROOT_UUID rootflags=subvol=@ rw
b.4 system snapshot
mkdir -p /mnt/top
mount -o subvolid=5 /dev/sda2 /mnt/top
btrfs subvolume snapshot -r /mnt/top/@ /mnt/top/@-snap-1
umount /mnt/top
the snapshot lies next to the subvolume @ and takes no space until the data changes.
appendix c. glossary
| word | what it means |
|---|---|
| stage 3 | a ready base system in one archive, without a kernel and bootloader |
| chroot | starting a shell with a different root directory. this is how you work in the new system while the live iso is loaded |
| uefi | modern firmware. boots from the esp partition |
| bios (legacy, csm) | old firmware, the bootloader is written to the start of the disk or partition |
| esp | efi system partition, a fat32 partition with the bootloader for uefi |
| initramfs | a small temporary system that boots before the main one and finds the root partition |
| uuid | a unique partition identifier, does not change when the disk name changes |
| limine | a bootloader that reads /boot/limine.conf |
| dracut | a program that builds initramfs |
| openrc | init and service management system |
| doas | running commands as root, a replacement for sudo |
| recipe | a package description for cloudpkg: where to get the sources and how to build |
| subvolume | a separate branch of the btrfs filesystem for which snapshots can be made |