summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKacper <kacper@mail.openlinux.dev>2025-12-16 00:36:30 +0100
committerKacper <kacper@mail.openlinux.dev>2025-12-16 00:36:30 +0100
commit91ecd00cc83cf701fe7f73b1aa244c27174e8386 (patch)
treec38ffefaa73e671fd917ca0b94b8adec53456a06
parent01cf24ec66c663e3f40be1d5c703aa9666effc85 (diff)
Add init prog, chroot syscall and fix menuconfig build
-rw-r--r--.gitignore9
-rw-r--r--Kbuild2
-rw-r--r--bin/clear/Kbuild1
-rw-r--r--bin/clear/clear.c2
-rw-r--r--bin/echo/Kbuild1
-rw-r--r--bin/false/Kbuild3
-rw-r--r--bin/yes/Kbuild2
-rw-r--r--boot/Kbuild1
-rw-r--r--boot/init/Kbuild3
-rwxr-xr-xboot/init/initbin0 -> 145432 bytes
-rw-r--r--boot/init/init.c126
-rw-r--r--include/unistd.h1
-rw-r--r--lib/libc/Kbuild1
-rw-r--r--lib/libc/unistd/Kbuild5
-rw-r--r--lib/libc/unistd/chroot.c7
-rw-r--r--lib/libm/Kbuild1
-rw-r--r--makefile43
-rw-r--r--scripts/kconfig/makefile15
-rwxr-xr-xscripts/kconfig/mconfbin0 -> 224184 bytes
-rw-r--r--scripts/makefile.build31
20 files changed, 230 insertions, 24 deletions
diff --git a/.gitignore b/.gitignore
index e950c442..17ea6903 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,14 @@
+bin/*/*
+!bin/*/*.*
+!bin/*/Kbuild
+
+*.lex.c
+*.tab.c
+*.tab.h
+
*.o
*.a
+*.d
.cache
diff --git a/Kbuild b/Kbuild
index fb663bbd..d37581e8 100644
--- a/Kbuild
+++ b/Kbuild
@@ -1,4 +1,6 @@
obj-y += lib/
obj-y += bin/
+obj-y += boot/
bin/: lib/
+boot/: lib/
diff --git a/bin/clear/Kbuild b/bin/clear/Kbuild
index 845df317..3e56e161 100644
--- a/bin/clear/Kbuild
+++ b/bin/clear/Kbuild
@@ -1,3 +1,4 @@
bin-y := clear
obj-y += clear.o
libs-y += $(srctree)/lib/libc/libc.a
+install-y := bin/clear
diff --git a/bin/clear/clear.c b/bin/clear/clear.c
index c5a7a7c0..f689485c 100644
--- a/bin/clear/clear.c
+++ b/bin/clear/clear.c
@@ -1,6 +1,6 @@
#include <unistd.h>
-void _start(void)
+int main(void)
{
write(STDOUT_FILENO, "\033[H\033[2J", 7);
_exit(0);
diff --git a/bin/echo/Kbuild b/bin/echo/Kbuild
index 00d6ecdd..0f816ddf 100644
--- a/bin/echo/Kbuild
+++ b/bin/echo/Kbuild
@@ -1,3 +1,4 @@
bin-y := echo
obj-y += echo.o
libs-y += $(srctree)/lib/libc/libc.a
+install-y := bin/echo
diff --git a/bin/false/Kbuild b/bin/false/Kbuild
index 3b6f0687..2f8e102d 100644
--- a/bin/false/Kbuild
+++ b/bin/false/Kbuild
@@ -1,3 +1,4 @@
bin-y := false
-
obj-y += arch/
+
+install-y := bin/false
diff --git a/bin/yes/Kbuild b/bin/yes/Kbuild
index be596906..711029bc 100644
--- a/bin/yes/Kbuild
+++ b/bin/yes/Kbuild
@@ -1,3 +1,3 @@
bin-y := yes
obj-y := yes.o
-libs := $(srctree)/lib/libc/libc.a
+libs-y := $(srctree)/lib/libc/libc.a
diff --git a/boot/Kbuild b/boot/Kbuild
new file mode 100644
index 00000000..01daa04b
--- /dev/null
+++ b/boot/Kbuild
@@ -0,0 +1 @@
+obj-y += init/
diff --git a/boot/init/Kbuild b/boot/init/Kbuild
new file mode 100644
index 00000000..461a0101
--- /dev/null
+++ b/boot/init/Kbuild
@@ -0,0 +1,3 @@
+bin-y := init
+obj-y := init.o
+libs-y := $(srctree)/lib/libc/libc.a
diff --git a/boot/init/init b/boot/init/init
new file mode 100755
index 00000000..87e091d3
--- /dev/null
+++ b/boot/init/init
Binary files differ
diff --git a/boot/init/init.c b/boot/init/init.c
new file mode 100644
index 00000000..4e643a34
--- /dev/null
+++ b/boot/init/init.c
@@ -0,0 +1,126 @@
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/fs.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+struct rootfs {
+ char *dev;
+ int flags;
+};
+
+int get_rootfs(struct rootfs *root)
+{
+ int fd;
+ ssize_t len;
+ char buf[1024];
+
+ root->dev = NULL;
+ root->flags = 0;
+
+ fd = open("/proc/cmdline", O_RDONLY);
+ if (fd < 0) {
+ return -1;
+ }
+
+ len = read(fd, buf, sizeof(buf) - 1);
+ if (len < 0) {
+ close(fd);
+ return -1;
+ }
+ buf[len] = '\0';
+ close(fd);
+
+ // Read cmdline by words
+ // not using strtok
+ char *p = buf;
+ while (*p) {
+ while (*p == ' ')
+ p++;
+
+ if (*p == '\0')
+ break;
+
+ char *start = p;
+ while (*p && *p != ' ')
+ p++;
+ size_t word_len = p - start;
+
+ if (strncmp(start, "root=", 5) == 0) {
+ size_t dev_len = word_len - 5;
+ root->dev = strndup(start + 5, dev_len);
+ } else if (strncmp(start, "ro", 2) == 0) {
+ root->flags |= MS_RDONLY;
+ } else if (strncmp(start, "rw", 2) == 0) {
+ root->flags &= ~MS_RDONLY;
+ }
+ }
+
+ return 0;
+}
+
+int main(void)
+{
+ struct rootfs root;
+ char *const argv[] = { "/bin/init", NULL };
+
+ if (mkdir("/dev", 0755) < 0 && errno != EEXIST) {
+ perror("mkdir /dev");
+ return -1;
+ }
+
+ if (mount("devtmpfs", "/dev", "devtmpfs", 0, NULL) < 0) {
+ perror("mount devtmpfs");
+ return -1;
+ }
+
+ if (mkdir("/proc", 0755) < 0 && errno != EEXIST) {
+ perror("mkdir /proc");
+ return -1;
+ }
+
+ if (mount("proc", "/proc", "proc", 0, NULL) < 0) {
+ perror("mount proc");
+ return -1;
+ }
+
+ /* Get root filesystem info from kernel cmdline */
+ if (get_rootfs(&root) < 0) {
+ err(1, "init: get rootfs info");
+ }
+
+ if (mount(root.dev, "/root", "ext4", root.flags, NULL) < 0)
+ err(1, "init: mount rootfs %s", root.dev);
+
+ if (mkdir("/root/dev", 0755) < 0)
+ err(1, "init: mkdir /root/dev");
+
+ if (mount("/dev", "/root/dev", NULL, MS_BIND | MS_REC, NULL) < 0)
+ err(1, "init: mount --bind /dev");
+
+ if (mkdir("/root/proc", 0755) < 0)
+ err(1, "init: chdir /root");
+
+ if (mount("/proc", "/root/proc", NULL, MS_BIND | MS_REC, NULL) < 0)
+ err(1, "init: mount --bind /proc");
+
+ if (mkdir("/root/sys", 0755) < 0)
+ err(1, "init: chdir /root");
+
+ if (mount("sysfs", "/root/sys", "sysfs", 0, NULL) < 0)
+ err(1, "init: mount --bind /sys");
+
+ if (chroot("/root") < 0)
+ err(1, "init: chroot /root");
+
+ if (chdir("/") < 0)
+ err(1, "init: chdir /");
+
+ execve("/bin/init", argv, NULL);
+ err(1, "init: execve /bin/init");
+}
diff --git a/include/unistd.h b/include/unistd.h
index dd8dba5a..83c8a99e 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -35,6 +35,7 @@ int access(const char *, int);
unsigned alarm(unsigned);
int chdir(const char *);
int chown(const char *, uid_t, gid_t);
+int chroot(const char *);
int close(int);
// TODO:
diff --git a/lib/libc/Kbuild b/lib/libc/Kbuild
index e1eafe87..76e05807 100644
--- a/lib/libc/Kbuild
+++ b/lib/libc/Kbuild
@@ -1,4 +1,5 @@
lib-y := libc.a
+install-y := lib/libc.a
cflags-y += -I $(src)/include
diff --git a/lib/libc/unistd/Kbuild b/lib/libc/unistd/Kbuild
index ff3f025a..20f02c33 100644
--- a/lib/libc/unistd/Kbuild
+++ b/lib/libc/unistd/Kbuild
@@ -1,9 +1,10 @@
-obj-y += _exit.o
obj-y += _Fork.o
+obj-y += _exit.o
obj-y += access.o
obj-y += alarm.o
obj-y += chdir.o
obj-y += chown.o
+obj-y += chroot.o
obj-y += close.o
obj-y += dup.o
obj-y += dup2.o
@@ -29,8 +30,8 @@ obj-y += getgid.o
obj-y += getgroups.o
obj-y += gethostid.o
obj-y += gethostname.o
-obj-y += getlogin_r.o
obj-y += getlogin.o
+obj-y += getlogin_r.o
obj-y += getopt.o
obj-y += getpgid.o
obj-y += getpid.o
diff --git a/lib/libc/unistd/chroot.c b/lib/libc/unistd/chroot.c
new file mode 100644
index 00000000..5a895e13
--- /dev/null
+++ b/lib/libc/unistd/chroot.c
@@ -0,0 +1,7 @@
+#include <syscall.h>
+#include <unistd.h>
+
+int chroot(const char *path)
+{
+ return syscall(chroot, path);
+}
diff --git a/lib/libm/Kbuild b/lib/libm/Kbuild
index 6d3074cb..7dc47f30 100644
--- a/lib/libm/Kbuild
+++ b/lib/libm/Kbuild
@@ -1,4 +1,5 @@
lib-y := libm.a
+install-y := lib/libm.a
obj-y += __cos.o
obj-y += __cosdf.o
diff --git a/makefile b/makefile
index 19d61f2d..07f101f1 100644
--- a/makefile
+++ b/makefile
@@ -42,7 +42,13 @@ ifeq ($(CCACHE),1)
CC := ccache $(CC)
endif
-export CC LD AR STRIP CROSS_COMPILE ARCH
+ifndef O
+ O := $(srctree)/dist
+else
+ O := $(srctree)/$(O)
+endif
+
+export CC LD AR STRIP CROSS_COMPILE ARCH O
ifeq ($(V),1)
Q :=
@@ -120,25 +126,29 @@ PHONY :=
export Q srctree MAKEFLAGS KCONFIG_CONFIG \
KBUILD_CFLAGS KBUILD_ASFLAGS KBUILD_LDFLAGS
+PHONY += install
all: compile_commands.json
$(Q)$(MAKE) -f scripts/makefile.build obj=$(obj)
+PHONY += install
+install: all
+ $(Q)$(MAKE) -f scripts/makefile.build obj=$(obj) install
+ mkdir -p $(O)/usr
+ cp -r $(srctree)/include $(O)/usr/
+ rm -rf $(O)/usr/include/arch $(O)/usr/include/generated ${O}/usr/include/config
+
+PHONY += clean
clean:
$(Q)$(MAKE) -f scripts/makefile.build obj=$(obj) clean
$(Q)rm -f $(srctree)/include/config/auto.conf
$(Q)rm -f $(srctree)/include/generated/autoconf.h
+ $(Q)rm -rf $(srctree)/dist
+PHONY += distclean
distclean: clean
$(Q)$(MAKE) -C scripts/kconfig clean
$(Q)rm -f compile_commands.json
-info:
- echo "CC: $(CC)"
- echo "ARCH: $(ARCH)"
- echo "CFLAGS: $(KBUILD_CFLAGS)"
- echo "LDFLAGS: $(KBUILD_LDFLAGS)"
- echo "ASFLAGS: $(KBUILD_ASFLAGS)"
-
$(KCONFIG_CONFIG):
@echo >&2 '***'
@echo >&2 '*** Configuration file "$@" not found!'
@@ -148,13 +158,26 @@ $(KCONFIG_CONFIG):
@echo >&2 '***'
@false
+PHONY += help
+help:
+ @echo "Available make targets:"
+ @echo " all - Build the project (default)"
+ @echo " install - Install the built files"
+ @echo " clean - Clean build files"
+ @echo " distclean - Clean all generated files"
+ @echo " menuconfig - Launch the menu-based configuration tool"
+ @echo " include-what-you-use - Run include-what-you-use on the source files"
+ @echo " clang-tidy - Run clang-tidy on the source files"
+ @echo " clang-format - Format source files using clang-format"
+
compile_commands.json:
$(Q)bear -- $(MAKE) -f scripts/makefile.build obj=$(obj) all
PHONY += menuconfig
menuconfig:
- $(Q)$(MAKE) -f scripts/kconfig/makefile 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 \
@@ -163,10 +186,12 @@ include-what-you-use: compile_commands.json
--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/')
diff --git a/scripts/kconfig/makefile b/scripts/kconfig/makefile
index 6bfd24a1..bab0ef36 100644
--- a/scripts/kconfig/makefile
+++ b/scripts/kconfig/makefile
@@ -2,10 +2,8 @@ CC ?= gcc
LEX ?= flex
YACC ?= bison
-VPATH := $(srctree)/scripts/kconfig
-
-CFLAGS := -Iinclude
-LDFLAGS := -lncurses
+CFLAGS += -Iinclude
+LDFLAGS += -lcurses
common-obj := confdata.o expr.o lexer.lex.o menu.o parser.tab.o \
preprocess.o symbol.o util.o
@@ -17,7 +15,7 @@ lxdl-obj := checklist.o inputbox.o menubox.o \
conf: conf.o $(common-obj)
mconf: mconf.o $(common-obj) $(lxdl-obj)
nconf: nconf.o nconf.gui.o mnconf-common.o $(common-obj)
-lexer.lex.c: lexer.l
+lexer.lex.c: lexer.l | parser.tab.h
parser.tab.c parser.tab.h: parser.y
%.lex.c: %.l
@@ -27,13 +25,14 @@ parser.tab.c parser.tab.h: parser.y
$(YACC) -d -o parser.tab.c $<
syncconfig: conf
- scripts/kconfig/conf --syncconfig Kconfig .config
+ ./conf --syncconfig Kconfig $(srctree)/.config
menuconfig: mconf
- scripts/kconfig/mconf Kconfig
+ ./mconf $(srctree)/Kconfig
+ [ -f .config ] && mv -f .config $(srctree) || true
clean:
- rm -f *.o lexer.lex.c parser.tab.c parser.tab.h conf mconf nconf
+ rm -f *.o *.lex.c parser.tab.c parser.tab.h conf mconf nconf
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
diff --git a/scripts/kconfig/mconf b/scripts/kconfig/mconf
new file mode 100755
index 00000000..35f70dcb
--- /dev/null
+++ b/scripts/kconfig/mconf
Binary files differ
diff --git a/scripts/makefile.build b/scripts/makefile.build
index fe8f1a78..7049d19c 100644
--- a/scripts/makefile.build
+++ b/scripts/makefile.build
@@ -21,7 +21,7 @@ endif
objects := $(filter %.o,$(obj-y))
subdirs := $(filter %/,$(obj-y))
-cflags := $(cflags-y) $(KBUILD_CFLAGS)
+cflags := $(cflags-y) $(KBUILD_CFLAGS) -MMD -MP
asflags := $(asflags-y) $(KBUILD_ASFLAGS)
ldflags := $(ldflags-y) $(KBUILD_LDFLAGS)
@@ -39,6 +39,9 @@ else
all-objects := $(objects)
endif
+deps := $(all-objects:.o=.d)
+-include $(deps)
+
c-sources := $(wildcard $(addprefix $(obj),$(objects:.o=.c)))
s-sources := $(wildcard $(addprefix $(obj),$(objects:.o=.s)))
subdir-c-sources := $(wildcard $(addprefix $(obj),$(subdir-objects:.o=.c)))
@@ -51,14 +54,38 @@ all: $(obj)$(lib-y) $(addprefix $(obj),$(always))
$(obj)$(lib-y): $(addprefix $(obj),$(all-objects))
$(MSG) AR "$@"
$(Q)$(AR) rcs $@ $^
+
+$(O)/$(install-y): $(obj)$(lib-y)
+ mkdir -p $(O)/$(dir $(install-y))
+ install -m 0644 $< $(O)/$(install-y)
+
+ifdef install-y
+install: $(O)/$(install-y)
+else
+install:
+endif
+
else ifdef bin-y
all: $(obj)$(bin-y) $(addprefix $(obj),$(always))
$(obj)$(bin-y): $(addprefix $(obj),$(all-objects)) $(libs-y) ${prereq}
$(MSG) LD "$@"
$(Q)$(LD) $(ldflags) -o $@ $^
+
+ifdef install-y
+$(O)/$(install-y): $(obj)$(bin-y)
+ mkdir -p $(O)/$(dir $(install-y))
+ install -m 0755 $< $(O)/$(install-y)
+
+install: $(O)/$(install-y)
+else
+install:
+endif
+
else
all: $(addprefix $(obj),$(all-objects)) $(subdirs) $(addprefix $(obj),$(always))
+
+install: $(subdirs)
endif
PHONY += clean clean-%
@@ -92,7 +119,7 @@ $(filter $(addprefix $(obj),$(all-objects)),$(s-sources:.s=.o) $(subdir-s-source
.PHONY: $(subdirs)
$(subdirs):
- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj="$(obj)$@"
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj="$(obj)$@" ${MAKECMDGOALS}
clean-%:
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj="$(obj)$*" clean