Fork me on GitHub
Fiwix symbol
Welcome to the Fiwix project
Your small UNIX-like kernel



Welcome to FiwixOS 3.3

FiwixOS 3.3 is a completely free, open source, UNIX-like hobby operating system based on the Fiwix kernel. This is a true self-hosting operating system, which means that all packages supplied (including the kernel) have been compiled natively and no other operating system has been used in the process.

All binaries are linked statically and are built to use pure 80386 code. This is intended to make sure that FiwixOS 3.3 will run in very old hardware.

Hardware Requirements

FiwixOS 3.3 runs only in the 32-bit i386 architecture with the following minimal requirements:
  • Standard IBM PC-AT architecture.
  • CPU: i386 (with floating-point processor).
  • RAM: 4MiB (recommended 128MiB).
  • ATA Hard disk: 1GiB (minimal install requires only 200MiB).
  • ATAPI CD-ROM drive.

New in FiwixOS 3.3

This section provides an overview of the major highlights in this release.

  • Fiwix kernel version 1.5.0 (see detailed changes below).
  • FiwixOS has now its own repository which includes the scripts to generate the installation media.
  • Added DMA support and 32bit I/O data transfers in the ATA driver.
  • Overall improvements in the disk access (specially under QEMU).
  • Improvements and bug fixes in the buffer cache and memory management.
  • Most kernel structures are now dynamically allocated which reduces the kernel memory footprint.
  • Added the file /proc/buddyinfo to keep track the new kernel memory allocator.
  • New kernel process called kbdflushd that flushes dirty buffers periodically.
  • Added support for the Bochs Graphics Adapter with the new kernel parameter bga=.
  • Added support for multiple RAMdisk drives.
  • Added kexec implementation.
  • Added microsecond resolution to sys_gettimeofday.
  • Added the magic SysRq key Alt+SysRq+m to show current memory information.
  • Added the /proc/<PID>/fd subdirectory containing symbolic links named by its file descriptor.
  • Added support for 64bit offsets which helps to have filesystems bigger than 4GiB.
  • Added support for the virtual memory split 2GiB(user)/2GiB(kernel).
  • Added support for large initrd images.
  • Added the following new system calls:
    • sys_lchown.
      • The new sys_lchown replaced the syscall #16 sys_chown which in turn was moved to #182. This was necessary because the commands chown and chgrp won't work correctly on systems without sys_lchown. This might break the compatibility with Linux 2.0 ABI.
    • sys_readv.
    • sys_writev.
    • sys_mmap2.
      • Not supported by Newlib C library yet.
  • The kernel now mounts the root filesystem in read-only mode by default.
  • The Minix filesystem is now optional when building the kernel.
  • The installation process includes a minimal install for very reduced disk sizes (~200MiB).
  • FiwixOS can be installed on a specific partition.
  • GRUB installation is now optional.
  • Several segmentation faults specially during package building will no longer appear as a result of adding the Bash configuration option --without-bash-malloc. This turns off the use of Bash's memory allocation (malloc) function which is known to cause segmentation faults.
  • Massive kernel bug fixing.
  • Improvements and bug fixes in the system environment.

My very special thanks to Richard R. Masters for his invaluable contribution to the kernel.

Installation-Related Notes

This section outlines those issues that are related to the installation procedure.

  • The floppy disk cannot start the installation procedure; only the CD-ROM is able to. Still, if you have an old PC that is unable to boot from CD-ROM, you can boot from the floppy disk and use the CD-ROM as the root filesystem to proceed with the installation. To do so, you need to modify the kernel command-line in the GRUB menu of the floppy disk by changing (root=/dev/fd0) by the CD-ROM device (e.g: root=/dev/hdc or wherever the CD-ROM drive resides), and also appending the kernel parameters rootfstype=iso9660 ramdisksize=4096.

Package Changes

This is a list of packages that have been upgraded since the previous release:

  • at-3.1.23
  • binutils-2.25.1
  • byacc-20230521
  • coreutils-9.1
  • cpio-2.14
  • dash-0.5.12
  • dialog-1.3-20230209
  • diffstat-1.65
  • diffutils-3.6
  • dos2unix-7.5.0
  • e2fsprogs-1.29
  • ed-1.19
  • expat-2.5.0
  • global-6.6.10
  • gmp-6.2.1
  • grep-3.8
  • indent-2.2.13
  • lcms2-2.15.1
  • less-633
  • libarchive-3.6.2
  • libffi-3.4.4
  • libxcrypt-4.4.33
  • libxslt-v1.1.35
  • logrotate-3.21.0
  • lua-5.4.6
  • mpc-1.1.0
  • mpfr-3.1.6
  • nano-4.9.3
  • nasm-2.16.01
  • newt-r0-52-23
  • opkg-0.6.2
  • popt-1.19
  • slang-2.3.3
  • tree-2.1.1
  • units-2.22
  • vttest-20230201
  • zlib-1.2.13

This is a list of packages new in this version:

  • tmpwatch-2.11

Kernel changes

The following is a complete list of changes.

1.5.0 - 15-Nov-2023
- Added a kernel memory allocator that uses the buddy algorithm to manage
  requests smaller than PAGE_SIZE (4KiB).
- Added the new file /proc/buddyinfo to view buddy algorithm statistics.
- Added the new configuration option FREE_PAGES_RATIO (with a default value of
  5), as the minimum percentage of free memory pages before calling the swapper
  to reclaim memory from the buffer cache.
- Added the buffer-dirty-flush kernel daemon kbdflushd. This also includes the
  new configuration option BUFFER_DIRTY_RATIO to limit the percentage of dirty
- Added the new file /proc/sys/vm/dirty_background_ratio to show the current
  value of the option BUFFER_DIRTY_RATIO.
- Added support for the Bochs Graphics Adapter with the configuration option
  CONFIG_BGA, and introducing the new kernel parameter bga= to set the screen
  resolution (width x height x bpp). Refer to docs/kernel-parameters.txt to
  know all the screen resolutions supported.
- Added 32bit I/O transfers support to the ATA/ATAPI driver.
- Added DMA (Multi-word) transfers support to the ATA disk driver.
- Added overall improvements in the ATA disk driver.
- Added a check in psig() to terminate the process if it doesn't have the stack
  region in its vma table.
- Added PCI BARs handling in the serial driver.
- Added the files buffer_max and buffer_nr in /proc/sys/kernel/.
- Added more checks on data received during ATA drive identify to make sure it
  makes sense.
- Added the magic SysRq key 'm' to show current memory information.
- Added the Multiboot magic value as a new parameter in get_last_boot_addr() to
  avoid a kernel panic when it is booted without the Multiboot structure.
- Added a check if flag MULTIBOOT_INFO_ELF_SHDR is set before reading the ELF
  section header table to avoid possible kernel panics.
- Added support in parse_cmdline() to recognize values enclosed in double
- Added support for multiple RAMdisk drives.
- Added kexec implementation (see docs/kexec.txt) which introduces the new
  configuration option CONFIG_KEXEC (disabled by default).
- Added microsecond resolution to sys_gettimeofday().
- Added the /proc/<PID>/fd/ subdirectory containing symbolic links named by its
  file descriptor.
- Added support for 64bit offsets and introduced the new option CONFIG_OFFSET64
  (enabled by default).
- Added the linkage of libgcc into the kernel in order to have functions like
  __divdi3() and friends, necessary when doing certain arithmetic operations
  with 64bit offsets on an i386 architecture.
- Added support for the O_DIRECTORY flag to sys_open(). [#32]
- Added support for the virtual memory split 2GiB(user)/2GiB(kernel), by
  introducing the new option CONFIG_VM_SPLIT22 (disabled by default). [#34]
- Added support for large initrd images (see docs/initrd.txt). [#34]
- Added the ability to have different blksize values for each device minor.
- Added the new system call sys_lchown by renaming the old sys_chown (number 16)
  to sys_lchown, and creating the new sys_chown (number 182) which will follow
  (dereference) symbolic links. This might break the compatibility with Linux
  2.0 ABI.
- Added support for F_DUPFD_CLOEXEC in sys/fcntl.h. [#40]
- Added support for sys_readv() and sys_writev() system calls. [#42]
- Added support for sys_mmap2() system call. [#47]
- Added the length modifier 'l' for long long int arguments in printk().
- Changed the mode how the kernel mounts the root filesystem. From now on, it
  will be mounted in read/write mode by default. This introduces the new kernel
  parameter ro to force to mount it in read-only mode.
- Changed the vma table from static to dynamically allocated array and removed
  the option VMA_REGIONS.
- Changed lots of fixed-size arrays to dynamically allocated arrays.
- Changed malloc_name() and free_name() to use the new memory allocator.
- Changed do_namei() to use the new memory allocator.
- Changed the generic llseek() method to support 64bit offsets.
- Changed the location of the kernel stack address to be right after the BSS
  section. [#34]
- Rewritten reclaim_buffers() to be more efficient and also to free up unused
  buffers and shrink the buffer table.
- Modified the Makefile to disable compiling with PIE option enabled by some
  builds of GCC. [#6]
- Reverted 40bf18b because some signals weren't caugth and created malfunction
  in cron jobs.
- Reverted 082b316 as it created a kernel panic when using IPC shared memory.
- Reverted ad3fc56 so malloc_name() and free_name() will always request
  PAGE_SIZE bytes. This is more efficient as it helped to remove the call to
  strlen() and even can return now a proper ENAMETOOLONG error.
- Disabled interrupts in runnable() and not_runnable() to avoid race conditions.
- Removed the option RAMDISK_MAXSIZE from the RAMdisk drives.
- Bar addresses of PCI devices are now discovered by the driver.
- Reorganized _init() functions in start_kernel().
- Disk drives now show the ATA major version number.
- Reorganized the steps to do on a page fault in kernel mode.
- The kernel parameter ramdisksize= no longer controls the size of the initrd
  image. [#34]
- The build of the Minix filesystem depends on the new option CONFIG_FS_MINIX
  (disabled by default).
- Fixed a bug in syscalls/wait4.c introduced in 9cfe372 that created malfunction
  in control jobs.
- Fixed to call sleep_init(), buffer_init(), sched_init() and inode_init()
  before initializing devices.
- Fixed the offset value in elf_load_interpreter() and elf_load().
- Fixed in pci_add_device() to use pci_read_short() instead of pci_read_char()
  for Command and Status registers.
- Fixed in do_execve() to reuse tmp_name allocated in sys_execve().
- Fixed a number of common variable definitions that prevented from build Fiwix
  with the newest GCC cross-compiler. [#10]
- Fixed in fs/namei.c to return ENOENT for missing directory. [#12]
- Fixed a bug in ext2_bmap() that prevented large files from persist on an ext2
  filesystem. [#14]
- Fixed a bug in v2_minix_bmap() that prevented large files from persist on a
  minix v2 filesystem. [#14]
- Fixed do_page_fault() to handle better a faulty address outside the user
  address space in kernel mode.
- Fixed the I/O address size in the ISA serial driver.
- Fixed a missing iput() in ext2_followlink() when there are too many nested
  symbolic links.
- Fixed a missing iput() in minix_followlink() when there are too many nested
  symbolic links.
- Fixed the hexadecimal values of /dev/tty10, /dev/tty11 and /dev/tty12 in
- Fixed some possible race conditions in buffer cache.
- Fixed a bug in mmap that prevented overlapped VMA regions from merging
  correctly. [#16]
- Fixed to terminate properly a read or write request on hdd timeout.
- Fixed a race condition in sys_nanosleep() when setting the processs sleeping
- Fixed merge_vma_regions() to free memory pages in overlapped segments. [#16]
- Fixed memory mapped files not written to disk correctly. [#18]
- Fixed sys_execve() to make sure arguments and environment do not exceed the
  maximum length. [#20]
- Fixed sys_mount() to use malloc_name() and free_name() to validate the
  argument fstype.
- Fixed do_page_fault() to handle a page fault when trying to access a
  non-existent user stack address in kernel mode when
  CONFIG_LAZY_USER_ADDR_CHECK is enabled. [#22]
- Fixed verify_address() to accept a possible non-existent user stack address
  when CONFIG_LAZY_USER_ADDR_CHECK is disabled, since do_page_fault() will do
  the rest of the job. [#22]
- Fixed the logic in parse_arg() to support kernel parameters without arguments.
- Fixed a long standing bug where after removing an inode there was not a call
  to invalidate all its pages from the cache. [#24]
- Fixed a missing initialization in the PCI structure during scan_bus(). [#25]
- Fixed bread() to check if the bytes read matches with what was requested.
- Fixed premature output of information from the serial driver when acting as
  the remote console.
- Fixed frame buffer memory spaces to be marked as reserved if they conflict
  with available memory.
- Fixed sys_select() to return in the timeout argument the amount of time not
  slept. This is Linux specific but POSIX permits this behavior.
- Fixed Magic SysRq key 't' to also list zombie processes.
- Fixed Magic SysRq keys to work even when the tty has not been opened yet.
- Fixed get_free_page() to reduce the excessive number of iterations with
  reclaim_buffers() when running out of memory pages.
- Fixed the mechanism to sleep all processes in stop_kernel().
- Fixed the sleep address in page_lock() to match with page_unlock().
- Fixed a kernel panic if irq_keyboard() receives an unrecognized function key.
- Fixed to correctly disable the RAMdisk device if there is not enough physical
- Fixed an inode-related race condition in iget() and iput().
- Fixed to not use the buffer after failed to be synced in sync_one_buffer().
- Fixed in ext2_symlink(), ext2_mkdir(), ext2_mknod() and ext2_create() to make
  sure the inode doesn't exist.
- Fixed in minix_symlink(), minix_mkdir(), minix_mknod() and minix_create() to
  make sure the inode doesn't exist.
- Fixed a deadlock between getblk() and kbdflushd(). [#27]
- Fixed a missing lock that led to a possible memory page corruption bug in
  bread_page(). [#27]
- Fixed atapi_cd_init() to setup the correct block size in the device structure.
- Fixed sys_ftruncate() to return EINVAL if its method does not exist.
- Fixed sync_superblocks() to sync all superblocks if argument is zero.
- Fixed the size on every symlink in procfs to 64 bytes.
- Fixed iget() to avoid locking when read_inode() returns an error.
- Fixed a missing call to sync_buffers() in close() methods of RAMdisk drive and
  floppy drive.
- Fixed serial_set_termios() to avoid a division by zero.
- Fixed script_load() with || instead of && that led to incorrectly recognize as
  script when there is an incomplete shebang.
- Fixed a linked list corruption when messages are retrieved not sequentially in
- Fixed ata_hd_init() to not fail build if CONFIG_PCI is #undef.
- Fixed padding in fbcon_insert_char() to use character 0x20 instead of 0x00.
- Fixed vgacon_scroll_screen() to use double-buffering.
- Small fixes and cosmetic changes.

Known Issues

This is a list of known issues pending to be resolved:

  • Sometimes the system looks unresponsive specially when dealing with multiple processes. In the majority of cases the system can be resumed by simply log into another console or terminal. It seems that there is a problem waking up processes at some point. In other cases, less frequent, the system is not so easy to recover unless you hit CTRL-ALT-DEL which will cause a reboot. Not sure what is the cause of this behavior, it could be a race condition in the ATA interrupt/sleep mechanism. Finally, there are very remote serious cases where system totally freezes.
  • Regarding the filesystem, file corruption cases are really low but not 100% free. I recommend to make periodic filesystem backups to make sure you can recover from a serious situation.
  • Filesystems with 4KiB blocksize are poorly tested so they will be more buggy, be careful.

Definitely the kernel needs more eye balls to help to catch all these bugs.

First   Previous   Next   Last