summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKacper Fiedorowicz <kf@efab.pl>2026-01-03 18:44:51 +0100
committerKacper Fiedorowicz <kf@efab.pl>2026-01-03 18:44:51 +0100
commit6018e17637264a9561b37be699c3d53b6661de23 (patch)
tree8546c9fa94358e7d6daaad5f11ac53e61be97ad5
parentab21f339a33abb1144f3c0f5c4285324e7e88392 (diff)
Add docs and nohup/unlink utitiliesHEADmaster
-rw-r--r--README5
-rw-r--r--bin/Kbuild2
-rw-r--r--bin/Kconfig14
-rw-r--r--bin/nohup/Kbuild3
-rw-r--r--bin/nohup/nohup.c47
-rw-r--r--bin/playground/Kbuild6
-rw-r--r--bin/playground/main.c6
-rw-r--r--bin/unlink/Kbuild3
-rw-r--r--bin/unlink/unlink.c30
-rw-r--r--docs/README11
-rw-r--r--docs/boot.txt15
-rw-r--r--docs/fs.txt30
-rw-r--r--docs/initrd.txt10
-rw-r--r--include/aio.h11
-rw-r--r--include/alloca.h5
-rw-r--r--include/arpa/inet.h9
-rw-r--r--include/assert.h5
-rw-r--r--include/bits/in_addr.h5
-rw-r--r--include/complex.h6
-rw-r--r--include/devctl.h6
-rw-r--r--include/elf.h5
-rw-r--r--makefile22
-rw-r--r--scripts/makefile.build2
23 files changed, 182 insertions, 76 deletions
diff --git a/README b/README
new file mode 100644
index 00000000..93f7fa06
--- /dev/null
+++ b/README
@@ -0,0 +1,5 @@
+Openlinux
+=========
+
+The Openlinux is tiny userspace for Linux kernel.
+It provides built from scratch system libraries and utilities.
diff --git a/bin/Kbuild b/bin/Kbuild
index b06279b2..13856f53 100644
--- a/bin/Kbuild
+++ b/bin/Kbuild
@@ -4,8 +4,10 @@ obj-$(CONFIG_BIN_ECHO) += echo/
obj-$(CONFIG_BIN_FALSE) += false/
obj-$(CONFIG_BIN_FREE) += free/
obj-$(CONFIG_BIN_GZIP) += gzip/
+obj-$(CONFIG_BIN_NOHUP) += nohup/
obj-$(CONFIG_BIN_PWD) += pwd/
obj-$(CONFIG_BIN_SLEEP) += sleep/
obj-$(CONFIG_BIN_SYNC) += sync/
obj-$(CONFIG_BIN_TRUE) += true/
obj-$(CONFIG_BIN_YES) += yes/
+obj-$(CONFIG_BIN_UNLINK) += unlink/
diff --git a/bin/Kconfig b/bin/Kconfig
index 67e4e63d..325e6ab3 100644
--- a/bin/Kconfig
+++ b/bin/Kconfig
@@ -48,4 +48,18 @@ config BIN_TRUE
help
Build/Add the 'true' command which returns a zero exit status.
+config BIN_NOHUP
+ bool "nohup"
+ default y
+ depends on LIB_LIBC
+ help
+ Build/Add the 'nohup' command which returns a zero exit status.
+
+config BIN_UNLINK
+ bool "unlink"
+ default y
+ depends on LIB_LIBC
+ help
+ Build/Add the 'unlink' command which returns a zero exit status.
+
endmenu
diff --git a/bin/nohup/Kbuild b/bin/nohup/Kbuild
new file mode 100644
index 00000000..2214faf1
--- /dev/null
+++ b/bin/nohup/Kbuild
@@ -0,0 +1,3 @@
+bin-y := nohup
+obj-y += nohup.o
+libs-y += $(srctree)/lib/libc/libc.a
diff --git a/bin/nohup/nohup.c b/bin/nohup/nohup.c
new file mode 100644
index 00000000..8a6171eb
--- /dev/null
+++ b/bin/nohup/nohup.c
@@ -0,0 +1,47 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+ int fildes;
+
+ if (argc < 2) {
+ write(STDOUT_FILENO, "nohup utility [argument...]\n", 29);
+ return 1;
+ }
+
+ if (signal(SIGHUP, SIG_IGN) == SIG_ERR) {
+ perror("nohup: signal");
+ return 1;
+ }
+
+ if (isatty(STDOUT_FILENO)) {
+ fildes = open("nohup.out", O_WRONLY | O_APPEND | O_CREAT);
+ if (fildes < 0) {
+ perror("nohup: open");
+ return 1;
+ }
+
+ if (dup2(fildes, STDOUT_FILENO) < 0) {
+ perror("nohup: dup2");
+ return 1;
+ }
+
+ close(fildes);
+ }
+
+ if (isatty(STDERR_FILENO)) {
+ if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0) {
+ perror("nohup: dup2");
+ return 1;
+ }
+ }
+
+ execvp(argv[0], argv);
+ perror("nohup: execvp");
+ return 127 + (errno == ENOENT);
+}
diff --git a/bin/playground/Kbuild b/bin/playground/Kbuild
deleted file mode 100644
index d9c08784..00000000
--- a/bin/playground/Kbuild
+++ /dev/null
@@ -1,6 +0,0 @@
-bin-y := main
-obj-y := main.o
-
-cflags-y += -fblocks
-
-libs-y := $(srctree)/lib/libc/libc.a
diff --git a/bin/playground/main.c b/bin/playground/main.c
deleted file mode 100644
index a6dab69a..00000000
--- a/bin/playground/main.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* Place where code from libs can be tested */
-
-int main(void)
-{
- return 0;
-}
diff --git a/bin/unlink/Kbuild b/bin/unlink/Kbuild
new file mode 100644
index 00000000..91be1b03
--- /dev/null
+++ b/bin/unlink/Kbuild
@@ -0,0 +1,3 @@
+bin-y := unlink
+obj-y += unlink.o
+libs-y += $(srctree)/lib/libc/libc.a
diff --git a/bin/unlink/unlink.c b/bin/unlink/unlink.c
new file mode 100644
index 00000000..ae2a6da2
--- /dev/null
+++ b/bin/unlink/unlink.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+ char opt;
+
+ while ((opt = getopt(argc, argv, "")) != -1) {
+ switch (opt) {
+ default:
+ goto usage;
+ return 1;
+ }
+ }
+
+ if (argc != 2) {
+ goto usage;
+ return 1;
+ }
+
+ if (unlink(argv[1]) == -1) {
+ perror("unlink: ");
+ return 1;
+ }
+
+ return 0;
+usage:
+ write(STDERR_FILENO, "usage: unlink file\n", 10);
+ return 0;
+}
diff --git a/docs/README b/docs/README
new file mode 100644
index 00000000..caceec3f
--- /dev/null
+++ b/docs/README
@@ -0,0 +1,11 @@
+Documentation
+=============
+
+There are some tiny documents how openlinux is designed.
+Is not another copy of wikipedia, how things work, but
+collection of base things and useful sources.
+
+docs/
+ boot.txt - boot procedure design
+ fs.txt - filesystem layout
+ initrd.txt - initramfs layout
diff --git a/docs/boot.txt b/docs/boot.txt
new file mode 100644
index 00000000..eddb09b9
--- /dev/null
+++ b/docs/boot.txt
@@ -0,0 +1,15 @@
+BOOT
+====
+
+Openlinux for now supports only uefi based booting.
+Kernel bzImage must have efi stub (1) option enabled,
+and placed in correct path (2). The uefi starts image,
+kernel does it startup procedures, then mounts our initrd (3),
+and parses bootconfig.txt (3), next init (4) is called.
+Init program mounts kernel virtual filesystems and switches to real root partition, then
+runs real init system.
+
+(1) - https://www.kernel.org/doc/html/latest/admin-guide/efi-stub.html
+(2) - See docs/fs.txt
+(3) - See docs/initrd.txt
+(4) - https://www.kernel.org/doc/html/latest/admin-guide/bootconfig.html
diff --git a/docs/fs.txt b/docs/fs.txt
new file mode 100644
index 00000000..c6617df0
--- /dev/null
+++ b/docs/fs.txt
@@ -0,0 +1,30 @@
+FILESYSTEM
+==========
+
+Openlinux filesystem is designed to be as handy as possible.
+
+┌── bin/
+│ └── (System binaries)
+│
+├── efi/ (separate parition can be mounted at /boot)
+│   └── boot/
+│   ├── bootx64.efi (1)
+│   └── initrd (2)
+│
+├── lib/
+│ └── (System libraries)
+│
+├── usr/
+│ ├── include/
+│ │ └── (System headers)
+│ │
+│ ├── local/
+│   │ ├── bin/
+│   │ │ └── (User binaries)
+│   │ ├── lib/
+│   │ │ └── (User libraries)
+│ │ └── include/
+│   │ └── (User headers)
+
+(1) - https://www.kernel.org/doc/html/latest/admin-guide/efi-stub.html
+(2) - https://www.kernel.org/doc/html/latest/admin-guide/initrd.html
diff --git a/docs/initrd.txt b/docs/initrd.txt
new file mode 100644
index 00000000..ca0c646f
--- /dev/null
+++ b/docs/initrd.txt
@@ -0,0 +1,10 @@
+INITRD
+======
+
+Initrd contains two files:
+
+- bootconfig.txt (1)
+- init (2)
+
+(1) - https://docs.kernel.org/admin-guide/bootconfig.html
+(2) - See boot.txt
diff --git a/include/aio.h b/include/aio.h
index 0ac9c7d6..4518b23a 100644
--- a/include/aio.h
+++ b/include/aio.h
@@ -1,13 +1,10 @@
-#ifndef __AIO_H
-#define __AIO_H
+#pragma once
-#include <stddef.h>
-#include <time.h>
#define __BITS_SIGEVENT_H_
-#include <bits/sigevent.h>
+#include "bits/sigevent.h"
#define __BITS_TIMESPEC_H_
-#include <bits/timespec.h>
+#include "bits/timespec.h"
#define AIO_CANCELED 0
#define AIO_NOTCANCELED 1
@@ -42,5 +39,3 @@ ssize_t aio_return(struct aiocb *);
int aio_suspend(const struct aiocb *const[], int, const struct timespec *);
int aio_write(struct aiocb *);
int lio_listio(int, struct aiocb *restrict const[restrict], int, struct sigevent *restrict);
-
-#endif
diff --git a/include/alloca.h b/include/alloca.h
index b70f6572..a3522055 100644
--- a/include/alloca.h
+++ b/include/alloca.h
@@ -1,6 +1,3 @@
-#ifndef __ALLOCA_H
-#define __ALLOCA_H
+#pragma once
#define alloca(__size) __builtin_alloca(__size)
-
-#endif
diff --git a/include/arpa/inet.h b/include/arpa/inet.h
index 478fb1ac..44999b03 100644
--- a/include/arpa/inet.h
+++ b/include/arpa/inet.h
@@ -1,10 +1,7 @@
-#ifndef __ARPA_INET_H
-#define __ARPA_INET_H
+#pragma once
-#include <stdint.h>
#define __BITS_IN_ADDR_H_
-#include <bits/in_addr.h>
-#undef __BITS_IN_ADDR_H_
+#include "bits/in_addr.h"
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
@@ -23,5 +20,3 @@ in_addr_t inet_addr(const char *);
char *inet_ntoa(struct in_addr);
const char *inet_ntop(int, const void *restrict, char *restrict, socklen_t);
int inet_pton(int, const char *restrict, void *restrict);
-
-#endif
diff --git a/include/assert.h b/include/assert.h
index 49550e39..04ec025b 100644
--- a/include/assert.h
+++ b/include/assert.h
@@ -1,14 +1,11 @@
-#ifndef __ASSERT_H
-#define __ASSERT_H
+#pragma once
#ifdef NDEBUG
#define assert(ignore) ((void)0)
#else
#define assert(__expr) ((__expr) ? (void)0 : __assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, #__expr))
-#endif
_Noreturn void __assert(const char *_Nonnull __file, int __line, const char *_Nonnull __func,
const char *_Nonnull __expr);
-
#endif
diff --git a/include/bits/in_addr.h b/include/bits/in_addr.h
index 1d7ac0af..54aa6e3e 100644
--- a/include/bits/in_addr.h
+++ b/include/bits/in_addr.h
@@ -1,5 +1,4 @@
-#ifndef __BITS_IN_ADDR_H
-#define __BITS_IN_ADDR_H
+#pragma once
#ifndef __BITS_IN_ADDR_H_
#error "Internal header — include the public API header instead."
@@ -10,5 +9,3 @@ typedef __UINT32_TYPE__ in_addr_t;
struct in_addr {
in_addr_t s_addr;
};
-
-#endif
diff --git a/include/complex.h b/include/complex.h
index e8cec9cc..e1430f7e 100644
--- a/include/complex.h
+++ b/include/complex.h
@@ -1,7 +1,5 @@
-#ifndef __COMPLEX_H
-#define __COMPLEX_H
+#pragma once
-#include <complex.h>
#define complex _Complex
#define _Complex_I (__extension__(0.0f + 1.0fi))
#define imaginary _Imaginary
@@ -78,5 +76,3 @@ double complex ctanh(double complex);
float complex ctanhf(float complex);
long double complex ctanhl(long double complex);
long double complex ctanl(long double complex);
-
-#endif
diff --git a/include/devctl.h b/include/devctl.h
index 6948af13..573ec821 100644
--- a/include/devctl.h
+++ b/include/devctl.h
@@ -1,9 +1,5 @@
-#ifndef __DEVCTL_H
-#define __DEVCTL_H
+#pragma once
-#include <stddef.h>
typedef __SIZE_TYPE__ size_t;
int posix_devctl(int, int, void *restrict, size_t, int *restrict);
-
-#endif
diff --git a/include/elf.h b/include/elf.h
index ea2014a6..fdff052f 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -1,5 +1,4 @@
-#ifndef __ELF_H
-#define __ELF_H
+#pragma once
#include <stdint.h>
@@ -402,5 +401,3 @@ typedef struct {
uint64_t a_val;
} a_un;
} Elf64_auxv_t;
-
-#endif
diff --git a/makefile b/makefile
index 4da86ea9..84a2827d 100644
--- a/makefile
+++ b/makefile
@@ -163,7 +163,6 @@ clean:
PHONY += distclean
distclean: clean
$(Q)$(MAKE) -C scripts/kconfig clean
- $(Q)rm -f compile_commands.json
$(KCONFIG_CONFIG):
@echo >&2 '***'
@@ -179,42 +178,23 @@ help:
@echo "Available make targets:"
@echo " all - Build the project (default)"
@echo " clang-format - Format source files using clang-format"
- @echo " clang-tidy - Run clang-tidy on the source files"
@echo " clean - Clean build files"
@echo " distclean - Clean all generated files"
- @echo " include-what-you-use - Run include-what-you-use on the source files"
@echo " install - Install the built files"
@echo " menuconfig - Launch the menu-based configuration tool"
@echo "Flags:"
@echo " o=<dir>/ - Destination directory"
@echo " obj=<dir>/ - Build single target"
-compile_commands.json:
- $(Q)bear -- $(MAKE) -f scripts/makefile.build obj=$(obj) all
-
PHONY += menuconfig
menuconfig:
$(Q)$(MAKE) -C $(srctree)/scripts/kconfig menuconfig
-PHONY += include-what-you-use
-include-what-you-use: compile_commands.json
- $(Q)iwyu_tool.py -p. -j4 -- -Xiwyu --update_comments -Xiwyu --transitive_includes_only -Xiwyu --no_internal_mappings | \
- fix_includes.py --comments \
- --quoted_includes_first \
- --nosafe_headers \
- --update_comments \
- --reorder
-
-PHONY += clang-tidy
-clang-tidy: compile_commands.json
- $(Q)clang-tidy -header-filter=.* -p=. -fix -fix-errors $(shell find . -name '*.c' -o -name '*.h' | grep -v './scripts/\|dtoa\|linux\|arch\|bits\|libm') \
- --export-fixes=clang-tidy-fixes.yaml
-
PHONY += clang-format
clang-format:
$(Q)clang-format -i $(shell find . -name '*.c' -o -name '*.h' | grep -v './scripts/')
-%/include/config/auto.conf %/include/generated/autoconf.h: $(KCONFIG_CONFIG) compile_commands.json
+%/include/config/auto.conf %/include/generated/autoconf.h: $(KCONFIG_CONFIG)
$(Q)$(MAKE) -f scripts/kconfig/makefile syncconfig
.PHONY: $(PHONY)
diff --git a/scripts/makefile.build b/scripts/makefile.build
index e4926b3e..bba5da3c 100644
--- a/scripts/makefile.build
+++ b/scripts/makefile.build
@@ -27,7 +27,6 @@ ifneq ($(strip $(bin-y) $(bin-n)),)
bin = $(bin-y)$(bin-n)
endif
-
objects := $(filter %.o,$(obj-y))
subdirs := $(filter %/,$(obj-y)) $(filter %/,$(obj-m))
@@ -39,7 +38,6 @@ collect-obj-y = $(foreach e,$(shell echo 'all:; @echo $$(obj-y)' | \
$(MAKE) -f $(obj)$(1)Kbuild -f - --no-print-directory 2>/dev/null),\
$(if $(filter %/,$(e)),$(addprefix $(e),$(call collect-obj-y,$(1)$(e))),$(e)))
-
ifneq ($(strip $(lib-y) $(lib-m)),)
subdir-objects := $(foreach d,$(subdirs),$(addprefix $(d),$(call collect-obj-y,$(d))))
all-objects := $(objects) $(subdir-objects)