diff --git a/README.assets/image-20230626210944466.png b/.README.assets/image-20230626210944466.png similarity index 100% rename from README.assets/image-20230626210944466.png rename to .README.assets/image-20230626210944466.png diff --git a/README.assets/image-20230626211247187.png b/.README.assets/image-20230626211247187.png similarity index 100% rename from README.assets/image-20230626211247187.png rename to .README.assets/image-20230626211247187.png diff --git a/README.assets/image-20230626211822243.png b/.README.assets/image-20230626211822243.png similarity index 100% rename from README.assets/image-20230626211822243.png rename to .README.assets/image-20230626211822243.png diff --git a/README.assets/image-20230626211928349.png b/.README.assets/image-20230626211928349.png similarity index 100% rename from README.assets/image-20230626211928349.png rename to .README.assets/image-20230626211928349.png diff --git a/README.assets/image-20230626212023883.png b/.README.assets/image-20230626212023883.png similarity index 100% rename from README.assets/image-20230626212023883.png rename to .README.assets/image-20230626212023883.png diff --git a/README.assets/image-20230626212038935.png b/.README.assets/image-20230626212038935.png similarity index 100% rename from README.assets/image-20230626212038935.png rename to .README.assets/image-20230626212038935.png diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..06e7bd2 --- /dev/null +++ b/.clang-format @@ -0,0 +1,12 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# .clang-format for Simple-XX/SimpleRTOS. + +--- +# @version clang-format version 15 +# @see https://clang.llvm.org/docs/ClangFormatStyleOptions.html +# 使用 LLVM 规范 +BasedOnStyle: LLVM +... diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..ba3c62a --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,22 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# .clang-tidy for Simple-XX/SimpleRTOS. + +--- +Checks: '-*,\ + bugprone-*,\ + clang-analyzer-*,\ + cppcoreguidelines-*,\ + hicpp-*,\ + llvm-*,\ + misc-* + modernize-*,\ + performance-*,\ + portability-*,\ + readability-*,\ + -cppcoreguidelines-pro-type-reinterpret-cast' +HeaderFilterRegex: '^${sourceDir}/src' +AnalyzeTemporaryDtors: true +... diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml new file mode 100644 index 0000000..6082095 --- /dev/null +++ b/.github/workflows/workflow.yml @@ -0,0 +1,114 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# workflow.yml for Simple-XX/SimpleRTOS. + +name: build + +on: + - push + - pull_request + - release + +env: + CMAKE_BUILD_TYPE: Release + +jobs: + build_docs: + name: Build and publish documentation + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo apt update + sudo apt install --fix-missing -y doxygen graphviz clang-format clang-tidy cppcheck qemu-system lcov + sudo apt install --fix-missing -y gcc g++ gcc-riscv64-linux-gnu g++-riscv64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu + + - name: Build + run: | + cmake --preset=build_x86_64 + cmake --build build_x86_64 --target doc + + - name: Publish + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ${{github.workspace}}/doc/html + + build_ubuntu: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo apt update + sudo apt install --fix-missing -y doxygen graphviz clang-format clang-tidy cppcheck qemu-system lcov + sudo apt install --fix-missing -y gcc g++ gcc-riscv64-linux-gnu g++-riscv64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu + + - name: x86_64 + run: | + cmake --preset=build_x86_64 + # @todo ci 暂时跑不过 + # cmake --build build_x86_64 --target boot + # cmake --build build_x86_64 --target kernel + cmake --build build_x86_64 --target coverage + + - name: riscv64 + run: | + cmake --preset=build_riscv64 + # @todo ci 暂时跑不过 + # cmake --build build_riscv64 --target kernel + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + with: + files: build_x86_64/coverage/coverage.info + verbose: true + +# build_osx: +# runs-on: macos-latest +# steps: +# - name: get code +# uses: actions/checkout@v3 +# +# - name: setup toolchain +# shell: bash +# run: | +# brew install x86_64-elf-gcc +# brew tap riscv-software-src/riscv +# brew install riscv-tools +# +# - name: make build dir +# shell: bash +# run: | +# mkdir ${{github.workspace}}/build +# +# - name: osx-i386 +# shell: bash +# working-directory: ${{github.workspace}}/build +# run: | +# cmake -DTOOLCHAIN_PREFIX=x86_64-elf- -DCMAKE_C_COMPILER=x86_64-elf-gcc -DCMAKE_CXX_COMPILER=x86_64-elf-g++ -DARCH=i386 -DCMAKE_BUILD_TYPE=RELEASE -DHAVE_FLAG_SEARCH_PATHS_FIRST=0 .. +# make +# rm -rf ./* +# +# - name: osx-x86_64 +# shell: bash +# working-directory: ${{github.workspace}}/build +# run: | +# cmake -DTOOLCHAIN_PREFIX=x86_64-elf- -DCMAKE_C_COMPILER=x86_64-elf-gcc -DCMAKE_CXX_COMPILER=x86_64-elf-g++ -DARCH=x86_64 -DCMAKE_BUILD_TYPE=RELEASE -DHAVE_FLAG_SEARCH_PATHS_FIRST=0 .. +# make +# rm -rf ./* +# +# - name: osx-riscv64 +# shell: bash +# working-directory: ${{github.workspace}}/build +# run: | +# cmake -DTOOLCHAIN_PREFIX=riscv64-unknown-elf- -DCMAKE_C_COMPILER=riscv64-unknown-elf-gcc -DCMAKE_CXX_COMPILER=riscv64-unknown-elf-g++ -DARCH=riscv64 -DCMAKE_BUILD_TYPE=RELEASE -DHAVE_FLAG_SEARCH_PATHS_FIRST=0 .. +# make +# rm -rf ./* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f68dab0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# .gitignore for Simple-XX/SimpleRTOS. + +*.o +.DS_Store +build +build_aarch64 +build_riscv64 +build_x86_64 +doc/html +cmake-build* +.gdbinit +tools/opensbi/build +.vscode +.idea +3rd +Doxyfile diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c4dcc86 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,82 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# CMakeLists.txt for Simple-XX/SimpleRTOS. + +# 设置最小 cmake 版本 +cmake_minimum_required(VERSION 3.27 FATAL_ERROR) + +# 设置项目名与版本 +project( + SimpleRTOS + VERSION 0.0.1 +) + +# 禁止原地编译 +if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR}) + # 如果你看到这句话,cmake 此时已经在根目录下生成了一些临时文件,你需要删除它们 + # CMakeFiles, CMakeCache.txt + message( + FATAL_ERROR + "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there." + ) +endif () + +# 设置辅助 cmake 脚本路径 +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") + +# 导入项目配置 +include(project_config) +# 导入头文件处理 +include(add_header) +# 导入函数 +include(functions) + +# 导入第三方依赖 +include(3rd) + +# 导入编译配置 +include(compile_config) + +# qemu 参数设置 +list(APPEND QEMU_FLAGS + # 使用标准输出显示 + -serial stdio + # 启动 telnet 服务,使用 2333 端口,不等待连接 + -monitor ${QEMU_MONITOR_ARG} +) +# 目标平台参数 +if(TARGET_ARCH STREQUAL "x86_64") + list(APPEND QEMU_FLAGS + -m 128M + -net none + -bios ${ovmf_BINARY_DIR}/OVMF_${TARGET_ARCH}.fd + -hda fat:rw:./image/ + ) +elseif(TARGET_ARCH STREQUAL "riscv64") + list(APPEND QEMU_FLAGS + -machine virt + -nographic + # 可选项,qemu7.0 自带了 opensbi1.0 + -bios ${opensbi_BINARY_DIR}/platform/generic/firmware/fw_jump.elf + -kernel $ + ) +elseif(TARGET_ARCH STREQUAL "aarch64") + # @todo +endif() + +# 添加要编译的目录 +add_subdirectory(${PROJECT_SOURCE_DIR}/src) +add_subdirectory(${PROJECT_SOURCE_DIR}/test) +add_subdirectory(${PROJECT_SOURCE_DIR}/doc) + +# 添加 run 和 debug target +add_run_target(NAME run + DEPENDS $<$:boot> kernel ${RUN_DEPENDS} ${DEBUG_DEPENDS} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + TARGET ${TARGET_ARCH} + BOOT ${PROJECT_BINARY_DIR}/src/boot/boot.efi + KERNEL $ + QEMU_FLAGS ${QEMU_FLAGS} +) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..acb1c7c --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,113 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 27, + "patch": 0 + }, + "configurePresets": [ + { + "name": "std", + "description": "This preset makes sure the project actually builds with at least the specified standard", + "hidden": true, + "cacheVariables": { + "CMAKE_C_EXTENSIONS": "OFF", + "CMAKE_C_STANDARD": "17", + "CMAKE_C_STANDARD_REQUIRED": "ON", + "CMAKE_CXX_EXTENSIONS": "OFF", + "CMAKE_CXX_STANDARD": "20", + "CMAKE_CXX_STANDARD_REQUIRED": "ON" + } + }, + { + "name": "configurePresets_base", + "hidden": true, + "inherits": [ + "std" + ], + "condition": true, + "displayName": "configurePresets_base", + "description": "base configurePresets", + "generator": "Unix Makefiles", + "toolchainFile": "", + "binaryDir": "", + "installDir": "", + "cacheVariables": { + "CMAKE_VERBOSE_MAKEFILE": { + "type": "BOOL", + "value": "TRUE" + }, + "CMAKE_EXPORT_COMPILE_COMMANDS": { + "type": "BOOL", + "value": "ON" + }, + "CMAKE_BUILD_TYPE": { + "type": "STRING", + "value": "Debug" + }, + "COVERAGE_OUTPUT_DIR": { + "type": "STRING", + "value": "coverage" + }, + "PLATFORM": { + "type": "STRING", + "value": "qemu" + }, + "QEMU_GDB_PORT": { + "type": "STRING", + "value": "tcp::1234" + }, + "QEMU_MONITOR_ARG": { + "type": "STRING", + "value": "telnet::2333,server,nowait" + }, + "BOOT_ELF_OUTPUT_NAME": { + "type": "STRING", + "value": "boot.elf" + }, + "BOOT_EFI_OUTPUT_NAME": { + "type": "STRING", + "value": "boot.efi" + }, + "KERNEL_ELF_OUTPUT_NAME": { + "type": "STRING", + "value": "kernel.elf" + } + } + }, + { + "name": "build_x86_64", + "hidden": false, + "inherits": [ + "configurePresets_base" + ], + "displayName": "build x86_64 kernel", + "description": "build x86_64 kernel", + "toolchainFile": "${sourceDir}/cmake/x86_64-x86_64-gcc.cmake", + "binaryDir": "${sourceDir}/build_x86_64", + "cacheVariables": { + "TARGET_ARCH": { + "type": "STRING", + "value": "x86_64" + } + } + }, + { + "name": "build_riscv64", + "hidden": false, + "inherits": [ + "configurePresets_base" + ], + "displayName": "build riscv64 kernel", + "description": "build riscv64 kernel", + "toolchainFile": "${sourceDir}/cmake/x86_64-riscv64-gcc.cmake", + "binaryDir": "${sourceDir}/build_riscv64", + "cacheVariables": { + "TARGET_ARCH": { + "type": "STRING", + "value": "riscv64" + } + } + } + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4de23ae --- /dev/null +++ b/Dockerfile @@ -0,0 +1,70 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# Dockerfile for Simple-XX/SimpleRTOS. + +FROM ubuntu:latest + +# 替换为你想要的用户名 +ARG user=zone +ARG password=zone + +# 元数据 +LABEL maintainer="Zone.N" email="zone.niuzh@hotmail.com" + +# 安装所有依赖 +RUN DEBIAN_FRONTEND=noninteractive \ + && apt update \ + && apt install --no-install-recommends --fix-missing -y \ + curl \ + wget \ + sudo \ + zsh \ + zip \ + openssh-server \ + rsync \ + tar \ + git \ + vim \ + doxygen \ + graphviz \ + make \ + cmake \ + clang-format \ + qemu-system \ + build-essential \ + binutils \ + valgrind \ + gdb-multiarch \ + gcc \ + g++ \ + gcc-riscv64-linux-gnu \ + g++-riscv64-linux-gnu \ + && apt clean \ + && git config --global --add safe.directory '*' \ + && sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" + +# 设置 ssh +RUN mkdir -p /var/run/sshd \ + && echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config \ + && echo 'PubkeyAuthentication yes' >> /etc/ssh/sshd_config \ + && echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config \ + && ssh-keygen -A + +# 添加用户 +RUN useradd --create-home --no-log-init --shell /bin/zsh ${user} \ + && adduser ${user} sudo \ + && echo "${user}:${password}" | chpasswd + +# 指定容器登录用户 +# USER ${user} + +# 指定容器起来的工作目录 +WORKDIR /home/${user} + +# 开放 22 端口 +EXPOSE 22 + +# 启动 ssh 服务 +ENTRYPOINT service ssh restart && bash diff --git a/README.md b/README.md index c344fcc..d5d5c24 100644 --- a/README.md +++ b/README.md @@ -75,25 +75,25 @@ 例如`stm32f103vet6`的项目: -![image-20230626210944466](README.assets/image-20230626210944466.png) +![image-20230626210944466](.README.assets/image-20230626210944466.png) ###### step2: 连接好开发板调试器和串口,并确认供电正常 串口设置: -![image-20230626211928349](README.assets/image-20230626211928349.png) +![image-20230626211928349](.README.assets/image-20230626211928349.png) ###### step3: 构建 -![image-20230626211247187](README.assets/image-20230626211247187.png) +![image-20230626211247187](.README.assets/image-20230626211247187.png) ###### step4: 下载 -![image-20230626211822243](README.assets/image-20230626211822243.png) +![image-20230626211822243](.README.assets/image-20230626211822243.png) 然后可以观察到串口输出,输入`help`可以查看当前`os`中的命令 -![image-20230626212038935](README.assets/image-20230626212038935.png) +![image-20230626212038935](.README.assets/image-20230626212038935.png) #### 2.2.2 linux环境: @@ -206,7 +206,7 @@ SIMPLERTOS ├─Build ├─gcc-arm-none-eabi-10-2020-q4-major ├─notes -├─README.assets +├─.README.assets └─workspace ├─catOS │ ├─bsp diff --git a/cmake/3rd.cmake b/cmake/3rd.cmake new file mode 100644 index 0000000..3d1d1db --- /dev/null +++ b/cmake/3rd.cmake @@ -0,0 +1,355 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# 3rd.cmake for Simple-XX/SimpleRTOS. +# 依赖管理 + +# 设置依赖下载路径 +set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/3rd) +# 优先使用本地文件 +set(CPM_USE_LOCAL_PACKAGES True) +# https://github.com/cpm-cmake/CPM.cmake +# -------- get_cpm.cmake -------- +set(CPM_DOWNLOAD_VERSION 0.38.2) + +if (CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif (DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else () + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif () + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +function (download_cpm) + message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") + file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} + ) +endfunction () + +if (NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) + download_cpm() +else () + # resume download if it previously failed + file(READ ${CPM_DOWNLOAD_LOCATION} check) + if ("${check}" STREQUAL "") + download_cpm() + endif () + unset(check) +endif () + +include(${CPM_DOWNLOAD_LOCATION}) +# -------- get_cpm.cmake -------- + +# https://github.com/google/googletest +CPMAddPackage( + NAME googletest + GITHUB_REPOSITORY google/googletest + GIT_TAG v1.13.0 + VERSION 1.13.0 + OPTIONS + "INSTALL_GTEST OFF" + "gtest_force_shared_crt ON" +) + +# # https://github.com/abumq/easyloggingpp +# CPMAddPackage( +# NAME easylogingpp +# VERSION 9.97.0 +# GITHUB_REPOSITORY amrayn/easyloggingpp +# OPTIONS +# "build_static_lib ON" +# "lib_utc_datetime ON" +# ) + +# https://github.com/rttrorg/rttr +# @bug 打开这个会导致编译参数中多出来几个 +# CPMAddPackage( +# NAME rttr # link against RTTR::Core_Lib +# VERSION 0.9.6 +# GITHUB_REPOSITORY rttrorg/rttr +# OPTIONS +# "BUILD_RTTR_DYNAMIC Off" +# "BUILD_UNIT_TESTS Off" +# "BUILD_STATIC On" +# "BUILD_PACKAGE Off" +# "BUILD_WITH_RTTI On" +# "BUILD_EXAMPLES Off" +# "BUILD_DOCUMENTATION Off" +# "BUILD_INSTALLER Off" +# "USE_PCH Off" +# "CUSTOM_DOXYGEN_STYLE Off" +# ) + +# https://github.com/TheLartians/Format.cmake +# CPMAddPackage( +# NAME Format.cmake +# GITHUB_REPOSITORY TheLartians/Format.cmake +# VERSION 1.7.3 +# ) + +# # https://github.com/freetype/freetype +# CPMAddPackage( +# NAME freetype +# GIT_REPOSITORY https://github.com/freetype/freetype.git +# GIT_TAG VER-2-13-0 +# VERSION 2.13.0 +# ) +# if (freetype_ADDED) +# add_library(Freetype::Freetype ALIAS freetype) +# endif() + +if (${TARGET_ARCH} STREQUAL "riscv64") + # https://github.com/riscv-software-src/opensbi + CPMAddPackage( + NAME opensbi + GIT_REPOSITORY https://github.com/riscv-software-src/opensbi.git + GIT_TAG v1.3 + VERSION 1.3 + DOWNLOAD_ONLY True + ) + if (opensbi_ADDED) + # 编译 opensbi + add_custom_target(opensbi + COMMENT "build opensbi..." + # make 时编译 + ALL + WORKING_DIRECTORY ${opensbi_SOURCE_DIR} + COMMAND + ${CMAKE_COMMAND} + -E + make_directory + ${opensbi_BINARY_DIR} + COMMAND + make + CROSS_COMPILE=${TOOLCHAIN_PREFIX} + FW_JUMP=y + FW_JUMP_ADDR=0x80200000 + PLATFORM_RISCV_XLEN=64 + PLATFORM=generic + O=${opensbi_BINARY_DIR} + COMMAND + ${CMAKE_COMMAND} + -E + copy_directory + ${opensbi_SOURCE_DIR}/include + ${opensbi_BINARY_DIR}/include + ) + endif () +endif () + +if (${TARGET_ARCH} STREQUAL "x86_64" OR ${TARGET_ARCH} STREQUAL "aarch64") + # https://sourceforge.net/projects/gnu-efi/ + CPMAddPackage( + NAME gnu-efi + URL "https://sourceforge.net/projects/gnu-efi/files/gnu-efi-3.0.17.tar.bz2" + VERSION 3.0.17 + DOWNLOAD_ONLY True + ) + if (gnu-efi_ADDED) + # 编译 gnu-efi + add_custom_target(gnu-efi + COMMENT "build gnu-efi..." + # make 时编译 + ALL + WORKING_DIRECTORY ${gnu-efi_SOURCE_DIR} + COMMAND + ${CMAKE_COMMAND} + -E + make_directory + ${gnu-efi_BINARY_DIR} + COMMAND + make + # @note 仅支持 gcc + CC=${CMAKE_C_COMPILER} + AR=${CMAKE_AR} + ARCH=${TARGET_ARCH} + OBJDIR=${gnu-efi_BINARY_DIR} + COMMAND + ${CMAKE_COMMAND} + -E + copy_directory + ${gnu-efi_SOURCE_DIR}/inc + ${gnu-efi_BINARY_DIR}/inc + ) + endif () + + # ovmf + # @todo 使用互联网连接或从 edk2 编译 + CPMAddPackage( + NAME ovmf + SOURCE_DIR ${PROJECT_SOURCE_DIR}/tools/ovmf + ) + if (ovmf_ADDED) + add_custom_target(ovmf + COMMENT "build ovmf ..." + # make 时编译 + ALL + WORKING_DIRECTORY ${ovmf_SOURCE_DIR} + COMMAND + ${CMAKE_COMMAND} + -E + copy + ${ovmf_SOURCE_DIR}/* + ${ovmf_BINARY_DIR} + ) + endif () + + # # https://github.com/tianocore/edk2 + # # @todo 下载下来的文件为 makefile 形式,需要自己编译 + # CPMAddPackage( + # NAME edk2 + # GIT_REPOSITORY https://github.com/tianocore/edk2.git + # GIT_TAG edk2-stable202305 + # DOWNLOAD_ONLY True + # ) +endif () + +# https://github.com/gdbinit/Gdbinit +CPMAddPackage( + NAME gdbinit + GIT_REPOSITORY https://github.com/gdbinit/Gdbinit.git + GIT_TAG e5138c24226bdd05360ca41743d8315a9e366c40 + DOWNLOAD_ONLY True +) +if (gdbinit_ADDED) + add_custom_target(gdbinit + COMMENT "Generate gdbinit ..." + WORKING_DIRECTORY ${gdbinit_SOURCE_DIR} + # 复制到根目录下并重命名 + COMMAND + ${CMAKE_COMMAND} + -E + copy + ${gdbinit_SOURCE_DIR}/gdbinit + ${CMAKE_SOURCE_DIR}/.gdbinit + COMMAND + echo "target remote ${QEMU_GDB_PORT}" >> ${CMAKE_SOURCE_DIR}/.gdbinit + COMMAND + echo "add-symbol-file ${${KERNEL_ELF_OUTPUT_NAME}_BINARY_DIR}/${KERNEL_ELF_OUTPUT_NAME}" >> ${CMAKE_SOURCE_DIR}/.gdbinit + COMMAND + echo "add-symbol-file ${${BOOT_ELF_OUTPUT_NAME}_BINARY_DIR}/${BOOT_ELF_OUTPUT_NAME}" >> ${CMAKE_SOURCE_DIR}/.gdbinit + ) +endif () + +# https://github.com/libcxxrt/libcxxrt +CPMAddPackage( + NAME libcxxrt + GIT_REPOSITORY https://github.com/libcxxrt/libcxxrt + GIT_TAG a0f7f5c139a7daf71de0de201b6c405d852b1dc1 +) +target_compile_options(cxxrt-static PRIVATE + -fPIC +) + +# https://github.com/cpm-cmake/CPMLicenses.cmake +# 保持在 CPMAddPackage 的最后 +CPMAddPackage( + NAME CPMLicenses.cmake + GITHUB_REPOSITORY cpm-cmake/CPMLicenses.cmake + VERSION 0.0.7 +) +if (CPMLicenses.cmake_ADDED) + cpm_licenses_create_disclaimer_target( + write-licenses "${CMAKE_CURRENT_SOURCE_DIR}/3rd/LICENSE" "${CPM_PACKAGES}" + ) +endif () +# make 时自动在 3rd 文件夹下生成 LICENSE 文件 +add_custom_target(3rd_licenses + ALL + COMMAND + make + write-licenses +) + +# qemu +find_program(QEMU_EXE qemu-system-${TARGET_ARCH}) +if (NOT QEMU_EXE) + message(FATAL_ERROR "qemu-system-${TARGET_ARCH} not found.\n" + "Following https://www.qemu.org/ to install.") +endif () + +# doxygen +find_package(Doxygen + REQUIRED dot) +if (NOT DOXYGEN_FOUND) + message(FATAL_ERROR "Doxygen not found.\n" + "Following https://www.doxygen.nl/index.html to install.") +endif () + +# cppcheck +find_program(CPPCHECK_EXE NAMES cppcheck) +if (NOT CPPCHECK_EXE) + message(FATAL_ERROR "cppcheck not found.\n" + "Following https://cppcheck.sourceforge.io to install.") +endif () +add_custom_target(cppcheck + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Run cppcheck on ${CMAKE_BINARY_DIR}/compile_commands.json ..." + COMMAND + ${CPPCHECK_EXE} + --enable=all + --project=${CMAKE_BINARY_DIR}/compile_commands.json + --suppress-xml=${CMAKE_SOURCE_DIR}/tools/cppcheck-suppressions.xml + --output-file=${CMAKE_BINARY_DIR}/cppcheck_report.log +) + +# 获取全部源文件 +file(GLOB_RECURSE ALL_SOURCE_FILES + ${CMAKE_SOURCE_DIR}/src/*.h + ${CMAKE_SOURCE_DIR}/src/*.hpp + ${CMAKE_SOURCE_DIR}/src/*.c + ${CMAKE_SOURCE_DIR}/src/*.cpp + ${CMAKE_SOURCE_DIR}/test/*.h + ${CMAKE_SOURCE_DIR}/test/*.hpp + ${CMAKE_SOURCE_DIR}/test/*.c + ${CMAKE_SOURCE_DIR}/test/*.cpp +) + +# clang-tidy +find_program(CLANG_TIDY_EXE NAMES clang-tidy) +if (NOT CLANG_TIDY_EXE) + message(FATAL_ERROR "clang-tidy not found.\n" + "Following https://clang.llvm.org/extra/clang-tidy to install.") +endif () +add_custom_target(clang-tidy + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Run clang-tidy on ${ALL_SOURCE_FILES} ..." + COMMAND + ${CLANG_TIDY_EXE} + --config-file=${CMAKE_SOURCE_DIR}/.clang-tidy + -p=${CMAKE_BINARY_DIR} + ${ALL_SOURCE_FILES} + > ${CMAKE_BINARY_DIR}/clang_tidy_report.log 2>&1 +) + +# clang-format +find_program(CLANG_FORMAT_EXE NAMES clang-format) +if (NOT CLANG_FORMAT_EXE) + message(FATAL_ERROR "clang-format not found.\n" + "Following https://clang.llvm.org/docs/ClangFormat.html to install.") +endif () +add_custom_target(clang-format + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Run clang-format on ${ALL_SOURCE_FILES} ..." + COMMAND ${CLANG_FORMAT_EXE} -i -style=file ${ALL_SOURCE_FILES} +) + +# genhtml 生成测试覆盖率报告网页 +find_program(GENHTML_EXE genhtml) +if (NOT GENHTML_EXE) + message(FATAL_ERROR "genhtml not found.\n" + "Following https://github.com/linux-test-project/lcov to install.") +endif () + +# lcov 生成测试覆盖率报告 +find_program(LCOV_EXE lcov) +if (NOT LCOV_EXE) + message(FATAL_ERROR "lcov not found.\n" + "Following https://github.com/linux-test-project/lcov to install.") +endif () diff --git a/cmake/add_header.cmake b/cmake/add_header.cmake new file mode 100644 index 0000000..b93c49a --- /dev/null +++ b/cmake/add_header.cmake @@ -0,0 +1,58 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# add_header.cmake for Simple-XX/SimpleRTOS. +# 将头文件路径添加到 _target 的搜索路径中 + +function (add_header_project _target) + target_include_directories(${_target} PRIVATE + ${CMAKE_SOURCE_DIR}/src) +endfunction () + +function (add_header_boot _target) + target_include_directories(${_target} PRIVATE + ${CMAKE_SOURCE_DIR}/src/boot/include) +endfunction () + +function (add_header_libc _target) + target_include_directories(${_target} PRIVATE + ${CMAKE_SOURCE_DIR}/src/kernel/libc/include) +endfunction () + +function (add_header_libcxx _target) + target_include_directories(${_target} PRIVATE + ${CMAKE_SOURCE_DIR}/src/kernel/libcxx/include) +endfunction () + +function (add_header_arch _target) + target_include_directories(${_target} PRIVATE + ${CMAKE_SOURCE_DIR}/src/kernel/arch/include) + target_include_directories(${_target} PRIVATE + ${CMAKE_SOURCE_DIR}/src/kernel/arch/${TARGET_ARCH}/include) +endfunction () + +function (add_header_kernel _target) + target_include_directories(${_target} PRIVATE + ${CMAKE_SOURCE_DIR}/src/kernel/include) +endfunction () + +function (add_header_driver _target) + target_include_directories(${_target} PRIVATE + ${CMAKE_SOURCE_DIR}/src/kernel/driver/include) +endfunction () + +function (add_header_3rd _target) + if (${TARGET_ARCH} STREQUAL "x86_64") + target_include_directories(${_target} PRIVATE + ${gnu-efi_BINARY_DIR}/inc) + target_include_directories(${_target} PRIVATE + ${gnu-efi_BINARY_DIR}/inc/${TARGET_ARCH}) + target_include_directories(${_target} PRIVATE + ${gnu-efi_BINARY_DIR}/inc/protocol) + elseif (${TARGET_ARCH} STREQUAL "riscv64") + target_include_directories(${_target} PRIVATE + ${opensbi_BINARY_DIR}/include) + elseif (${TARGET_ARCH} STREQUAL "aarch64") + endif () +endfunction () diff --git a/cmake/clang.cmake b/cmake/clang.cmake new file mode 100644 index 0000000..fd0c737 --- /dev/null +++ b/cmake/clang.cmake @@ -0,0 +1,44 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# clang.cmake for Simple-XX/SimpleRTOS. + +# 目标为无操作系统的环境 +set(CMAKE_SYSTEM_NAME Generic) +# 目标架构 +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +# @todo mac 测试 +if (APPLE) + message(STATUS "Now is Apple systems.") + # @todo +elseif (UNIX) + message(STATUS "Now is UNIX-like OS's.") + # clang + find_program(Compiler_clang++ clang++) + if (NOT Compiler_clang++) + message(FATAL_ERROR "clang++ not found.\n" + "Run `sudo apt-get install -y clang clang++` to install.") + else () + message(STATUS "Found clang++ ${Compiler_clang++}") + endif () + + set(CMAKE_C_COMPILER clang) + set(CMAKE_CXX_COMPILER clang++) + set(CMAKE_READELF readelf) + set(CMAKE_AR ar) + set(CMAKE_LINKER ld) + set(CMAKE_NM nm) + set(CMAKE_OBJDUMP objdump) + set(CMAKE_RANLIB ranlib) + + # qemu + find_program(QEMU qemu-system-x86_64) + if (NOT QEMU) + message(FATAL_ERROR "qemu not found.\n" + "Run `sudo apt-get install -y qemu-system` to install.") + else () + message(STATUS "Found qemu ${QEMU}") + endif () +endif () diff --git a/cmake/compile_config.cmake b/cmake/compile_config.cmake new file mode 100644 index 0000000..02c0f18 --- /dev/null +++ b/cmake/compile_config.cmake @@ -0,0 +1,174 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# compile_config.cmake for Simple-XX/SimpleRTOS. +# 配置信息 + +# 通用编译选项 +list(APPEND COMMON_COMPILE_OPTIONS + # 如果 CMAKE_BUILD_TYPE 为 Release 则使用 -O3 -Werror,否则使用 -O0 -g -ggdb + $<$:-O3;-Werror> + $<$:-O0;-g;-ggdb> + # 打开全部警告 + -Wall + # 打开额外警告 + -Wextra + # 启用异常处理机制 + -fexceptions + + # 目标平台编译选项 + # @todo clang 交叉编译参数 + $<$: + # 禁用 red-zone + -mno-red-zone + > + + $<$: + > + + $<$: + # 生成 armv8-a 代码 + -march=armv8-a + # 针对 cortex-a72 优化代码 + -mtune=cortex-a72 + > + + # gcc 特定选项 + $<$: + > + + # clang 特定选项 + $<$: + > + + # 平台相关 + $<$: + > +) + +list(APPEND DEFAULT_BOOT_COMPILE_OPTIONS + ${COMMON_COMPILE_OPTIONS} + # 使用 2 字节 wchar_t + -fshort-wchar + # 允许 wchar_t + -fpermissive + # 生成位置无关代码 + -fPIC + + # 目标平台编译选项 + $<$: + # 使 gnu-efi + -DGNU_EFI_USE_MS_ABI + > + + $<$: + # 使 gnu-efi + -DGNU_EFI_USE_MS_ABI + > +) + +list(APPEND DEFAULT_KERNEL_COMPILE_OPTIONS + ${COMMON_COMPILE_OPTIONS} +) + +# 通用链接选项 +list(APPEND COMMON_LINK_OPTIONS + # 不链接 ctr0 等启动代码 + -nostartfiles + + # 目标平台编译选项 + # @todo clang 交叉编译参数 + $<$: + # 设置最大页大小为 0x1000(4096) 字节 + -z max-page-size=0x1000 + > + + $<$: + # 链接脚本 + -T ${CMAKE_SOURCE_DIR}/src/kernel/arch/${TARGET_ARCH}/link.ld + # 不生成位置无关可执行代码 + -no-pie + > + + $<$: + > +) + +list(APPEND DEFAULT_BOOT_LINK_OPTIONS + ${COMMON_LINK_OPTIONS} + + # 目标平台编译选项 + $<$: + # 编译为共享库 + -shared + # 符号级别绑定 + -Wl,-Bsymbolic + > +) + +list(APPEND DEFAULT_KERNEL_LINK_OPTIONS + ${COMMON_LINK_OPTIONS} + + $<$: + # 链接脚本 + -T ${CMAKE_SOURCE_DIR}/src/kernel/arch/${TARGET_ARCH}/link.ld + # 不生成位置无关可执行代码 + -no-pie + > +) + +# 通用库选项 +list(APPEND COMMON_LINK_LIB + ${libcxxrt_BINARY_DIR}/lib/libcxxrt.a + # 目标平台编译选项 + $<$: + > + + $<$: + > + + $<$: + > +) + +list(APPEND DEFAULT_BOOT_LINK_LIB + ${COMMON_LINK_LIB} + # 目标平台编译选项 + $<$: + # 链接 gnu-efi + # ${gnu-efi_BINARY_DIR}/gnuefi/reloc_${TARGET_ARCH}.o + ${gnu-efi_BINARY_DIR}/gnuefi/crt0-efi-${TARGET_ARCH}.o + ${gnu-efi_BINARY_DIR}/gnuefi/libgnuefi.a + ${gnu-efi_BINARY_DIR}/lib/libefi.a + > + + $<$: + # 链接 gnu-efi + # ${gnu-efi_BINARY_DIR}/gnuefi/reloc_${TARGET_ARCH}.o + ${gnu-efi_BINARY_DIR}/gnuefi/crt0-efi-${TARGET_ARCH}.o + ${gnu-efi_BINARY_DIR}/gnuefi/libgnuefi.a + ${gnu-efi_BINARY_DIR}/lib/libefi.a + > +) + +list(APPEND DEFAULT_KERNEL_LINK_LIB + ${COMMON_LINK_LIB} +) + +# 编译依赖 +if (${TARGET_ARCH} STREQUAL "x86_64") + list(APPEND COMPILE_DEPENDS + gnu-efi + cxxrt-static + ) +elseif (${TARGET_ARCH} STREQUAL "riscv64") + list(APPEND COMPILE_DEPENDS + opensbi + cxxrt-static + ) +elseif (${TARGET_ARCH} STREQUAL "aarch64") + list(APPEND COMPILE_DEPENDS + gnu-efi + ) +endif () diff --git a/cmake/functions.cmake b/cmake/functions.cmake new file mode 100644 index 0000000..64f1dce --- /dev/null +++ b/cmake/functions.cmake @@ -0,0 +1,154 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# functions.cmake for Simple-XX/SimpleRTOS. +# 辅助函数 + +# 生成 target 输出文件的 readelf -a +# _target: target 名 +# 在 ${${_target}_BINARY_DIR} 目录下生成 $.readelf 文件 +function (readelf_a _target) + add_custom_command(TARGET ${_target} + COMMENT "readelf -a $ ..." + POST_BUILD + DEPENDS ${_target} + WORKING_DIRECTORY ${${_target}_BINARY_DIR} + COMMAND ${CMAKE_READELF} -a $ > $.readelf || (exit 0) + ) +endfunction () + +# 生成 target 输出文件的 objdump -D +# _target: target 名 +# 在 ${${_target}_BINARY_DIR} 目录下生成 $.disassembly 文件 +function (objdump_D _target) + add_custom_command(TARGET ${_target} + COMMENT "objdump -D $ ..." + POST_BUILD + DEPENDS ${_target} + WORKING_DIRECTORY ${${_target}_BINARY_DIR} + COMMAND ${CMAKE_OBJDUMP} -D $ > $.disassembly + ) +endfunction () + +# 将 elf 转换为 efi +# _elf: 要转换的 target 名 +# _efi: 输出的 efi 文件名 +# 在 ${${_target}_BINARY_DIR} 目录下生成 ${_efi} 文件 +function (elf2efi _target _efi) + add_custom_command(TARGET ${_target} + COMMENT "Convert $ to efi ..." + POST_BUILD + DEPENDS ${_target} + WORKING_DIRECTORY ${${_target}_BINARY_DIR} + COMMAND ${CMAKE_OBJCOPY} $ ${_efi} + -S + -R .comment + -R .note.gnu.build-id + -R .gnu.hash + -R .dynsym + --target=efi-app-${TARGET_ARCH} --subsystem=10 + ) +endfunction () + +# 添加测试覆盖率 target +# DEPENDS 要生成的 targets +# SOURCE_DIR 源码路径 +# BINARY_DIR 二进制文件路径 +# EXCLUDE_DIR 要排除的目录 +function (add_coverage_target) + # 解析参数 + set(options) + set(one_value_keywords SOURCE_DIR BINARY_DIR) + set(multi_value_keywords DEPENDS EXCLUDE_DIR) + cmake_parse_arguments( + ARG "${options}" "${one_value_keywords}" "${multi_value_keywords}" ${ARGN} + ) + + # 不检查的目录 + list(APPEND EXCLUDES --exclude) + foreach (_item ${ARG_EXCLUDE_DIR}) + list(APPEND EXCLUDES '${_item}') + endforeach () + + # 添加 target + add_custom_target(coverage DEPENDS ${ARG_DEPENDS} + COMMAND ${CMAKE_CTEST_COMMAND} + ) + # 在 coverage 执行完毕后生成报告 + add_custom_command(TARGET coverage + COMMENT "Generating coverage report ..." + POST_BUILD + WORKING_DIRECTORY ${ARG_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_OUTPUT_DIR} + COMMAND ${LCOV_EXE} + -c + -o ${COVERAGE_OUTPUT_DIR}/coverage.info + -d ${ARG_BINARY_DIR} + -b ${ARG_SOURCE_DIR} + --no-external + ${EXCLUDES} + --rc lcov_branch_coverage=1 + COMMAND ${GENHTML_EXE} + ${COVERAGE_OUTPUT_DIR}/coverage.info + -o ${COVERAGE_OUTPUT_DIR} + --branch-coverage + ) +endfunction () + +# 添加运行 qemu target +# NAME 生成的 target 前缀 +# TARGET 目标架构 +# WORKING_DIRECTORY 工作目录 +# BOOT boot 文件路径 +# KERNEL kernel 文件路径 +# DEPENDS 依赖的 target +# QEMU_FLAGS qemu 参数 +function (add_run_target) + # 解析参数 + set(options) + set(one_value_keywords NAME TARGET WORKING_DIRECTORY BOOT KERNEL) + set(multi_value_keywords DEPENDS QEMU_FLAGS) + cmake_parse_arguments( + ARG "${options}" "${one_value_keywords}" "${multi_value_keywords}" ${ARGN} + ) + + list(APPEND commands + COMMAND ${CMAKE_COMMAND} -E copy ${ARG_KERNEL} image/ + ) + if (${ARG_TARGET} STREQUAL "x86_64") + get_filename_component(BOOT_FILE_NAME ${ARG_BOOT} NAME) + configure_file(${CMAKE_SOURCE_DIR}/tools/startup.nsh.in image/startup.nsh @ONLY) + list(APPEND commands + COMMAND ${CMAKE_COMMAND} -E copy ${ARG_BOOT} image/ + ) + elseif (${ARG_TARGET} STREQUAL "aarch64") + get_filename_component(BOOT_FILE_NAME ${ARG_BOOT} NAME) + configure_file(${CMAKE_SOURCE_DIR}/tools/startup.nsh.in image/startup.nsh @ONLY) + list(APPEND commands + COMMAND ${CMAKE_COMMAND} -E copy ${ARG_BOOT} image/ + ) + endif () + + # 添加 target + add_custom_target(${ARG_NAME}_run DEPENDS ${ARG_DEPENDS} + WORKING_DIRECTORY ${ARG_WORKING_DIRECTORY} + COMMAND ${CMAKE_COMMAND} -E make_directory image/ + ${commands} + COMMAND + qemu-system-${ARG_TARGET} + ${ARG_QEMU_FLAGS} + ) + add_custom_target(${ARG_NAME}_debug DEPENDS ${ARG_DEPENDS} + WORKING_DIRECTORY ${ARG_WORKING_DIRECTORY} + COMMAND ${CMAKE_COMMAND} -E make_directory image/ + ${commands} + COMMAND + qemu-system-${ARG_TARGET} + ${ARG_QEMU_FLAGS} + # 等待 gdb 连接 + -S + # 使用 1234 端口 + -gdb ${QEMU_GDB_PORT} + ) +endfunction () \ No newline at end of file diff --git a/cmake/project_config.cmake b/cmake/project_config.cmake new file mode 100644 index 0000000..20c7f94 --- /dev/null +++ b/cmake/project_config.cmake @@ -0,0 +1,91 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# project_config.cmake for Simple-XX/SimpleRTOS. +# 配置信息 + +# 设置 cmake 目标环境根目录 +# @todo 设置目录 +list(APPEND CMAKE_FIND_ROOT_PATH + /usr/x86_64-linux-gnu + /usr/riscv64-linux-gnu + /usr/aarch64-linux-gnu +) +# 在目标环境搜索 program +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# 在目标环境搜索库文件 +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +# 在目标环境搜索头文件 +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# 设置清理目标 在 make clean 时删除文件夹 +set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES + # 删除 .gdbinit + ${CMAKE_SOURCE_DIR}/.gdbinit +) + +# 要运行的平台 +list(APPEND VALID_PLATFORM qemu) +if (NOT DEFINED PLATFORM) + set(PLATFORM qemu) +endif () +message(STATUS "PLATFORM is: ${PLATFORM}") +# 如果不合法则报错 +if (NOT PLATFORM IN_LIST VALID_PLATFORM) + message(FATAL_ERROR "PLATFORM must be one of ${VALID_PLATFORM}") +endif () + +# 目标架构 +list(APPEND VALID_TARGET_ARCH x86_64 riscv64 aarch64) +# 默认构建 x86_64 +if (NOT DEFINED TARGET_ARCH) + set(TARGET_ARCH x86_64) +endif () +message(STATUS "TARGET_ARCH is: ${TARGET_ARCH}") +# 如果不合法则报错 +if (NOT TARGET_ARCH IN_LIST VALID_TARGET_ARCH) + message(FATAL_ERROR "TARGET_ARCH must be one of ${VALID_TARGET_ARCH}") +endif () + +message(STATUS "CMAKE_TOOLCHAIN_FILE is: ${CMAKE_TOOLCHAIN_FILE}") +# 编译器只支持 gnu-gcc 或 clang +if (NOT ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) + message(FATAL_ERROR "Only support gnu-gcc/clang") +endif () + +# qemu 运行依赖 +if (${TARGET_ARCH} STREQUAL "x86_64") + list(APPEND RUN_DEPENDS + ovmf + ) +elseif (${TARGET_ARCH} STREQUAL "riscv64") + list(APPEND RUN_DEPENDS + opensbi + ) +elseif (${TARGET_ARCH} STREQUAL "aarch64") + list(APPEND RUN_DEPENDS + ovmf + ) +endif () + +# qemu 调试依赖 +list(APPEND DEBUG_DEPENDS + ${RUN_DEPENDS} + gdbinit +) + +# qemu gdb 调试端口 +if (NOT DEFINED QEMU_GDB_PORT) + set(QEMU_GDB_PORT tcp::1234) +endif () + +# qemu monitor 参数 +if (NOT DEFINED QEMU_MONITOR_ARG) + set(QEMU_MONITOR_ARG + telnet::2333,server,nowait + ) +endif () + +# 生成项目配置头文件,传递给代码 +configure_file(${CMAKE_SOURCE_DIR}/tools/project_config.h.in ${CMAKE_SOURCE_DIR}/src/project_config.h @ONLY) diff --git a/cmake/x86_64-riscv64-gcc.cmake b/cmake/x86_64-riscv64-gcc.cmake new file mode 100644 index 0000000..9a56264 --- /dev/null +++ b/cmake/x86_64-riscv64-gcc.cmake @@ -0,0 +1,53 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# x86_64-riscv64-gcc.cmake for Simple-XX/SimpleRTOS. + +# 目标为无操作系统的环境 +set(CMAKE_SYSTEM_NAME Generic) +# 目标架构 +set(CMAKE_SYSTEM_PROCESSOR riscv64) + +# @todo mac 测试 +if (APPLE) + message(STATUS "Now is Apple systens.") + # GCC + find_program(Compiler_gcc riscv64-unknown-elf-g++) + if (NOT Compiler_gcc) + message(FATAL_ERROR "riscv64-unknown-elf-g++ not found.\n" + "Following https://github.com/riscv-software-src/homebrew-riscv to install.") + else () + message(STATUS "Found riscv64-unknown-elf-g++ ${Compiler_gcc}") + endif () + + set(TOOLCHAIN_PREFIX riscv64-unknown-elf-) + set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) + set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) + set(CMAKE_READELF ${TOOLCHAIN_PREFIX}readelf) + set(CMAKE_AR ${TOOLCHAIN_PREFIX}ar) + set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}ld) + set(CMAKE_NM ${TOOLCHAIN_PREFIX}nm) + set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump) + set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}ranlib) +elseif (UNIX) + message(STATUS "Now is UNIX-like OS's.") + # GCC + find_program(Compiler_gcc riscv64-linux-gnu-g++) + if (NOT Compiler_gcc) + message(FATAL_ERROR "riscv64-linux-gnu-g++ not found.\n" + "Run `sudo apt install -y gcc-riscv64-linux-gnu g++-riscv64-linux-gnu` to install.") + else () + message(STATUS "Found riscv64-linux-gnu-g++ ${Compiler_gcc}") + endif () + + set(TOOLCHAIN_PREFIX riscv64-linux-gnu-) + set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) + set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) + set(CMAKE_READELF ${TOOLCHAIN_PREFIX}readelf) + set(CMAKE_AR ${TOOLCHAIN_PREFIX}ar) + set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}ld) + set(CMAKE_NM ${TOOLCHAIN_PREFIX}nm) + set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump) + set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}ranlib) +endif () diff --git a/cmake/x86_64-x86_64-gcc.cmake b/cmake/x86_64-x86_64-gcc.cmake new file mode 100644 index 0000000..03ccd19 --- /dev/null +++ b/cmake/x86_64-x86_64-gcc.cmake @@ -0,0 +1,47 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# x86_64-x86_64-gcc.cmake for Simple-XX/SimpleRTOS. + +# 目标为无操作系统的环境 +set(CMAKE_SYSTEM_NAME Generic) +# 目标架构 +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +# @todo mac 测试 +if (APPLE) + message(STATUS "Now is Apple system.") + # GCC + find_program(Compiler_gcc x86_64-elf-g++) + if (NOT Compiler_gcc) + message(FATAL_ERROR "x86_64-elf-g++ not found.\n" + "Run `brew install x86_64-elf-g++` to install.") + else () + message(STATUS "Found x86_64-elf-g++ ${Compiler_gcc}") + endif () + + set(TOOLCHAIN_PREFIX x86_64-elf-) + set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) + set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) + set(CMAKE_READELF ${TOOLCHAIN_PREFIX}readelf) + set(CMAKE_AR ${TOOLCHAIN_PREFIX}ar) + set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}ld) + set(CMAKE_NM ${TOOLCHAIN_PREFIX}nm) + set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump) + set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}ranlib) + + # 跳过编译器检查 + set(CMAKE_C_COMPILER_FORCED TRUE) + set(CMAKE_CXX_COMPILER_FORCED TRUE) +elseif (UNIX) + message(STATUS "Now is UNIX-like OS's.") + # GCC + find_program(Compiler_gcc g++) + if (NOT Compiler_gcc) + message(FATAL_ERROR "g++ not found.\n" + "Run `sudo apt-get install -y gcc g++` to install.") + else () + message(STATUS "Found g++ ${Compiler_gcc}") + endif () +endif () diff --git "a/doc/0_\345\267\245\345\205\267\351\223\276.md" "b/doc/0_\345\267\245\345\205\267\351\223\276.md" new file mode 100644 index 0000000..8935065 --- /dev/null +++ "b/doc/0_\345\267\245\345\205\267\351\223\276.md" @@ -0,0 +1,120 @@ +# SimpleRTOS 工具链 + +SimpleRTOS 为了保证在各个平台上的可用性,选择了较为通用的工具链,主要分为三个部分 + +1. 构建系统 + + 使用 CMake 对代码进行管理,同时控制编译选项 + +2. 内核的编译 + + 使用 GCC 工具链 + +3. 模拟器 + + 对于 x86/x86_64 架构,支持 bochs 与 qemu + + arm/aarch64/riscv64 架构,使用 qemu + +4. 辅助脚本 + + 主要用于环境变量管理,如 `./run.sh` 是用来编译并运行内核,`./tools/env.sh` 则规定了需要的参数。 + + 此外还有模拟器配置,如 `./bochsrc_linux.txt` + +## CMake + +CMake 可以分为两个部分 + +1. 主要 cmake 规则 + + 所有 CMakeLists.txt 文件,规定了内核的编译方式。 + + - ./CMakeLists.txt + + 设置了一些 CMake 选项,并在最后通过 `add_subdirectory(${${SimpleRTOS_SOURCE_DIR}/src})` 将控制权转移到 ./src/CMakeLists.txt + + - ./src/CMakeLists.txt + + 规定了 gcc 的编译选项,指定生成的二进制文件名称,并规定生成二进制文件所需的模块 + + - ./src/*/CMakeLists.txt + + 各个模块的编译规则 + +2. 辅助 cmake 规则 + + 用于辅助主要规则,保存在 ./cmake 目录下 + + - toolchain_*.cmake 用于判断依赖是否已安装 + - header_files.cmake 用于添加头文件 + - find_asm_files.cmake 用于将汇编文件添加到编译列表 + - arch_detector.cmake 用于判断目标架构 + +更多细节请查看注释。 + +项目地址:[CMake](https://cmake.org) + +## GCC + +GCC 需要根据目标平台与宿主机进行配置,即 target 与 host。 + +一般而言,网上有编译好的可以直接拿来用。 + +以 target=riscv64,host=osx 为例,可以在 `https://github.com/riscv/homebrew-riscv` 找到现成的,只需要按照说明安装即可。 + +对于特殊情况,可能需要自己手动编译 gcc,大致步骤如下[^1]: + +1. 安装依赖 +2. 下载源码 +3. 配置 +4. 编译 + +其中比较重要的地方是第三步,需要根据需要进行配置,你可以参考 ./tools/x86_64-elf-gcc.sh 的内容进行编译。 + +项目地址:[GCC, the GNU Compiler Collection - GNU Project](https://gcc.gnu.org) + +## bochs + +bochs 是专门用于 x86/x86_64 的虚拟机。 + +./tools/bochsrc_*.txt 规定了虚拟机的配置选项 + +./tools/bochsinit 规定在虚拟机启动后执行的命令 + +项目地址:[bochs: The Open Source IA-32 Emulation Project (Home Page)](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwibsOK5v5b4AhUFD0QIHTX-BS4QFnoECBMQAQ&url=https%3A%2F%2Fbochs.sourceforge.io%2F&usg=AOvVaw22vn_4SPHPDYUk_NoYgyP2) + +更多细节请查看注释 + +## qemu + +qemu 是支持范围更大的虚拟机,支持多种架构。 + +安装: + +项目地址:[QEMU](https://www.qemu.org) + +## 辅助脚本 + +- ./tools/env.sh + + 设置目标架构,并根据设置的目标架构初始化相关变量。 + + 更多细节请查看注释。 + +- ./run.sh + + 根据 tools/env.sh 的设置在虚拟机中运行内核。 + + 更多细节请查看注释。 + + +## 相关文档 + +关于交叉编译的一些说明:https://wiki.osdev.org/GCC_Cross-Compiler + +arm 工具链:https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads + +riscv 工具链:https://github.com/riscv/riscv-gnu-toolchain + +[^1]: https://gcc.gnu.org/install/ diff --git "a/doc/1_\347\263\273\347\273\237\345\220\257\345\212\250.md" "b/doc/1_\347\263\273\347\273\237\345\220\257\345\212\250.md" new file mode 100644 index 0000000..2e2b3b4 --- /dev/null +++ "b/doc/1_\347\263\273\347\273\237\345\220\257\345\212\250.md" @@ -0,0 +1,92 @@ +# SimpleRTOS 启动 + +内核实际上也是一个程序,它从链接脚本规定的入口点(`ENTRY(_start)`)开始执行,但在这一步之前,还得让硬件知道 `_start` 的位置,这一步骤 SimpleRTOS 使用了一些开源的引导程序来辅助这一过程,你可以在 osdev 看看具体的流程[^1],这里不再赘述。 + +## IA32 + +IA32 包括 i386(或 x86) 与 x86_64,它们在细节上有部分区别。 + +SimpleRTOS 使用 grub2 进行辅助,跳过与机器打交道的部分,由 grub2 进行最最开始的设置,我们只需要处理从 `_start` 开始的代码即可。 + +相比其它架构,IA32 有太多历史包袱,这导致它的启动过程比较麻烦,尤其是实模式(16bit),保护模式(32bit),以及长模式(64bit)的切换十分复杂。幸运的是,grub2 已经帮我们进入了保护模式,这使得我们可以暂时跳过相关模式的设置。 + +- grub2[^2] + + 一个引导程序,在 linux 中有广泛的应用,这里只使用了它最基础的功能。 + +- multiboot2[^3] + + 这是一个引导标准,一般用于 pc 的启动,任何符合 multiboot2 标准的内核都可以通过支持 multiboot2 标准的引导程序启动。 + + 这个标准在内核中的表现为 ia32/*/boot.S 中的 + + ```assembly + // 声明这一段代码以 32 位模式编译 + .code32 + + // multiboot2 文件头 + // 计算头长度 + .SET HEADER_LENGTH, multiboot_header_end - multiboot_header + // 计算校验和 + .SET CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + HEADER_LENGTH) + // 8 字节对齐 + .align MULTIBOOT_HEADER_ALIGN + // 声明所属段 + .section .multiboot_header + multiboot_header: + // 魔数 + .long MULTIBOOT2_HEADER_MAGIC + // 架构 + .long MULTIBOOT_ARCHITECTURE_I386 + // 头长度 + .long HEADER_LENGTH + // 校验和 + .long CHECKSUM + // 添加其它内容在此,详细信息见 Multiboot2 Specification version 2.0.pdf + .short MULTIBOOT_HEADER_TAG_END + // 结束标记 + .short 0 + .long 8 + multiboot_header_end: + ``` + + 只要在内核开始部分检测到符合 multiboot2 规定的数据,就认为这是一个符合规范的内核,引导程序会在对硬件进行初始化后将控制权交给 `_start` + +- x86 + + 由于 grub 已经进入了保护模式,我们不需要做什么多余的事情,在设置栈指针后直接进入 C 函数 `kernel_main` 执行即可。 + + - 执行流 + + 模拟器 -> grub2 -> _start(boot.S ) -> kernel_main(kernel_main.cpp) + +- x86_64 + + TODO + +更多细节请查看注释。 + +## RISCV + +riscv 相较 IA32 非常新,其标准至今还在更新,它没有 IA32 那么多的遗留问题与设计冗余,所以简单不少。 + +引导程序使用了 opensbi,与 grub 类似,opensbi 将硬件设置为 S 态后跳转到我们的代码中,但相比 ia32/grub 的繁琐,riscv/opensbi 更为精炼。 + +- opensbi[^4] + + 在 riscv 设备启动时,会进入 M(Machine) 态,这是 riscv 架构中权限最高的一级,可以操作所有硬件资源,opensbi 会在这一级进行一些设置,然后切换到 S(Supervisor) 态执行内核代码,S 态可以访问到的资源是 M 态的子集。 + +同样,在设置栈地址后跳转到 `kernel_main` 执行。 + +- 执行流 + + 模拟器 -> opensbi -> _start(boot.S) -> kernel_main(kernel_main.cpp) + +更多细节请查看注释。 + +## 相关文档 + +[^1]: https://wiki.osdev.org/Bare_Bones +[^2]: https://www.gnu.org/software/grub/manual/grub/grub.html +[^3]: https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html +[^4]: https://github.com/riscv/opensbi diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000..1ddc7de --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,45 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# CMakeLists.txt for Simple-XX/SimpleRTOS. + +# 设置项目名与版本 +project( + doc + VERSION 0.0.1 +) + +# 设置 doxygen 相关参数 +set(DOXYGEN_HAVE_DOT YES) +set(DOXYGEN_DOT_MULTI_TARGETS YES) +set(DOXYGEN_GENERATE_LATEX NO) +set(DOXYGEN_PROJECT_NAME ${CMAKE_PROJECT_NAME}) +set(DOXYGEN_PROJECT_NUMBER ${CMAKE_PROJECT_VERSION}) +set(DOXYGEN_PROJECT_BRIEF ${PROJECT_DESCRIPTION}) +set(DOXYGEN_RECURSIVE YES) +set(DOXYGEN_EXCLUDE_PATTERNS */3rd/*, */.vscode/*, */.idea/*, */.github/*, */.git/*, */build*/*, */cmake-/*) +set(DOXYGEN_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}) +set(DOXYGEN_EXTRACT_ALL YES) +set(DOXYGEN_EXTRACT_PRIVATE YES) +set(DOXYGEN_EXTRACT_STATIC YES) +set(DOXYGEN_EXTRACT_LOCAL_CLASSES YES) +set(DOXYGEN_SOURCE_BROWSER YES) +set(DOXYGEN_INLINE_SOURCES YES) +set(DOXYGEN_ALPHABETICAL_INDEX YES) +set(DOXYGEN_GENERATE_TREEVIEW YES) +set(DOXYGEN_ENABLE_PREPROCESSING YES) +set(DOXYGEN_CLASS_DIAGRAMS YES) +set(DOXYGEN_CLASS_GRAPH YES) +set(DOXYGEN_GRAPHICAL_HIERARCHY YES) +set(DOXYGEN_CALLER_GRAPH YES) +set(DOXYGEN_CALL_GRAPH YES) +set(DOXYGEN_UML_LOOK YES) +set(DOXYGEN_HTML_TIMESTAMP YES) + +# 创建 target 并通过 VERBATIM 将 cmake 参数传递给 doxygen +doxygen_add_docs(doc + COMMENT "Generating docs at ${PROJECT_SOURCE_DIR}/html/index.html ..." + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR} +) diff --git a/doc/build_system.md b/doc/build_system.md new file mode 100644 index 0000000..dbb29dc --- /dev/null +++ b/doc/build_system.md @@ -0,0 +1,117 @@ +# 构建系统 + +## 目录及文件介绍 + +```shell +. +├── 3rd // 第三方源文件 +├── CMakeLists.txt // 最上层 cmake +├── CMakePresets.json // 预定义的 cmake 配置 +├── Dockerfile // docker 配置 +├── LICENSE // MIT 与 ANTI996 +├── README.md // README +├── build_riscv64 // riscv64 架构的构建目录 +├── build_x86_64 // x86_64 架构的构建目录 +├── cmake // cmake 模块目录 +│ ├── 3rd.cmake // 管理第三方资源 +│ ├── add_header.cmake // 为 target 添加头文件 +│ ├── clang.cmake // clang 工具链配置 +│ ├── compile_config.cmake // 编译选项 +│ ├── functions.cmake // 辅助函数 +│ ├── project_config.cmake // 项目配置 +│ ├── x86_64-riscv64-gcc.cmake // host 为 x86_64,target 为 riscv64 的工具链 +│ └── x86_64-x86_64-gcc.cmake // host 为 x86_64,target 为 x86_64 的工具链 +├── doc // 文档目录 +│ ├── CMakeLists.txt // 生成 doxygen 文档 +│ ├── UEFI_Spec_2_10_Aug29.pdf // UEFI 协议文档 +│ ├── build.md // 本文件 +│ └── docker.md // docker 使用方法 +├── run.sh // 一键运行脚本 +├── src // 代码目录 +│ ├── CMakeLists.txt // +│ ├── boot // 引导程序目录 +│ │ ├── CMakeLists.txt // +│ │ ├── boot.cpp // +│ │ ├── graphics.cpp // +│ │ ├── include // +│ │ │ ├── boot.h // +│ │ │ ├── load_elf.h // +│ │ │ └── ostream.hpp // +│ │ ├── load_elf.cpp // +│ │ ├── memory.cpp // +│ │ └── ostream.cpp // +│ └── kernel // 内核目录 +│ ├── CMakeLists.txt // +│ ├── arch // 架构相关代码 +│ │ ├── CMakeLists.txt // +│ │ ├── aarch64 // +│ │ │ └── arch.cpp // +│ │ ├── arch.cpp // +│ │ ├── include // +│ │ │ └── arch.h // +│ │ ├── riscv64 // +│ │ │ ├── arch.cpp // +│ │ │ ├── boot.S // +│ │ │ └── link.ld // 链接脚本 +│ │ └── x86_64 // +│ │ └── arch.cpp // +│ ├── driver // 驱动目录 +│ │ ├── CMakeLists.txt // +│ │ ├── driver.cpp // +│ │ └── include // +│ │ └── driver.h // +│ ├── include // 内核头文件目录 +│ │ └── kernel.h // +│ ├── libc // libc 目录 +│ │ ├── CMakeLists.txt // +│ │ ├── include // +│ │ │ └── libc.h // +│ │ └── libc.c // +│ ├── libcxx // libcxx 目录 +│ │ ├── CMakeLists.txt // +│ │ ├── include // +│ │ │ └── libcxx.h // +│ │ └── libcxx.cpp // +│ └── main.cpp // 内核入口 +├── test // 测试目录 +│ ├── CMakeLists.txt // +│ ├── integration_test // 集成测试 +│ │ ├── CMakeLists.txt // +│ │ └── example.cpp // +│ ├── system_test // 系统测试 +│ │ ├── CMakeLists.txt // +│ │ ├── gnu_efi_test // 测试 gnu-efi +│ │ │ ├── CMakeLists.txt // +│ │ │ ├── README.md // +│ │ │ ├── boot.cpp // +│ │ │ └── main.cpp // +│ │ └── opensbi_test // 测试 opensbi +│ │ ├── CMakeLists.txt // +│ │ └── boot.cpp // +│ └── unit_test // 单元测试 +│ ├── CMakeLists.txt // +│ └── example.cpp // +└── tools // 其它工具 + ├── cppcheck-suppressions.xml // cppcheck 配置文件 + ├── ovmf // ovmf 文件目录 + │ └── OVMF_x86_64.fd // + └── startup.nsh.in // uefi 初始化配置输入文件 +``` + +每个子模块都有自己的 cmake 文件,上级 cmake 通过 add_subdirectory 将其引入,同时传递由 config.cmake 设置的变量。 + +所有内核相关代码都在 src 目录下,其中 + +1. boot 是引导程序,在生成时为一个独立的 elf 文件。 +2. arch 目录下存放了体系结构相关的代码,在有涉及到体系结构内容时应当将实现放在这里,向外提供统接口。 +3. driver 目录下是设备驱动。在内核开发初期,可以将驱动代码与内核一起编译,在后期应当提供独立文件。 +4. kernel 目录是内核的核心逻辑,内存管理、任务管理等。 +5. libc 与 libcxx 是 c/c++ 库的位置,提供内核可用的相关接口。 + +## 命名规范 + +- 系统测试 + + 以测试内容为名称的文件夹。 + + cmake project 名为 xxx-test,如 gnu-efi-test。 diff --git a/doc/docker.md b/doc/docker.md new file mode 100644 index 0000000..e905d2e --- /dev/null +++ b/doc/docker.md @@ -0,0 +1,66 @@ + +# 构建 Docker 并通过 ssh 使用 + +## 构建 Docker image + +构建 image + +``` +cd SimpleRTOS +docker build -t SimpleRTOS-docker . +``` + +## 启动容器,并配置 ssh + +运行以下命令启动容器: + +``` +docker run --name SimpleRTOS-container -itd -p 233:22 -v ./:/home/zone/SimpleRTOS SimpleRTOS-docker +``` + +进入 docker container ubuntu 命令行环境 + +``` +docker exec -it SimpleRTOS-container /bin/zsh +``` + +## 配置 ssh + +在本地创建 RSA Key: + +``` +# 检查是否已经存在 RSA key: +ls ~/.ssh +# 如果已经存在 id_rsa.pub 则忽略后续步骤,否则继续 +# 将 替换为你想要的任意字符串 +ssh-keygen -t rsa -b 2048 -C "" +``` + +运行 `cat ~/.ssh/id_rsa.pub`, 然后复制内容。 + +回到容器中 + +- 默认用户 `zone`:`zone` + +``` +ssh -p 233 zone@localhost +# 输入密码 +``` + +创建 `/home/zone/.ssh/authorized_keys`,并粘贴。 + +ssh 登录 ubuntu: + +``` +ssh -p 233 zone@localhost +``` + +此时应该能够直接登录,不再需要输入密码 + +## 配置 vscode + +* 安装`Remote - SSH` 插件 +* 打开Command Palette: CMD+Shift+P +* 输入`Remote-SSH: Add New SSH Host...` +* 输入SSH命令: `ssh -p 233 zone@localhost` +* 登录成功后,在打开的窗口中打开文件夹。 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..eaf5c8b --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,48 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# CMakeLists.txt for Simple-XX/SimpleRTOS. + +# 设置项目名与版本 +project( + test + VERSION 0.0.1 +) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/system_test) + +# 仅在 host 环境下进行 ut 和 it +if (TARGET_ARCH STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR) + enable_testing() + include(GoogleTest) + + list(APPEND DEFAULT_TEST_COMPILE_OPTIONS + --coverage + ) + + list(APPEND DEFAULT_TEST_LINK_OPTIONS + --coverage + -fsanitize=leak + -fsanitize=address + -fno-omit-frame-pointer + ) + + list(APPEND DEFAULT_TEST_LINK_LIB + arch + driver + libc + libcxx + gtest_main + ) + + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/unit_test) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/integration_test) + + add_coverage_target( + DEPENDS unit_test integration_test + SOURCE_DIR ${CMAKE_SOURCE_DIR} + BINARY_DIR ${CMAKE_BINARY_DIR} + EXCLUDE_DIR ${CMAKE_SOURCE_DIR}/3rd/* + ) +endif () diff --git a/test/integration_test/CMakeLists.txt b/test/integration_test/CMakeLists.txt new file mode 100644 index 0000000..50ba922 --- /dev/null +++ b/test/integration_test/CMakeLists.txt @@ -0,0 +1,29 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# CMakeLists.txt for Simple-XX/SimpleRTOS. + +# 设置项目名与版本 +project( + integration-test + VERSION 0.0.1 +) + +add_executable(integration_test + example.cpp +) + +target_compile_options(integration_test PRIVATE + ${DEFAULT_TEST_COMPILE_OPTIONS} +) + +target_link_options(integration_test PRIVATE + ${DEFAULT_TEST_LINK_OPTIONS} +) + +target_link_libraries(integration_test PRIVATE + ${DEFAULT_TEST_LINK_LIB} +) + +gtest_discover_tests(integration_test) diff --git a/test/integration_test/example.cpp b/test/integration_test/example.cpp new file mode 100644 index 0000000..65dc311 --- /dev/null +++ b/test/integration_test/example.cpp @@ -0,0 +1,19 @@ + +/** + * @file example.cpp + * @brief 集成测试示例 + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2023-09-02 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleRTOS + * @par change log: + * + *
DateAuthorDescription + *
2023-09-02Zone.N创建文件 + *
+ */ + +#include "gtest/gtest.h" + +TEST(example, test_group1) { EXPECT_EQ(0, 0); } diff --git a/test/system_test/CMakeLists.txt b/test/system_test/CMakeLists.txt new file mode 100644 index 0000000..cc3e285 --- /dev/null +++ b/test/system_test/CMakeLists.txt @@ -0,0 +1,17 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# CMakeLists.txt for Simple-XX/SimpleRTOS. + +# 设置项目名与版本 +project( + system-test + VERSION 0.0.1 +) + +if (${TARGET_ARCH} STREQUAL "x86_64" OR ${TARGET_ARCH} STREQUAL "aarch64") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/gnu_efi_test) +elseif (${TARGET_ARCH} STREQUAL "riscv64") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/opensbi_test) +endif () diff --git a/test/system_test/gnu_efi_test/CMakeLists.txt b/test/system_test/gnu_efi_test/CMakeLists.txt new file mode 100644 index 0000000..de11040 --- /dev/null +++ b/test/system_test/gnu_efi_test/CMakeLists.txt @@ -0,0 +1,90 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# CMakeLists.txt for Simple-XX/SimpleRTOS. + +# 设置项目名与版本 +project( + gnu-efi-test + VERSION 0.0.1 +) + +enable_language(CXX) + +add_executable(${PROJECT_NAME}_boot + boot.cpp + ${CMAKE_SOURCE_DIR}/src/boot/load_elf.cpp + ${CMAKE_SOURCE_DIR}/src/boot/ostream.cpp + ${CMAKE_SOURCE_DIR}/src/boot/graphics.cpp + ${CMAKE_SOURCE_DIR}/src/boot/memory.cpp +) + +add_header_project(${PROJECT_NAME}_boot) +add_header_boot(${PROJECT_NAME}_boot) +add_header_3rd(${PROJECT_NAME}_boot) + +target_compile_options(${PROJECT_NAME}_boot PRIVATE + ${DEFAULT_BOOT_COMPILE_OPTIONS} +) + +target_link_options(${PROJECT_NAME}_boot PRIVATE + ${DEFAULT_BOOT_LINK_OPTIONS} +) + +target_link_libraries(${PROJECT_NAME}_boot PRIVATE + ${DEFAULT_BOOT_LINK_LIB} +) + +add_dependencies(${PROJECT_NAME}_boot + ${COMPILE_DEPENDS} +) + +set_target_properties(${PROJECT_NAME}_boot PROPERTIES PREFIX "") +set_target_properties(${PROJECT_NAME}_boot PROPERTIES OUTPUT_NAME ${BOOT_ELF_OUTPUT_NAME}) + +# readelf -a +readelf_a(${PROJECT_NAME}_boot) + +# objdump -D +objdump_D(${PROJECT_NAME}_boot) + +# 生成 efi +elf2efi(${PROJECT_NAME}_boot ${BOOT_EFI_OUTPUT_NAME}) + +add_executable(${PROJECT_NAME}_kernel + main.cpp +) + +add_header_kernel(${PROJECT_NAME}_kernel) + +target_compile_options(${PROJECT_NAME}_kernel PRIVATE + ${DEFAULT_KERNEL_COMPILE_OPTIONS} +) + +target_link_options(${PROJECT_NAME}_kernel PRIVATE + ${DEFAULT_KERNEL_LINK_OPTIONS} +) + +set_target_properties(${PROJECT_NAME}_kernel PROPERTIES PREFIX "") +set_target_properties(${PROJECT_NAME}_kernel PROPERTIES OUTPUT_NAME ${KERNEL_ELF_OUTPUT_NAME}) + +# readelf -a +readelf_a(${PROJECT_NAME}_kernel) + +# objdump -D +objdump_D(${PROJECT_NAME}_kernel) + +# 添加 run 和 debug target +add_run_target(NAME ${PROJECT_NAME} + DEPENDS ${PROJECT_NAME}_boot ${PROJECT_NAME}_kernel ${RUN_DEPENDS} ${DEBUG_DEPENDS} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + TARGET ${TARGET_ARCH} + BOOT ${BOOT_EFI_OUTPUT_NAME} + KERNEL $ + QEMU_FLAGS + -m 128M + -net none + -bios ${ovmf_BINARY_DIR}/OVMF_${TARGET_ARCH}.fd + -hda fat:rw:./image/ +) diff --git a/test/system_test/gnu_efi_test/README.md b/test/system_test/gnu_efi_test/README.md new file mode 100644 index 0000000..f43a728 --- /dev/null +++ b/test/system_test/gnu_efi_test/README.md @@ -0,0 +1,10 @@ +# gnu_efi_test + +使用 gnu-efi 加载内核。 + +步骤: + +1. 在 qemu 中运行 +2. 读取 kernel elf 文件 +3. 读取机器内存信息 +4. 读取机器显示信息 \ No newline at end of file diff --git a/test/system_test/gnu_efi_test/boot.cpp b/test/system_test/gnu_efi_test/boot.cpp new file mode 100644 index 0000000..a8b942c --- /dev/null +++ b/test/system_test/gnu_efi_test/boot.cpp @@ -0,0 +1,107 @@ + +/** + * @file boot.cpp + * @brief boot cpp + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2023-07-15 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleRTOS + * @par change log: + * + *
DateAuthorDescription + *
2023-07-15Zone.N (Zone.Niuzh@hotmail.com)创建文件 + *
+ */ + +#include +#include + +#include "load_elf.h" +#include "ostream.hpp" +#include "project_config.h" + +uintptr_t ImageBase = 0; + +extern "C" [[maybe_unused]] EFI_STATUS EFIAPI +efi_main(EFI_HANDLE _image_handle, + [[maybe_unused]] EFI_SYSTEM_TABLE *_system_table) { + EFI_STATUS status = EFI_SUCCESS; + uint64_t kernel_addr = 0; + try { + // 输出 efi 信息 + EFI_LOADED_IMAGE *loaded_image = nullptr; + status = LibLocateProtocol(&LoadedImageProtocol, + reinterpret_cast(&loaded_image)); + if (EFI_ERROR(status)) { + debug << L"LibLocateProtocol: " << status << ostream::endl; + } + + debug << L"Revision: " << ostream::hex_X << loaded_image->Revision + << ostream::endl; + debug << L"ParentHandle: " << ostream::hex_X + << loaded_image->ParentHandle << ostream::endl; + debug << L"SystemTable: " << ostream::hex_X << loaded_image->SystemTable + << ostream::endl; + debug << L"DeviceHandle: " << ostream::hex_X + << loaded_image->DeviceHandle << ostream::endl; + debug << L"FilePath: " << ostream::hex_X << loaded_image->FilePath + << ostream::endl; + debug << L"Reserved: " << ostream::hex_X << loaded_image->Reserved + << ostream::endl; + debug << L"LoadOptionsSize: " << ostream::hex_X + << loaded_image->LoadOptionsSize << ostream::endl; + debug << L"LoadOptions: " << ostream::hex_X << loaded_image->LoadOptions + << ostream::endl; + debug << L"ImageBase: " << ostream::hex_X << loaded_image->ImageBase + << ostream::endl; + debug << L"ImageSize: " << ostream::hex_X << loaded_image->ImageSize + << ostream::endl; + debug << L"ImageCodeType: " << ostream::hex_X + << loaded_image->ImageCodeType << ostream::endl; + debug << L"ImageDataType: " << ostream::hex_X + << loaded_image->ImageDataType << ostream::endl; + debug << L"Unload: " << ostream::hex_X << loaded_image->Unload + << ostream::endl; + + // 初始化 Graphics + auto graphics = Graphics(); + // 打印图形信息 + graphics.print_info(); + // 设置为 1920*1080 + graphics.set_mode(); + // 初始化 Memory + auto memory = Memory(); + memory.print_info(); + // 加载内核 + auto elf = Elf(KERNEL_NAME); + // kernel_addr = elf.load_kernel_image(); + kernel_addr = elf.load(); + } catch (const std::exception &_e) { + debug << L"Fatal Error: " << _e.what() << ostream::endl; + return EFI_LOAD_ERROR; + } + debug << L"Set Kernel Entry Point to: [" << ostream::hex_X << kernel_addr + << L"]" << ostream::endl; + // 退出 boot service + uint64_t desc_count = 0; + EFI_MEMORY_DESCRIPTOR *memory_map = nullptr; + uint64_t map_key = 0; + uint64_t desc_size = 0; + uint32_t desc_version = 0; + memory_map = LibMemoryMap(&desc_count, &map_key, &desc_size, &desc_version); + if (memory_map == nullptr) { + debug << L"LibMemoryMap failed: memory_map == nullptr" << ostream::endl; + throw std::runtime_error("memory_map == nullptr"); + } + status = uefi_call_wrapper(gBS->ExitBootServices, 2, _image_handle, map_key); + if (EFI_ERROR(status)) { + debug << L"ExitBootServices failed, Memory Map has Changed " << status + << ostream::endl; + } + + auto kernel_entry = (void (*)())kernel_addr; + kernel_entry(); + + return EFI_SUCCESS; +} diff --git a/test/system_test/gnu_efi_test/main.cpp b/test/system_test/gnu_efi_test/main.cpp new file mode 100644 index 0000000..2ff36c0 --- /dev/null +++ b/test/system_test/gnu_efi_test/main.cpp @@ -0,0 +1,29 @@ + +/** + * @file main.cpp + * @brief 内核入口 + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2023-07-15 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleRTOS + * @par change log: + * + *
DateAuthorDescription + *
2023-07-15Zone.N (Zone.Niuzh@hotmail.com)创建文件 + *
+ */ + +#include "kernel.h" + +extern "C" void _start() { main(0, nullptr); } + +int main(int _argc, char **_argv) { + (void)_argc; + (void)_argv; + // 进入死循环 + while (true) { + ; + } + return 0; +} diff --git a/test/system_test/opensbi_test/CMakeLists.txt b/test/system_test/opensbi_test/CMakeLists.txt new file mode 100644 index 0000000..613b0e6 --- /dev/null +++ b/test/system_test/opensbi_test/CMakeLists.txt @@ -0,0 +1,62 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# CMakeLists.txt for Simple-XX/SimpleRTOS. + +# 设置项目名与版本 +project( + opensbi-test + VERSION 0.0.1 +) + +enable_language(ASM) +enable_language(CXX) + +add_executable(${PROJECT_NAME}_kernel + boot.cpp + ${CMAKE_SOURCE_DIR}/src/kernel/arch/${TARGET_ARCH}/boot.S +) + +add_header_3rd(${PROJECT_NAME}_kernel) + +target_compile_options(${PROJECT_NAME}_kernel PRIVATE + -g -ggdb + -O0 + -Wall -Wextra + -ffreestanding +) + +target_link_options(${PROJECT_NAME}_kernel PRIVATE + -no-pie + -nostdlib + -T ${CMAKE_SOURCE_DIR}/src/kernel/arch/${TARGET_ARCH}/link.ld +) + +target_compile_options(cxxrt-static PRIVATE + -fPIC +) + +add_dependencies(${PROJECT_NAME}_kernel + opensbi + cxxrt-static +) + +set_target_properties(${PROJECT_NAME}_kernel PROPERTIES PREFIX "") +set_target_properties(${PROJECT_NAME}_kernel PROPERTIES OUTPUT_NAME ${KERNEL_ELF_OUTPUT_NAME}) + +readelf_a(${PROJECT_NAME}_kernel) +objdump_D(${PROJECT_NAME}_kernel) + +# 添加 run 和 debug target +add_run_target(NAME ${PROJECT_NAME} + DEPENDS ${PROJECT_NAME}_kernel ${RUN_DEPENDS} ${DEBUG_DEPENDS} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + TARGET ${TARGET_ARCH} + KERNEL $ + QEMU_FLAGS + -serial stdio -monitor telnet::2333,server,nowait + -machine virt -nographic + -bios ${opensbi_BINARY_DIR}/platform/generic/firmware/fw_jump.elf + -kernel $ +) diff --git a/test/system_test/opensbi_test/boot.cpp b/test/system_test/opensbi_test/boot.cpp new file mode 100644 index 0000000..b6cb481 --- /dev/null +++ b/test/system_test/opensbi_test/boot.cpp @@ -0,0 +1,75 @@ + +/** + * @file boot.cpp + * @brief boot cpp + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2023-07-15 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleRTOS + * @par change log: + * + *
DateAuthorDescription + *
2023-07-15Zone.N (Zone.Niuzh@hotmail.com)创建文件 + *
+ */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cstdint" + +#include "sbi/sbi_ecall_interface.h" + +struct sbiret_t { + /// 错误码 + long error; + /// 返回值 + long value; +}; + +sbiret_t ecall(unsigned long _arg0, unsigned long _arg1, unsigned long _arg2, + unsigned long _arg3, unsigned long _arg4, unsigned long _arg5, + int _fid, int _eid) { + sbiret_t ret; + register uintptr_t a0 asm("a0") = (uintptr_t)(_arg0); + register uintptr_t a1 asm("a1") = (uintptr_t)(_arg1); + register uintptr_t a2 asm("a2") = (uintptr_t)(_arg2); + register uintptr_t a3 asm("a3") = (uintptr_t)(_arg3); + register uintptr_t a4 asm("a4") = (uintptr_t)(_arg4); + register uintptr_t a5 asm("a5") = (uintptr_t)(_arg5); + register uintptr_t a6 asm("a6") = (uintptr_t)(_fid); + register uintptr_t a7 asm("a7") = (uintptr_t)(_eid); + asm("ecall" + : "+r"(a0), "+r"(a1) + : "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(a6), "r"(a7) + : "memory"); + ret.error = a0; + ret.value = a1; + return ret; +} + +void put_char(const char _c) { + ecall(_c, 0, 0, 0, 0, 0, 0, SBI_EXT_0_1_CONSOLE_PUTCHAR); + return; +} + +int main(int, char **) { + put_char('H'); + put_char('e'); + put_char('l'); + put_char('l'); + put_char('W'); + put_char('o'); + put_char('r'); + put_char('l'); + put_char('d'); + put_char('!'); + + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/test/unit_test/CMakeLists.txt b/test/unit_test/CMakeLists.txt new file mode 100644 index 0000000..60e4ea6 --- /dev/null +++ b/test/unit_test/CMakeLists.txt @@ -0,0 +1,29 @@ + +# This file is a part of Simple-XX/SimpleRTOS +# (https://github.com/Simple-XX/SimpleRTOS). +# +# CMakeLists.txt for Simple-XX/SimpleRTOS. + +# 设置项目名与版本 +project( + unit-test + VERSION 0.0.1 +) + +add_executable(unit_test + example.cpp +) + +target_compile_options(unit_test PRIVATE + ${DEFAULT_TEST_COMPILE_OPTIONS} +) + +target_link_options(unit_test PRIVATE + ${DEFAULT_TEST_LINK_OPTIONS} +) + +target_link_libraries(unit_test PRIVATE + ${DEFAULT_TEST_LINK_LIB} +) + +gtest_discover_tests(unit_test) diff --git a/test/unit_test/example.cpp b/test/unit_test/example.cpp new file mode 100644 index 0000000..06cc9fc --- /dev/null +++ b/test/unit_test/example.cpp @@ -0,0 +1,19 @@ + +/** + * @file example.cpp + * @brief 单元测试示例 + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2023-09-02 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleRTOS + * @par change log: + * + *
DateAuthorDescription + *
2023-09-02Zone.N创建文件 + *
+ */ + +#include "gtest/gtest.h" + +TEST(example, test_group1) { EXPECT_EQ(0, 0); } diff --git a/tools/.Clion_usage.assets/2022-01-16 22.41.38.png b/tools/.Clion_usage.assets/2022-01-16 22.41.38.png new file mode 100644 index 0000000..f83a47f Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.41.38.png differ diff --git a/tools/.Clion_usage.assets/2022-01-16 22.42.21.png b/tools/.Clion_usage.assets/2022-01-16 22.42.21.png new file mode 100644 index 0000000..ef47d07 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.42.21.png differ diff --git a/tools/.Clion_usage.assets/2022-01-16 22.42.56.png b/tools/.Clion_usage.assets/2022-01-16 22.42.56.png new file mode 100644 index 0000000..0ecf20b Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.42.56.png differ diff --git a/tools/.Clion_usage.assets/2022-01-16 22.44.30.png b/tools/.Clion_usage.assets/2022-01-16 22.44.30.png new file mode 100644 index 0000000..41b75fd Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.44.30.png differ diff --git a/tools/.Clion_usage.assets/2022-01-16 22.45.14.png b/tools/.Clion_usage.assets/2022-01-16 22.45.14.png new file mode 100644 index 0000000..e33558f Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.45.14.png differ diff --git a/tools/.Clion_usage.assets/2022-01-16 22.48.24.png b/tools/.Clion_usage.assets/2022-01-16 22.48.24.png new file mode 100644 index 0000000..f3b6d24 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.48.24.png differ diff --git a/tools/.Clion_usage.assets/2022-01-16 22.52.00.png b/tools/.Clion_usage.assets/2022-01-16 22.52.00.png new file mode 100644 index 0000000..34031a3 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.52.00.png differ diff --git a/tools/.Clion_usage.assets/2022-01-16 22.54.02.png b/tools/.Clion_usage.assets/2022-01-16 22.54.02.png new file mode 100644 index 0000000..e52a45b Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.54.02.png differ diff --git a/tools/.Clion_usage.assets/2022-01-16 22.56.43.png b/tools/.Clion_usage.assets/2022-01-16 22.56.43.png new file mode 100644 index 0000000..4a0e318 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-16 22.56.43.png differ diff --git a/tools/.Clion_usage.assets/2022-01-17 16.29.12.png b/tools/.Clion_usage.assets/2022-01-17 16.29.12.png new file mode 100644 index 0000000..72a0efd Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-17 16.29.12.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.49.01.png b/tools/.Clion_usage.assets/2022-01-22 19.49.01.png new file mode 100644 index 0000000..833d450 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.49.01.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.49.07.png b/tools/.Clion_usage.assets/2022-01-22 19.49.07.png new file mode 100644 index 0000000..93fd8d4 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.49.07.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.53.12.png b/tools/.Clion_usage.assets/2022-01-22 19.53.12.png new file mode 100644 index 0000000..78bdc05 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.53.12.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.53.34-2852427.png b/tools/.Clion_usage.assets/2022-01-22 19.53.34-2852427.png new file mode 100644 index 0000000..e10b13a Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.53.34-2852427.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.53.34.png b/tools/.Clion_usage.assets/2022-01-22 19.53.34.png new file mode 100644 index 0000000..e10b13a Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.53.34.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.54.15.png b/tools/.Clion_usage.assets/2022-01-22 19.54.15.png new file mode 100644 index 0000000..f2ac784 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.54.15.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.55.16.png b/tools/.Clion_usage.assets/2022-01-22 19.55.16.png new file mode 100644 index 0000000..62405fa Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.55.16.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.56.23.png b/tools/.Clion_usage.assets/2022-01-22 19.56.23.png new file mode 100644 index 0000000..41ce159 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.56.23.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.56.31.png b/tools/.Clion_usage.assets/2022-01-22 19.56.31.png new file mode 100644 index 0000000..5313e0f Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.56.31.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.57.31.png b/tools/.Clion_usage.assets/2022-01-22 19.57.31.png new file mode 100644 index 0000000..73ae654 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.57.31.png differ diff --git a/tools/.Clion_usage.assets/2022-01-22 19.58.14.png b/tools/.Clion_usage.assets/2022-01-22 19.58.14.png new file mode 100644 index 0000000..02bd5f7 Binary files /dev/null and b/tools/.Clion_usage.assets/2022-01-22 19.58.14.png differ diff --git "a/tools/Git Commit \350\247\204\350\214\203.pdf" "b/tools/Git Commit \350\247\204\350\214\203.pdf" new file mode 100644 index 0000000..0cb973f Binary files /dev/null and "b/tools/Git Commit \350\247\204\350\214\203.pdf" differ diff --git a/tools/clion_usage.md b/tools/clion_usage.md new file mode 100644 index 0000000..cb5f01a --- /dev/null +++ b/tools/clion_usage.md @@ -0,0 +1,8 @@ + +# CLion Usage + +## osx+QEMU+x86_64 + +## osx+QEMU+riscv64 + +## osx+QEMU+aarch64 diff --git a/tools/cppcheck-suppressions.xml b/tools/cppcheck-suppressions.xml new file mode 100644 index 0000000..fdf721e --- /dev/null +++ b/tools/cppcheck-suppressions.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + * + */build* + + + + * + */3rd/* + + + + missingInclude + * + + + + unmatchedSuppression + * + + diff --git a/tools/ovmf/OVMF_x86_64.fd b/tools/ovmf/OVMF_x86_64.fd new file mode 100644 index 0000000..22bd6a6 Binary files /dev/null and b/tools/ovmf/OVMF_x86_64.fd differ diff --git a/tools/project_config.h.in b/tools/project_config.h.in new file mode 100644 index 0000000..c7a67d7 --- /dev/null +++ b/tools/project_config.h.in @@ -0,0 +1,24 @@ + +/** + * @file project_config.h + * @brief project_config 头文件,此文件由 cmake 自动生成,不要手动修改 + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2023-09-09 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleRTOS + * @par change log: + * + *
DateAuthorDescription + *
2023-09-09Zone.N (Zone.Niuzh@hotmail.com)创建文件 + *
+ */ + +#ifndef SimpleRTOS_PROJECT_CONFIG_H +#define SimpleRTOS_PROJECT_CONFIG_H + +#include "cstdint" + +#define KERNEL_NAME (wchar_t *)L"@KERNEL_ELF_OUTPUT_NAME@" + +#endif /* SimpleRTOS_PROJECT_CONFIG_H */ diff --git a/tools/riscv64_qemu_virt.dts b/tools/riscv64_qemu_virt.dts new file mode 100644 index 0000000..f6ca277 --- /dev/null +++ b/tools/riscv64_qemu_virt.dts @@ -0,0 +1,193 @@ +/dts-v1/; + +/ { + #address-cells = <0x02>; + #size-cells = <0x02>; + compatible = "riscv-virtio"; + model = "riscv-virtio,qemu"; + + fw-cfg@10100000 { + dma-coherent; + reg = <0x00 0x10100000 0x00 0x18>; + compatible = "qemu,fw-cfg-mmio"; + }; + + chosen { + bootargs = [00]; + stdout-path = "/soc/uart@10000000"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00 0x80000000 0x00 0x8000000>; + }; + + cpus { + #address-cells = <0x01>; + #size-cells = <0x00>; + timebase-frequency = <0x989680>; + + cpu@0 { + phandle = <0x01>; + device_type = "cpu"; + reg = <0x00>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv64imafdcsu"; + mmu-type = "riscv,sv48"; + + interrupt-controller { + #interrupt-cells = <0x01>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + phandle = <0x02>; + }; + }; + + cpu-map { + + cluster0 { + + core0 { + cpu = <0x01>; + }; + }; + }; + }; + + soc { + #address-cells = <0x02>; + #size-cells = <0x02>; + compatible = "simple-bus"; + ranges; + + flash@20000000 { + bank-width = <0x04>; + reg = <0x00 0x20000000 0x00 0x2000000 0x00 0x22000000 0x00 0x2000000>; + compatible = "cfi-flash"; + }; + + rtc@101000 { + interrupts = <0x0b>; + interrupt-parent = <0x03>; + reg = <0x00 0x101000 0x00 0x1000>; + compatible = "google,goldfish-rtc"; + }; + + uart@10000000 { + interrupts = <0x0a>; + interrupt-parent = <0x03>; + clock-frequency = "\08@"; + reg = <0x00 0x10000000 0x00 0x100>; + compatible = "ns16550a"; + }; + + poweroff { + value = <0x5555>; + offset = <0x00>; + regmap = <0x04>; + compatible = "syscon-poweroff"; + }; + + reboot { + value = <0x7777>; + offset = <0x00>; + regmap = <0x04>; + compatible = "syscon-reboot"; + }; + + test@100000 { + phandle = <0x04>; + reg = <0x00 0x100000 0x00 0x1000>; + compatible = "sifive,test1\0sifive,test0\0syscon"; + }; + + pci@30000000 { + interrupt-map-mask = <0x1800 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x03 0x20 0x00 0x00 0x00 0x02 0x03 0x21 0x00 0x00 0x00 0x03 0x03 0x22 0x00 0x00 0x00 0x04 0x03 0x23 0x800 0x00 0x00 0x01 0x03 0x21 0x800 0x00 0x00 0x02 0x03 0x22 0x800 0x00 0x00 0x03 0x03 0x23 0x800 0x00 0x00 0x04 0x03 0x20 0x1000 0x00 0x00 0x01 0x03 0x22 0x1000 0x00 0x00 0x02 0x03 0x23 0x1000 0x00 0x00 0x03 0x03 0x20 0x1000 0x00 0x00 0x04 0x03 0x21 0x1800 0x00 0x00 0x01 0x03 0x23 0x1800 0x00 0x00 0x02 0x03 0x20 0x1800 0x00 0x00 0x03 0x03 0x21 0x1800 0x00 0x00 0x04 0x03 0x22>; + ranges = <0x1000000 0x00 0x00 0x00 0x3000000 0x00 0x10000 0x2000000 0x00 0x40000000 0x00 0x40000000 0x00 0x40000000 0x3000000 0x04 0x00 0x04 0x00 0x04 0x00>; + reg = <0x00 0x30000000 0x00 0x10000000>; + dma-coherent; + bus-range = <0x00 0xff>; + linux,pci-domain = <0x00>; + device_type = "pci"; + compatible = "pci-host-ecam-generic"; + #size-cells = <0x02>; + #interrupt-cells = <0x01>; + #address-cells = <0x03>; + }; + + virtio_mmio@10008000 { + interrupts = <0x08>; + interrupt-parent = <0x03>; + reg = <0x00 0x10008000 0x00 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@10007000 { + interrupts = <0x07>; + interrupt-parent = <0x03>; + reg = <0x00 0x10007000 0x00 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@10006000 { + interrupts = <0x06>; + interrupt-parent = <0x03>; + reg = <0x00 0x10006000 0x00 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@10005000 { + interrupts = <0x05>; + interrupt-parent = <0x03>; + reg = <0x00 0x10005000 0x00 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@10004000 { + interrupts = <0x04>; + interrupt-parent = <0x03>; + reg = <0x00 0x10004000 0x00 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@10003000 { + interrupts = <0x03>; + interrupt-parent = <0x03>; + reg = <0x00 0x10003000 0x00 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@10002000 { + interrupts = <0x02>; + interrupt-parent = <0x03>; + reg = <0x00 0x10002000 0x00 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@10001000 { + interrupts = <0x01>; + interrupt-parent = <0x03>; + reg = <0x00 0x10001000 0x00 0x1000>; + compatible = "virtio,mmio"; + }; + + plic@c000000 { + phandle = <0x03>; + riscv,ndev = <0x35>; + reg = <0x00 0xc000000 0x00 0x210000>; + interrupts-extended = <0x02 0x0b 0x02 0x09>; + interrupt-controller; + compatible = "riscv,plic0"; + #interrupt-cells = <0x01>; + #address-cells = <0x00>; + }; + + clint@2000000 { + interrupts-extended = <0x02 0x03 0x02 0x07>; + reg = <0x00 0x2000000 0x00 0x10000>; + compatible = "riscv,clint0"; + }; + }; +}; diff --git a/tools/startup.nsh.in b/tools/startup.nsh.in new file mode 100644 index 0000000..8530240 --- /dev/null +++ b/tools/startup.nsh.in @@ -0,0 +1,2 @@ +fs0: +@BOOT_FILE_NAME@