diff --git a/.gitignore b/.gitignore index 0c216a1..6d814ac 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,10 @@ .vScode* .Vscode* .VScode* +/config/.config +/config/.config.old +.config +.config.old +/include/config +/include/generated + diff --git a/.gitmodules b/.gitmodules index 3846fe7..28960c7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "opensbi"] path = opensbi url = https://github.com/riscv-software-src/opensbi +[submodule "support/scripts/kconfig"] + path = support/scripts/kconfig + url = https://github.com/linux-kdevops/kconfig.git diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..becac31 --- /dev/null +++ b/Kconfig @@ -0,0 +1,140 @@ +mainmenu "Runikraft/0.1.0 Configuration" + +menu "Memory and CPU Configuration" + config HEAP_SIZE + int "Heap size(MiB)" + default 16 + + config STACK_SIZE_PAGE_ORDER + int "Page order of stack size(log STACK_SIZE)" + default 4 + + menu "Limit Configuration" + config MEMORY_SIZE + int "the maximum size of memory(B)" + default -1 + help + -1: unlimited + + config OPEN_FILES + int "the maximum size of open files" + default 1024 + + config PIPE_FILES + int "the maximum size of pipe files" + default 4096 + + config CPU_TIME + int "the limit of CPU time(ms)" + default -1 + help + -1: Duration::MAX + endmenu + + config LCPU_MAXCOUNT + int "the maximum count of CPU(less than 8)" + default 8 + + config MAIN_STACK_SIZE + int "the main stack size(B)" + default 65536 + + config PAGE_SZIE + int "the page size(B)" + default 4096 +endmenu + +menu "Library Configuration" + menu "rkplat features" + config has_smp + bool "Symmetric multiprocessor support" + default y + + config save_fp + bool "Save floating point registers when thread switches" + default n + + config driver_uart + bool "Uart device driver" + default n + + config driver_ns16550 + bool "ns16550 driver" + default y + select driver_uart + + config driver_virtio + bool "Virtio driver" + default n + help + Depend on volatile-v0.3 and bitflags-v1.3 + + config driver_virtio_blk + bool "Virtio block driver" + default y + select driver_virtio + + config driver_virtio_console + bool "Virtio console driver" + default y + select driver_virtio + + config driver_virtio_gpu + bool "Virtio GPU driver" + default y + select driver_virtio + + config driver_virtio_input + bool "Virtio input driver" + default y + select driver_virtio + + config driver_virtio_net + bool "Virtio net driver" + default y + select driver_virtio + + config driver_rtc + bool "Real time clock driver" + default n + + config driver_goldfish_rtc + bool "Goldfish real time clock driver" + default y + select driver_rtc + + config bios_io + bool "Use BIOS to output" + default n + endmenu + + menu "rkboot features" + config have_scheduler + bool "Have scheduler" + help + Depend on rksched + + config sched_coop + bool "Cooperative scheduler" + default y + select have_scheduler + help + Depend on rksched and rkschedcoop + endmenu +endmenu + +menu "Make Build Configuration" + choice + prompt "Make build type" + default debug + + config debug + bool "debug type" + help + Compile without "--release" + config release + bool "release type" + help + Compile with "--release" + endchoice +endmenu diff --git a/makefile b/Makefile similarity index 63% rename from makefile rename to Makefile index f103f0d..2f6c690 100644 --- a/makefile +++ b/Makefile @@ -2,6 +2,7 @@ # makefile for Runikraft # Authors: 张子辰 +# 陈建绿 <2512674094@qq.com> # Copyright (C) 2022 吴骏东, 张子辰, 蓝俊玮, 郭耸霄 and 陈建绿. @@ -39,18 +40,28 @@ export MAKE_ROOT_DIR := $(PWD)/build export REPORT_ROOT_DIR := $(PWD)/report export TEST_ROOT_DIR := $(PWD)/test export SRC_ROOT_DIR := $(PWD) -export MAKE_BUILD_TYPE := debug export CROSS_COMPILE := riscv64-linux-gnu- TEST_LIST := @all IGNORED_LIST := -.PHONY: all +export PROJECT = Runikraft +export VERSION = 0 +export PATCHLEVEL = 1 +export SUBLEVEL = 0 +export EXTRAVERSION = + +CONFIG_DIR := $(MAKE_ROOT_DIR)/config +SUPPORT_DIR := $(SRC_ROOT_DIR)/support +SCRIPTS_DIR := $(SUPPORT_DIR)/scripts +export KCONFIG_DIR := $(SCRIPTS_DIR)/kconfig + +PHNOY += all all: test -.PHONY: everything +PHNOY += everything everything: all report -.PHONY: report +PHNOY += report report: $(MAKE_ROOT_DIR)/report/makefile cd "$(MAKE_ROOT_DIR)/report" && $(MAKE) @@ -58,18 +69,20 @@ $(MAKE_ROOT_DIR)/report/makefile: makefiles/report.mk -mkdir --parents "$(MAKE_ROOT_DIR)/report" cp makefiles/report.mk "$(MAKE_ROOT_DIR)/report/makefile" -.PHONY: test build_test $(MAKE_ROOT_DIR)/test/makefile +PHNOY += test test: $(MAKE_ROOT_DIR)/test/makefile opensbi cd "$(MAKE_ROOT_DIR)/test" && $(MAKE) +PHNOY += build_test build_test: $(MAKE_ROOT_DIR)/test/makefile cd "$(MAKE_ROOT_DIR)/test" && $(MAKE) build +PHNOY += $(MAKE_ROOT_DIR)/test/makefile $(MAKE_ROOT_DIR)/test/makefile: makefiles/test.mk.sh makefiles/test.mk.0 makefiles/test.mk.1 -mkdir --parents "$(MAKE_ROOT_DIR)/test" makefiles/test.mk.sh makefiles/test.mk "$(MAKE_ROOT_DIR)/test/makefile" "$(TEST_ROOT_DIR)" "$(TEST_LIST)" "$(IGNORED_LIST)" "$(MAKE_ROOT_DIR)/opensbi/platform/generic/firmware/fw_jump.bin" -.PHONY: opensbi +PHNOY += opensbi opensbi: #FW_OPTIONS=1 indicates quiet boot -mkdir --parents "$(MAKE_ROOT_DIR)/opensbi" @@ -78,26 +91,51 @@ opensbi: $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib: $(SRC_ROOT_DIR)/lib/rkalloc/alloc_error_handler.rs @env RUSTC_BOOTSTRAP=1 rustc --edition=2021 $(SRC_ROOT_DIR)/lib/rkalloc/alloc_error_handler.rs --crate-type lib --target riscv64gc-unknown-none-elf -o $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib -$(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(MAKE_BUILD_TYPE)/deps/liballoc_error_handler.rlib: $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib - @-mkdir --parents $(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(MAKE_BUILD_TYPE)/deps/ - @cp $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib $(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(MAKE_BUILD_TYPE)/deps/liballoc_error_handler.rlib - +$(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(shell cat $(CONFIG_DIR)/features2.txt)/deps/liballoc_error_handler.rlib: $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib $(CONFIG_DIR)/features2.txt + @-mkdir --parents $(TEST_BUILD_DIR)/deps + @cp $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib $(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(shell cat $(CONFIG_DIR)/features2.txt)/deps/liballoc_error_handler.rlib -.PHONY: example run -example: $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib $(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(MAKE_BUILD_TYPE)/deps/liballoc_error_handler.rlib -ifeq ($(MAKE_BUILD_TYPE), release) - cd example/sudoku && env RUSTFLAGS="-Clink-arg=-T$(SRC_ROOT_DIR)/linker.ld --cfg __alloc_error_handler --extern __alloc_error_handler=$(MAKE_ROOT_DIR)/liballoc_error_handler.rlib" cargo build --release +PHNOY += example +example: $(MAKE_ROOT_DIR)/liballoc_error_handler.rlib $(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(shell cat $(CONFIG_DIR)/features2.txt)/deps/liballoc_error_handler.rlib $(CONFIG_DIR)/features1.txt $(CONFIG_DIR)/features2.txt +ifeq ($(shell cat $(CONFIG_DIR)/features2.txt), release) + cd example/sudoku && env RUSTFLAGS="-Clink-arg=-T$(SRC_ROOT_DIR)/linker.ld --cfg __alloc_error_handler --extern __alloc_error_handler=$(MAKE_ROOT_DIR)/liballoc_error_handler.rlib" cargo build --release $(shell cat $(CONFIG_DIR)/features1.txt) else -ifeq ($(MAKE_BUILD_TYPE), debug) - cd example/sudoku && env RUSTFLAGS="-Clink-arg=-T$(SRC_ROOT_DIR)/linker.ld --cfg __alloc_error_handler --extern __alloc_error_handler=$(MAKE_ROOT_DIR)/liballoc_error_handler.rlib" cargo build +ifeq ($(shell cat $(CONFIG_DIR)/features2.txt), debug) + cd example/sudoku && env RUSTFLAGS="-Clink-arg=-T$(SRC_ROOT_DIR)/linker.ld --cfg __alloc_error_handler --extern __alloc_error_handler=$(MAKE_ROOT_DIR)/liballoc_error_handler.rlib" cargo build $(shell cat $(CONFIG_DIR)/features1.txt) else @echo "Unknown build type, expect release/debug." false endif endif - $(CROSS_COMPILE)objcopy --strip-all "$(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(MAKE_BUILD_TYPE)/sudoku" -O binary "$(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(MAKE_BUILD_TYPE)/sudoku.bin" - + $(CROSS_COMPILE)objcopy --strip-all "$(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(shell cat $(CONFIG_DIR)/features2.txt)/sudoku" -O binary "$(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(shell cat $(CONFIG_DIR)/features2.txt)/sudoku.bin" +PHNOY += run run: - qemu-system-riscv64 -machine virt -kernel "$(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(MAKE_BUILD_TYPE)/sudoku.bin" -device virtio-gpu-device,xres=1280,yres=800 -serial mon:stdio -device virtio-keyboard-device -device virtio-rng-device -bios "$(MAKE_ROOT_DIR)/opensbi/platform/generic/firmware/fw_jump.bin" + qemu-system-riscv64 -machine virt -kernel "$(MAKE_ROOT_DIR)/riscv64gc-unknown-none-elf/$(shell cat $(CONFIG_DIR)/features2.txt)/sudoku.bin" -device virtio-gpu-device,xres=1280,yres=800 -serial mon:stdio -device virtio-keyboard-device -device virtio-rng-device -bios "$(MAKE_ROOT_DIR)/opensbi/platform/generic/firmware/fw_jump.bin" + +$(CONFIG_DIR)/features1.txt: menuconfig +$(CONFIG_DIR)/features2.txt: menuconfig + +PHNOY += menuconfig +menuconfig: $(KCONFIG_DIR)/mconf include/config/project.release $(CONFIG_DIR)/handle_config + @$< Kconfig + @mkdir -p $(CONFIG_DIR) + @$(CONFIG_DIR)/handle_config $(SRC_ROOT_DIR) $(CONFIG_DIR) + +include $(SCRIPTS_DIR)/objects.Makefile + +$(CONFIG_DIR)/handle_config: $(SUPPORT_DIR)/handle_config.cpp + @mkdir -p $(CONFIG_DIR) + @g++ $(SUPPORT_DIR)/handle_config.cpp -o $(CONFIG_DIR)/handle_config + +PHONY += clean +clean: + $(MAKE) -f $(SCRIPTS_DIR)/build.Makefile $@ + +PHONY += help +help: + @echo "Configuration options:" + @echo "menuconfig - demos the menuconfig functionality" + @echo " configuration options will be written in $(CONFIG_DIR)/config.rs" +.PHONY: $(PHONY) diff --git a/default_config.rs b/default_config.rs index bb2f415..35f1ea4 100644 --- a/default_config.rs +++ b/default_config.rs @@ -5,13 +5,24 @@ // permitted in any medium without royalty provided the copyright notice and // this notice are preserved. This file is offered as-is, without any warranty. -pub const LIBUKNETDEV_MAXNBQUEUES: usize = 1; -pub const RK_NETDEV_SCRATCH_SIZE: usize = 0; +pub const HEAP_SIZE: usize = 16<<20; + +pub mod rksched { + pub const STACK_SIZE_PAGE_ORDER: usize = 4; + pub const STACK_SIZE: usize = super::rkplat::PAGE_SIZE*(1< +#include +#include + +const std::string const_prefix = "pub const "; +const std::string mod_prefix = "pub mod "; +const std::string mod_suffix = "{\n\t"; +const std::string mod_end = "}\n"; +const std::string empty; + +std::string features1; +std::string features2; + +std::string scope; +unsigned int count = 0; + +std::string replace_content(std::string content, unsigned int flag); + +int main(int argc, char* argv[]) { + if(argc < 3) { + std::cerr << "Too few arguments!\n"; + } + // const std::string SRC_ROOT_DIR = "."; + // const std::string BUILD_DIR = "."; + const std::string SRC_ROOT_DIR = argv[1]; + const std::string BUILD_DIR = argv[2]; + + std::string output_filename = BUILD_DIR + "/config.rs"; + std::ofstream OutputFile(output_filename); + + std::cout << output_filename << "\n"; + + std::string message; + message += "// RUNIKRAFT_CONFIG_FILE: " + BUILD_DIR + "/config.rs\n// Automatically generated file. DO NOT EDIT.\n\n\n"; + OutputFile << message; + + std::string input_filename = SRC_ROOT_DIR + "/.config"; + std::ifstream InputFile(input_filename); + + std::string line; + while(std::getline(InputFile, line)) { + if(line.length() > 2 && line.substr(0, 2) == "# ") { + scope = line.substr(2, 6); + } else if(line.length() > 2 && line[0] != '#') { + if(line.find("CPU_TIME") != std::string::npos) + line = replace_content(line, 0); + else if(line.find("=y") != std::string::npos) + line = replace_content(line, 1); + else + line = replace_content(line, 2); + switch (count) { + case 0: { + message = const_prefix + line + "\n"; + OutputFile << message; + ++count; + break; + } + case 1: { + message = mod_prefix + "rksched" + mod_suffix; + message += const_prefix + line; + message = message + "\t" + "pub const STACK_SIZE: usize = super::rkplat::PAGE_SIZE*(1< 7 && content.substr(0, 7) == "CONFIG_") { + content = content.replace(0, 7, ""); + } + size_t pos; + while((pos = content.find('\"')) != std::string::npos){ + content = content.replace(pos, 1, ""); + } + if((pos = content.find('=')) != std::string::npos) { + if(flag == 0) { + std::string value_str = content.substr(pos+1); + int value = std::atoi(value_str.c_str()); + if(value < 0) { + content = content.replace(pos+1, content.length()-pos-1, "Duration::MAX"); + } else { + if(value == 0) { + std::cerr << "Warning: CPU_TIME can't be 0!\n"; + exit(-1); + } + std::string replace_str = "Duration::from_millis("; + replace_str += content.substr(pos+1) + ")"; + content = content.replace(pos+1, content.length()-pos, replace_str); + } + content = content.replace(pos, 1, ": Duration = ") + ";\n"; + } + else if(flag == 1) { + content = content.replace(pos, 2, ""); + } + else { + std::string value_str = content.substr(pos+1); + int value = std::atoi(value_str.c_str()); + if(value < 0) { + content = content.replace(pos+1, content.length()-pos-1, "usize::MAX"); + } + content = content.replace(pos, 1, ": usize = ") + ";\n"; + } + } + return content; +} \ No newline at end of file diff --git a/support/scripts/build.Makefile b/support/scripts/build.Makefile new file mode 100644 index 0000000..419237c --- /dev/null +++ b/support/scripts/build.Makefile @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Houses the targets which top level Makfiles can also define. +PHONY += clean +clean: $(clean-subdirs) + $(MAKE) -C $(KCONFIG_DIR)/ clean + +version-check: $(SRC_ROOT_DIR)/config/project.release + @echo Version: $(PROJECTVERSION) + @echo Release: $(PROJECTRELEASE) + +PHONY += help +help: + @$(MAKE) -s -C $(KCONFIG_DIR) help + @echo "Debugging" + @echo "version-check - demos version release functionality" + @echo "clean - cleans all output files" + +.PHONY: $(PHONY) diff --git a/support/scripts/kconfig b/support/scripts/kconfig new file mode 160000 index 0000000..43ccad2 --- /dev/null +++ b/support/scripts/kconfig @@ -0,0 +1 @@ +Subproject commit 43ccad2bd902dea0d9091db21b76a73ffd701e08 diff --git a/support/scripts/objects.Makefile b/support/scripts/objects.Makefile new file mode 100644 index 0000000..36f9f09 --- /dev/null +++ b/support/scripts/objects.Makefile @@ -0,0 +1,36 @@ +# Generic rule, you can be more specific in your own makefiles. +%.o: %.c *.h + $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< + +# Capture directories on obj-y and remove their leading character +# We will use this to construct a subdir object target for each, and +# a respective clean target. +__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) +subdir-y += $(__subdir-y) +subdir-y := $(sort $(subdir-y)) + +# Make a target rule for each subdir, so that we can later add to the obj-y +# target. The subdir-y-obs carries all subdirectory objects. +# If a subdir name dirname exists, we add dirname/dirname.o to the list of +# objects in subdir-y-objs +subdir-y-objs := $(foreach t,$(subdir-y),$(addsuffix /$t.o,$(t))) + +# Add a phony clean target, you'll need to add this as a dependency on the +# top level clean target. +clean-subdirs := $(foreach t,$(subdir-y),$(addsuffix /.ignore-clean,$(subdir-y))) +PHONY += $(clean-subdirs) + +# Remove all directories from obj-y +obj-y := $(filter-out %/, $(obj-y)) + +# Add the directory objects now to obj-y +obj-y := $(obj-y) $(subdir-y-objs) + +# For each clean target add a clean rule. +$(clean-subdirs): + $(MAKE) -C $(CURDIR)/$(patsubst %/.ignore-clean,%,$@) clean + +# For each subdirectory object target add a respective build target +# using a default target, by using the directory name only. +$(subdir-y-objs): + $(MAKE) -C $(dir $@)