30 Commits

Author SHA1 Message Date
Enrico Fraccaroli 510a2c0e73 Merge branch 'hotfix/v0.5.4' 2022-12-19 12:21:50 +01:00
Enrico Fraccaroli 4f650b3704 Update version. 2022-12-19 12:21:40 +01:00
Enrico Fraccaroli 679b943e0e Merge branch 'release/v0.5.3' 2022-12-19 11:59:15 +01:00
Enrico Fraccaroli 2d5e3ad41f Update version. 2022-12-19 11:59:03 +01:00
Enrico Fraccaroli 48ac939566 Set block size of generated ext2 filesystem to 4096. 2022-12-19 11:56:22 +01:00
Enrico Fraccaroli 60873784d2 Fix how we retrieve the first element of the list. 2022-12-19 11:55:33 +01:00
Enrico Fraccaroli f643e11212 Disable missing-braces warning. 2022-12-13 17:01:26 -05:00
Enrico Fraccaroli e654600c27 Deal with an unused variable. 2022-12-13 16:58:30 -05:00
Enrico Fraccaroli d499a07b0f Remove -Wno-unused-but-set-variable flag. 2022-12-13 16:56:14 -05:00
Enrico Fraccaroli 918b00e43d Force linker to be ld. 2022-12-13 16:47:08 -05:00
Enrico Fraccaroli 3d3c713828 Add verbose option 2022-12-13 16:02:21 -05:00
Enrico Fraccaroli 55932ce89e [WIP] Test extensive workflow. 2022-12-13 15:54:29 -05:00
Enrico Fraccaroli a572db52fd Add newline at the end of the files. Add -Wno-unused-command-line-argument to programs compilation flow, to support clang. 2022-12-13 15:44:31 -05:00
Enrico Fraccaroli 3f73b8d8a0 Add newline at the end of the files. Use built in keywords properly. 2022-12-13 14:31:27 -05:00
Enrico Fraccaroli 0965669f4b Add newline at the end of the files. 2022-12-13 14:25:16 -05:00
Enrico Fraccaroli 565df959b1 Simplify doxygen documentation building. 2022-12-12 22:38:07 -05:00
Enrico Fraccaroli 45376a2bb3 [Important] Extend main README. Write some more man entries. 2022-12-12 22:21:39 -05:00
Enrico Fraccaroli de9daa4a85 Add some missing documentation. There is still some work to do. 2022-12-09 11:35:30 -05:00
Enrico Fraccaroli 8e1424fbec Update comments. 2022-12-09 11:03:50 -05:00
Enrico Fraccaroli 79f150a3d5 Update readme. Add SCHEDULER_AEDF to cmake options. Add exercise template inside the scheduler_algorithm.c file. 2022-12-09 10:58:09 -05:00
Enrico Fraccaroli b61655b9de Merge tag 'v0.5.2' into develop
Debugging hotfix
2022-12-08 13:23:31 -05:00
Enrico Fraccaroli 3cf8ae04f1 Merge branch 'hotfix/v0.5.2' 2022-12-08 13:23:10 -05:00
Enrico Fraccaroli 25b4a34f1b Update version. 2022-12-08 13:23:03 -05:00
Enrico Fraccaroli b1f3169310 Align README and debugging procedure. 2022-12-08 13:20:17 -05:00
Enrico Fraccaroli 26daf96b90 Merge tag 'v0.5.1' into develop
MentOS version 0.5.1
2022-12-08 11:28:48 -05:00
Enrico Fraccaroli 206d0ebf05 Merge branch 'release/v0.5.1' 2022-12-08 11:28:29 -05:00
Enrico Fraccaroli a64ce2f81d Update version. 2022-12-08 11:28:17 -05:00
Enrico Fraccaroli 5aaddd467c Improve human readability of the Round-Robin algorithm. 2022-12-08 11:26:31 -05:00
Enrico Fraccaroli 0fd6bec4a3 Improve human readability of list_head functions. Add message of the day suggesting to use the command. 2022-12-08 10:43:22 -05:00
Enrico Fraccaroli c1cc7e366a Merge tag 'v0.5.0' into develop
MentOS version 0.5.0
2022-12-04 11:56:51 -05:00
152 changed files with 1004 additions and 5268 deletions
+81 -43
View File
@@ -1,52 +1,90 @@
name: Main name: Main
on: on:
push: push:
branches-ignore: branches-ignore:
- "releases/**" - "releases/**"
paths-ignore: paths-ignore:
- "**.md" - "**.md"
- ".gitignore" - ".gitignore"
pull_request: pull_request:
paths-ignore: paths-ignore:
- "**.md" - "**.md"
- ".gitignore" - ".gitignore"
jobs: jobs:
doxygen: doxygen:
name: Doxygen name: Doxygen
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Clone repo - name: Clone repo
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Install Doxygen Ubuntu - name: Install Doxygen Ubuntu
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y doxygen nasm sudo apt-get install -y doxygen nasm
- name: Generate documentation - name: Generate documentation
run: | run: |
cmake -B build -D DOXYGEN_WARN_AS_ERROR=NO cmake -B build -D DOXYGEN_WARN_AS_ERROR=NO
cmake --build build --target doxygen_doc cmake --build build --target mentos_documentation
test: test:
name: Build name: Build
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest] include: [
# You can access the following values via ${{ matrix.??? }}
#
# pkgs : apt-get package names. It can include multiple package names which are delimited by space.
# cc : C compiler executable.
# cxx : C++ compiler executable for `make ctocpptest`.
# x32 : Set 'true' if compiler supports x32. Otherwise, set 'false'.
# Set 'fail' if it supports x32 but fails for now. 'fail' cases must be removed.
# x86 : Set 'true' if compiler supports x86 (-m32). Otherwise, set 'false'.
# Set 'fail' if it supports x86 but fails for now. 'fail' cases must be removed.
# cxxtest : Set 'true' if it can be compiled as C++ code. Otherwise, set 'false'.
# freestanding : Set 'true' if it can be compiled and execute freestanding code. Otherwise, set 'false'.
# Usually, it requires Linux, x86_64 and gcc/g++.
# os : GitHub Actions YAML workflow label. See https://github.com/actions/virtual-environments#available-environments
# gcc
{ pkgs: 'nasm', cc: gcc, cxx: g++, os: ubuntu-latest, },
{ pkgs: 'gcc-12 g++-12 nasm', cc: gcc-12, cxx: g++-12, os: ubuntu-22.04, },
{ pkgs: 'gcc-11 g++-11 nasm', cc: gcc-11, cxx: g++-11, os: ubuntu-22.04, },
{ pkgs: 'gcc-10 g++-10 nasm', cc: gcc-10, cxx: g++-10, os: ubuntu-22.04, },
{ pkgs: 'gcc-9 g++-9 nasm', cc: gcc-9, cxx: g++-9, os: ubuntu-22.04, },
{ pkgs: 'gcc-8 g++-8 nasm', cc: gcc-8, cxx: g++-8, os: ubuntu-20.04, },
{ pkgs: 'gcc-7 g++-7 nasm', cc: gcc-7, cxx: g++-7, os: ubuntu-20.04, },
# clang
{ pkgs: 'nasm', cc: clang, cxx: clang++, os: ubuntu-latest, },
{ pkgs: 'clang-14 nasm', cc: clang-14, cxx: clang++-14, os: ubuntu-22.04, },
{ pkgs: 'clang-13 nasm', cc: clang-13, cxx: clang++-13, os: ubuntu-22.04, },
{ pkgs: 'clang-12 nasm', cc: clang-12, cxx: clang++-12, os: ubuntu-22.04, },
{ pkgs: 'clang-11 nasm', cc: clang-11, cxx: clang++-11, os: ubuntu-22.04, },
{ pkgs: 'clang-10 nasm', cc: clang-10, cxx: clang++-10, os: ubuntu-20.04, },
{ pkgs: 'clang-9 nasm', cc: clang-9, cxx: clang++-9, os: ubuntu-20.04, },
{ pkgs: 'clang-8 nasm', cc: clang-8, cxx: clang++-8, os: ubuntu-20.04, },
{ pkgs: 'clang-7 nasm', cc: clang-7, cxx: clang++-7, os: ubuntu-20.04, },
]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps:
- name: Clone repo
uses: actions/checkout@v2
- name: Install NASM Ubuntu # Set environment variables
if: matrix.os == 'ubuntu-latest' env:
run: | # We globally set CC and CXX to improve compatibility with .travis.yml
sudo apt-get update CC: ${{ matrix.cc }}
sudo apt-get install -y nasm CXX: ${{ matrix.cxx }}
- name: Build steps:
run: | - name: Clone repo
cmake -B build uses: actions/checkout@v3
cmake --build build --parallel 2
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.pkgs }}
- name: Build
run: |
cmake -B build
cmake --build build --parallel 2 --verbose
+5 -3
View File
@@ -17,7 +17,7 @@ endif()
# ============================================================================= # =============================================================================
# DOCUMENTATION # DOCUMENTATION
# ============================================================================= # =============================================================================
add_subdirectory(doc/doxygen) add_subdirectory(doc)
# ============================================================================= # =============================================================================
# OS-SPECIFIC COMPILERS # OS-SPECIFIC COMPILERS
@@ -68,6 +68,8 @@ else()
else() else()
# set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl) # set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
endif() endif()
# Speicfy the linker.
set(CMAKE_LINKER ld)
endif() endif()
# ============================================================================= # =============================================================================
@@ -93,7 +95,7 @@ add_custom_target(filesystem
COMMAND echo '=============================================================================' COMMAND echo '============================================================================='
COMMAND mkdir -p ${CMAKE_SOURCE_DIR}/files/proc COMMAND mkdir -p ${CMAKE_SOURCE_DIR}/files/proc
COMMAND mkdir -p ${CMAKE_SOURCE_DIR}/files/dev COMMAND mkdir -p ${CMAKE_SOURCE_DIR}/files/dev
COMMAND mke2fs -L 'rootfs' -N 0 -d ${CMAKE_SOURCE_DIR}/files -m 5 -r 1 -t ext2 -v -F ${CMAKE_BINARY_DIR}/rootfs.img 32M COMMAND mke2fs -L 'rootfs' -N 0 -d ${CMAKE_SOURCE_DIR}/files -b 4096 -m 5 -r 1 -t ext2 -v -F ${CMAKE_BINARY_DIR}/rootfs.img 32M
COMMAND echo '=============================================================================' COMMAND echo '============================================================================='
COMMAND echo 'Done!' COMMAND echo 'Done!'
COMMAND echo '=============================================================================' COMMAND echo '============================================================================='
@@ -155,7 +157,7 @@ add_custom_target(
# First, we need to generate a GDB file containing all the symbols of all our # First, we need to generate a GDB file containing all the symbols of all our
# executables. # executables.
add_custom_target( add_custom_target(
.gdbinit gdbinit
BYPRODUCTS ${CMAKE_BINARY_DIR}/.gdbinit BYPRODUCTS ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel.bin > ${CMAKE_BINARY_DIR}/.gdbinit COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel.bin > ${CMAKE_BINARY_DIR}/.gdbinit
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin >> ${CMAKE_BINARY_DIR}/.gdbinit COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin >> ${CMAKE_BINARY_DIR}/.gdbinit
+37 -24
View File
@@ -202,29 +202,42 @@ This example sets the `__DEBUG_LEVEL__`, so that all the messages from `INFO` an
## 7. Change the scheduling algorithm ## 7. Change the scheduling algorithm
MentOS provides three different scheduling algorithms: MentOS supports scheduling algorithms for aperiodic:
- Round-Robin - Round-Robin (RR)
- Priority - Highest Priority
- Completely Fair Scheduling - Completely Fair Scheduling (CFS)
- Aperiodic Earliest Deadline First (AEDF)
If you want to change the scheduling algorithm: It also supports periodic algorithms:
- Earliest Deadline First (EDF)
- Rate Monotonic (RM)
If you want to change the scheduling algorithm, to Round-Robin (RR) for instance:
```bash ```bash
cd build cd build
# Round Robin scheduling algorithm
cmake -DSCHEDULER_TYPE=SCHEDULER_RR .. cmake -DSCHEDULER_TYPE=SCHEDULER_RR ..
# Priority scheduling algorithm
cmake -DSCHEDULER_TYPE=SCHEDULER_PRIORITY ..
# Completely Fair Scheduling algorithm
cmake -DSCHEDULER_TYPE=SCHEDULER_CFS ..
make make
make qemu make qemu
``` ```
or you can activate one of the others:
```bash
# Highest Priority
cmake -DSCHEDULER_TYPE=SCHEDULER_PRIORITY ..
# Completely Fair Scheduling (CFS)
cmake -DSCHEDULER_TYPE=SCHEDULER_CFS ..
# Earliest Deadline First (EDF)
cmake -DSCHEDULER_TYPE=SCHEDULER_EDF ..
# Rate Monotonic (RM)
cmake -DSCHEDULER_TYPE=SCHEDULER_RM ..
# Aperiodic Earliest Deadline First (AEDF)
cmake -DSCHEDULER_TYPE=SCHEDULER_AEDF ..
```
Otherwise you can use `ccmake`: Otherwise you can use `ccmake`:
```bash ```bash
@@ -244,8 +257,7 @@ ENABLE_BUDDY_SYSTEM OFF
SCHEDULER_TYPE SCHEDULER_RR SCHEDULER_TYPE SCHEDULER_RR
``` ```
Select SCHEDULER_TYPE, and type Enter to scroll the three available algorithms Select SCHEDULER_TYPE, and type Enter to scroll the three available algorithms (SCHEDULER_RR, SCHEDULER_PRIORITY, SCHEDULER_CFS, SCHEDULER_EDF, SCHEDULER_RM, SCHEDULER_AEDF). Afterwards, you need to
(SCHEDULER_RR, SCHEDULER_PRIORITY, SCHEDULER_CFS). Afterwards,
```bash ```bash
<press c> <press c>
@@ -264,33 +276,34 @@ cmake ..
make make
``` ```
Then, you need to generate a file called `.gdbinit` placed inside the `build` directory, which will tell **gdb** which *object* file he needs to read in order to allow proper debugging. Then, you need to generate a file called `.gdbinit` placed inside the `build` directory, which will tell **gdb** which *object* file he needs to read in order to allow proper debugging. Basically, it provides for each binary file, the location of their `.text` section. To generate the file, just execute:
```bash ```bash
make gdb_file make gdbinit
``` ```
Finally, you run qemu in debugging mode with: Finally, you run qemu in debugging mode with:
```bash ```bash
make qemu-gdb make qemu-gdb
``` ```
If you did everything correctly, you should see an empty QEMU window. Basically, QEMU is waiting for you to connect *remotely* with gdb. Anyway, running `make qemu-gdb` will make your current shell busy, you cannot call `gdb` in it. You need to open a new shell inside the `build` folder and do a: If you did everything correctly, you should see an empty QEMU window. Basically, QEMU is waiting for you to connect *remotely* with gdb. Anyway, running `make qemu-gdb` will make your current shell busy, you cannot call `gdb` in it. You need to open a new shell inside the `build` folder and do a:
```bash ```bash
cgdb -q -iex 'add-auto-load-safe-path .' cgdb -q -iex 'add-auto-load-safe-path .'
``` ```
Now you will have: Now you should have in front of you:
1. the QEMU window waiting for you, 1. the QEMU window waiting for you;
2. the shell where you ran `make qemu-gdb` also waiting for you, 2. the **first** shell where you ran `make qemu-gdb`, which is also waiting for you;
3. the debugger that loaded a series of symbol files and the location of their `.text` section. 3. the **second** shell where `gdb` is runnign and, you guessed it, is waiting for you.
By default I placed a breakpoint at the begginning of 1) the bootloader, 2) the `kmain` function of the kernel. By default I placed a breakpoint at the begginning of (1) the *bootloader* and (2) the *kernel* itself.
So, when gdb starts you need to first give a continue: So, when gdb starts you need to first give a continue:
```bash ```bash
(gdb) continue (gdb) continue
``` ```
This will make the kernel run, and stop at the first breakpoint which is inside the *bootloader*: This will make the kernel run, and stop at the **first** breakpoint which is inside the *bootloader*:
```bash ```bash
Breakpoint 1, boot_main (...) at .../mentos/src/boot.c:220 Breakpoint 1, boot_main (...) at .../mentos/src/boot.c:220
220 { 220 {
@@ -298,7 +311,7 @@ Breakpoint 1, boot_main (...) at .../mentos/src/boot.c:220
giving a second `continue` will get you to the start of the operating system: giving a second `continue` will get you to the start of the operating system:
This will make the kernel run, and stop at the first breakpoint which is inside the *bootloader*: This will make the kernel run, and stop at the **second** breakpoint which is inside the *kernel*:
```bash ```bash
Breakpoint 2, kmain (...) at .../mentos/src/kernel.c:95 Breakpoint 2, kmain (...) at .../mentos/src/kernel.c:95
95 { 95 {
+290
View File
@@ -0,0 +1,290 @@
# Find Doxygen
find_package(Doxygen)
if (DOXYGEN_FOUND)
# Read the file with the version.
file(READ ${PROJECT_SOURCE_DIR}/mentos/inc/version.h version_file)
# Extract the OS version.
string(REGEX MATCH "OS_MAJOR_VERSION ([0-9]*)" _ ${version_file})
set(OS_MAJOR_VERSION ${CMAKE_MATCH_1})
string(REGEX MATCH "OS_MINOR_VERSION ([0-9]*)" _ ${version_file})
set(OS_MINOR_VERSION ${CMAKE_MATCH_1})
string(REGEX MATCH "OS_MICRO_VERSION ([0-9]*)" _ ${version_file})
set(OS_MICRO_VERSION ${CMAKE_MATCH_1})
# Setup the Doxygen documentation.
set(DOXYGEN_PROJECT_NAME "MentOS")
set(DOXYGEN_PROJECT_NUMBER "${OS_MAJOR_VERSION}.${OS_MINOR_VERSION}.${OS_MICRO_VERSION}")
set(DOXYGEN_PROJECT_BRIEF "The Mentoring Operating System")
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${PROJECT_SOURCE_DIR}/README.md)
set(DOXYGEN_IMAGE_PATH ${PROJECT_SOURCE_DIR}/doc/resources)
set(DOXYGEN_SHOW_INCLUDE_FILES NO)
set(DOXYGEN_GENERATE_TREEVIEW NO)
set(DOXYGEN_WARN_NO_PARAMDOC YES)
set(DOXYGEN_HTML_STYLESHEET ${PROJECT_SOURCE_DIR}/doc/doxygen.css)
doxygen_add_docs(
${PROJECT_NAME}_documentation
${PROJECT_SOURCE_DIR}/README.md
${PROJECT_SOURCE_DIR}/CODING_STYLE.md
${PROJECT_SOURCE_DIR}/LICENSE.md
${PROJECT_SOURCE_DIR}/TODO.md
${PROJECT_SOURCE_DIR}/doc/signal.md
${PROJECT_SOURCE_DIR}/doc/syscall.md
${PROJECT_SOURCE_DIR}/libc/src/crt0.S
${PROJECT_SOURCE_DIR}/libc/inc/array.h
${PROJECT_SOURCE_DIR}/libc/inc/assert.h
${PROJECT_SOURCE_DIR}/libc/inc/bits/ioctls.h
${PROJECT_SOURCE_DIR}/libc/inc/bits/stat.h
${PROJECT_SOURCE_DIR}/libc/inc/bits/termios-struct.h
${PROJECT_SOURCE_DIR}/libc/inc/ctype.h
${PROJECT_SOURCE_DIR}/libc/inc/debug.h
${PROJECT_SOURCE_DIR}/libc/inc/fcntl.h
${PROJECT_SOURCE_DIR}/libc/inc/fcvt.h
${PROJECT_SOURCE_DIR}/libc/inc/grp.h
${PROJECT_SOURCE_DIR}/libc/inc/io/mm_io.h
${PROJECT_SOURCE_DIR}/libc/inc/io/port_io.h
${PROJECT_SOURCE_DIR}/libc/inc/ipc/ipc.h
${PROJECT_SOURCE_DIR}/libc/inc/ipc/msg.h
${PROJECT_SOURCE_DIR}/libc/inc/ipc/sem.h
${PROJECT_SOURCE_DIR}/libc/inc/ipc/shm.h
${PROJECT_SOURCE_DIR}/libc/inc/libgen.h
${PROJECT_SOURCE_DIR}/libc/inc/limits.h
${PROJECT_SOURCE_DIR}/libc/inc/math.h
${PROJECT_SOURCE_DIR}/libc/inc/pwd.h
${PROJECT_SOURCE_DIR}/libc/inc/ring_buffer.h
${PROJECT_SOURCE_DIR}/libc/inc/sched.h
${PROJECT_SOURCE_DIR}/libc/inc/signal.h
${PROJECT_SOURCE_DIR}/libc/inc/stdarg.h
${PROJECT_SOURCE_DIR}/libc/inc/stdbool.h
${PROJECT_SOURCE_DIR}/libc/inc/stddef.h
${PROJECT_SOURCE_DIR}/libc/inc/stdint.h
${PROJECT_SOURCE_DIR}/libc/inc/stdio.h
${PROJECT_SOURCE_DIR}/libc/inc/stdlib.h
${PROJECT_SOURCE_DIR}/libc/inc/strerror.h
${PROJECT_SOURCE_DIR}/libc/inc/string.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/bitops.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/dirent.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/errno.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/ioctl.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/reboot.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/stat.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/types.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/unistd.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/utsname.h
${PROJECT_SOURCE_DIR}/libc/inc/sys/wait.h
${PROJECT_SOURCE_DIR}/libc/inc/system/syscall_types.h
${PROJECT_SOURCE_DIR}/libc/inc/termios.h
${PROJECT_SOURCE_DIR}/libc/inc/time.h
${PROJECT_SOURCE_DIR}/libc/src/abort.c
${PROJECT_SOURCE_DIR}/libc/src/assert.c
${PROJECT_SOURCE_DIR}/libc/src/ctype.c
${PROJECT_SOURCE_DIR}/libc/src/debug.c
${PROJECT_SOURCE_DIR}/libc/src/fcvt.c
${PROJECT_SOURCE_DIR}/libc/src/grp.c
${PROJECT_SOURCE_DIR}/libc/src/io/mm_io.c
${PROJECT_SOURCE_DIR}/libc/src/io/port_io.c
${PROJECT_SOURCE_DIR}/libc/src/ipc/ipc.c
${PROJECT_SOURCE_DIR}/libc/src/libc_start.c
${PROJECT_SOURCE_DIR}/libc/src/libgen.c
${PROJECT_SOURCE_DIR}/libc/src/math.c
${PROJECT_SOURCE_DIR}/libc/src/pwd.c
${PROJECT_SOURCE_DIR}/libc/src/sched.c
${PROJECT_SOURCE_DIR}/libc/src/setenv.c
${PROJECT_SOURCE_DIR}/libc/src/stdio.c
${PROJECT_SOURCE_DIR}/libc/src/stdlib.c
${PROJECT_SOURCE_DIR}/libc/src/strerror.c
${PROJECT_SOURCE_DIR}/libc/src/string.c
${PROJECT_SOURCE_DIR}/libc/src/sys/errno.c
${PROJECT_SOURCE_DIR}/libc/src/sys/ioctl.c
${PROJECT_SOURCE_DIR}/libc/src/sys/unistd.c
${PROJECT_SOURCE_DIR}/libc/src/sys/utsname.c
${PROJECT_SOURCE_DIR}/libc/src/termios.c
${PROJECT_SOURCE_DIR}/libc/src/time.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/chdir.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/close.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/creat.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/exec.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/exit.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/fork.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/getcwd.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/getdents.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/getgid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/getpgid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/getpid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/getppid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/getsid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/getuid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/interval.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/kill.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/lseek.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/mkdir.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/nice.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/open.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/read.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/reboot.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/rmdir.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/setgid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/setpgid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/setsid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/setuid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/signal.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/stat.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/unlink.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/waitpid.c
${PROJECT_SOURCE_DIR}/libc/src/unistd/write.c
${PROJECT_SOURCE_DIR}/libc/src/vscanf.c
${PROJECT_SOURCE_DIR}/libc/src/vsprintf.c
${PROJECT_SOURCE_DIR}/mentos/src/boot.S
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/exception.S
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/gdt.S
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/idt.S
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/interrupt.S
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/tss.S
${PROJECT_SOURCE_DIR}/mentos/src/process/user.S
${PROJECT_SOURCE_DIR}/mentos/inc/boot.h
${PROJECT_SOURCE_DIR}/mentos/inc/descriptor_tables/gdt.h
${PROJECT_SOURCE_DIR}/mentos/inc/descriptor_tables/idt.h
${PROJECT_SOURCE_DIR}/mentos/inc/descriptor_tables/isr.h
${PROJECT_SOURCE_DIR}/mentos/inc/descriptor_tables/tss.h
${PROJECT_SOURCE_DIR}/mentos/inc/devices/fpu.h
${PROJECT_SOURCE_DIR}/mentos/inc/devices/pci.h
${PROJECT_SOURCE_DIR}/mentos/inc/drivers/ata.h
${PROJECT_SOURCE_DIR}/mentos/inc/drivers/fdc.h
${PROJECT_SOURCE_DIR}/mentos/inc/drivers/keyboard/keyboard.h
${PROJECT_SOURCE_DIR}/mentos/inc/drivers/keyboard/keymap.h
${PROJECT_SOURCE_DIR}/mentos/inc/drivers/mouse.h
${PROJECT_SOURCE_DIR}/mentos/inc/drivers/ps2.h
${PROJECT_SOURCE_DIR}/mentos/inc/drivers/rtc.h
${PROJECT_SOURCE_DIR}/mentos/inc/elf/elf.h
${PROJECT_SOURCE_DIR}/mentos/inc/fs/ext2.h
${PROJECT_SOURCE_DIR}/mentos/inc/fs/ioctl.h
${PROJECT_SOURCE_DIR}/mentos/inc/fs/procfs.h
${PROJECT_SOURCE_DIR}/mentos/inc/fs/vfs.h
${PROJECT_SOURCE_DIR}/mentos/inc/fs/vfs_types.h
${PROJECT_SOURCE_DIR}/mentos/inc/hardware/cpuid.h
${PROJECT_SOURCE_DIR}/mentos/inc/hardware/pic8259.h
${PROJECT_SOURCE_DIR}/mentos/inc/hardware/timer.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/debug.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/mm_io.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/port_io.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/proc_modules.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/vga/vga.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/vga/vga_font.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/vga/vga_mode.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/vga/vga_palette.h
${PROJECT_SOURCE_DIR}/mentos/inc/io/video.h
${PROJECT_SOURCE_DIR}/mentos/inc/kernel.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/compiler.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/hashmap.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/irqflags.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/list.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/list_head.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/mutex.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/ndtree.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/rbtree.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/spinlock.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/stack_helper.h
${PROJECT_SOURCE_DIR}/mentos/inc/klib/stdatomic.h
${PROJECT_SOURCE_DIR}/mentos/inc/link_access.h
${PROJECT_SOURCE_DIR}/mentos/inc/mem/buddysystem.h
${PROJECT_SOURCE_DIR}/mentos/inc/mem/gfp.h
${PROJECT_SOURCE_DIR}/mentos/inc/mem/kheap.h
${PROJECT_SOURCE_DIR}/mentos/inc/mem/paging.h
${PROJECT_SOURCE_DIR}/mentos/inc/mem/slab.h
${PROJECT_SOURCE_DIR}/mentos/inc/mem/vmem_map.h
${PROJECT_SOURCE_DIR}/mentos/inc/mem/zone_allocator.h
${PROJECT_SOURCE_DIR}/mentos/inc/multiboot.h
${PROJECT_SOURCE_DIR}/mentos/inc/process/prio.h
${PROJECT_SOURCE_DIR}/mentos/inc/process/process.h
${PROJECT_SOURCE_DIR}/mentos/inc/process/scheduler.h
${PROJECT_SOURCE_DIR}/mentos/inc/process/wait.h
${PROJECT_SOURCE_DIR}/mentos/inc/proc_access.h
${PROJECT_SOURCE_DIR}/mentos/inc/sys/errno.h
${PROJECT_SOURCE_DIR}/mentos/inc/sys/ipc.h
${PROJECT_SOURCE_DIR}/mentos/inc/sys/kernel_levels.h
${PROJECT_SOURCE_DIR}/mentos/inc/sys/module.h
${PROJECT_SOURCE_DIR}/mentos/inc/sys/reboot.h
${PROJECT_SOURCE_DIR}/mentos/inc/sys/types.h
${PROJECT_SOURCE_DIR}/mentos/inc/sys/utsname.h
${PROJECT_SOURCE_DIR}/mentos/inc/system/panic.h
${PROJECT_SOURCE_DIR}/mentos/inc/system/printk.h
${PROJECT_SOURCE_DIR}/mentos/inc/system/signal.h
${PROJECT_SOURCE_DIR}/mentos/inc/system/syscall.h
${PROJECT_SOURCE_DIR}/mentos/inc/version.h
${PROJECT_SOURCE_DIR}/mentos/src/boot.c
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/exception.c
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/gdt.c
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/idt.c
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/interrupt.c
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/tss.c
${PROJECT_SOURCE_DIR}/mentos/src/devices/fpu.c
${PROJECT_SOURCE_DIR}/mentos/src/devices/pci.c
${PROJECT_SOURCE_DIR}/mentos/src/drivers/ata.c
${PROJECT_SOURCE_DIR}/mentos/src/drivers/fdc.c
${PROJECT_SOURCE_DIR}/mentos/src/drivers/keyboard/keyboard.c
${PROJECT_SOURCE_DIR}/mentos/src/drivers/keyboard/keymap.c
${PROJECT_SOURCE_DIR}/mentos/src/drivers/mouse.c
${PROJECT_SOURCE_DIR}/mentos/src/drivers/ps2.c
${PROJECT_SOURCE_DIR}/mentos/src/drivers/rtc.c
${PROJECT_SOURCE_DIR}/mentos/src/elf/elf.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/ext2.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/ioctl.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/namei.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/open.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/procfs.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/readdir.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/read_write.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/stat.c
${PROJECT_SOURCE_DIR}/mentos/src/fs/vfs.c
${PROJECT_SOURCE_DIR}/mentos/src/hardware/cpuid.c
${PROJECT_SOURCE_DIR}/mentos/src/hardware/pic8259.c
${PROJECT_SOURCE_DIR}/mentos/src/hardware/timer.c
${PROJECT_SOURCE_DIR}/mentos/src/io/debug.c
${PROJECT_SOURCE_DIR}/mentos/src/io/mm_io.c
${PROJECT_SOURCE_DIR}/mentos/src/io/port_io.c
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_running.c
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_system.c
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_video.c
${PROJECT_SOURCE_DIR}/mentos/src/io/stdio.c
${PROJECT_SOURCE_DIR}/mentos/src/io/vga/vga.c
${PROJECT_SOURCE_DIR}/mentos/src/io/video.c
${PROJECT_SOURCE_DIR}/mentos/src/ipc/msg.c
${PROJECT_SOURCE_DIR}/mentos/src/ipc/sem.c
${PROJECT_SOURCE_DIR}/mentos/src/ipc/shm.c
${PROJECT_SOURCE_DIR}/mentos/src/kernel/sys.c
${PROJECT_SOURCE_DIR}/mentos/src/kernel.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/assert.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/ctype.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/fcvt.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/hashmap.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/libgen.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/list.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/math.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/mutex.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/ndtree.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/rbtree.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/spinlock.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/strerror.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/string.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/time.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/vscanf.c
${PROJECT_SOURCE_DIR}/mentos/src/klib/vsprintf.c
${PROJECT_SOURCE_DIR}/mentos/src/mem/buddysystem.c
${PROJECT_SOURCE_DIR}/mentos/src/mem/kheap.c
${PROJECT_SOURCE_DIR}/mentos/src/mem/paging.c
${PROJECT_SOURCE_DIR}/mentos/src/mem/slab.c
${PROJECT_SOURCE_DIR}/mentos/src/mem/vmem_map.c
${PROJECT_SOURCE_DIR}/mentos/src/mem/zone_allocator.c
${PROJECT_SOURCE_DIR}/mentos/src/multiboot.c
${PROJECT_SOURCE_DIR}/mentos/src/process/process.c
${PROJECT_SOURCE_DIR}/mentos/src/process/scheduler.c
${PROJECT_SOURCE_DIR}/mentos/src/process/scheduler_algorithm.c
${PROJECT_SOURCE_DIR}/mentos/src/process/wait.c
${PROJECT_SOURCE_DIR}/mentos/src/sys/module.c
${PROJECT_SOURCE_DIR}/mentos/src/sys/utsname.c
${PROJECT_SOURCE_DIR}/mentos/src/system/errno.c
${PROJECT_SOURCE_DIR}/mentos/src/system/panic.c
${PROJECT_SOURCE_DIR}/mentos/src/system/printk.c
${PROJECT_SOURCE_DIR}/mentos/src/system/signal.c
${PROJECT_SOURCE_DIR}/mentos/src/system/syscall.c
)
endif (DOXYGEN_FOUND)
+44 -13
View File
@@ -26,6 +26,31 @@
outline: none; outline: none;
} }
.sm-dox a:hover {
color: #4b5263;
background-color: #A9B7C6;
}
.sm-dox ul,
.sm-dox ul a {
color: #A9B7C6;
background-color: #4b5263;
}
.sm-dox ul a.highlighted {
color: #4b5263;
background-color: #A9B7C6;
}
.sm-dox ul a:hover {
color: #4b5263;
background-color: #A9B7C6;
background-image: none;
background-repeat: no-repeat;
text-shadow: none;
outline: none;
}
.memberdecls tr:not(:first-child) { .memberdecls tr:not(:first-child) {
background-color: #333842; background-color: #333842;
} }
@@ -599,7 +624,8 @@ table.memberdecls {
} }
.memTemplParams { .memTemplParams {
color: #4665A2; color: #728dc2;
font-weight: bold;
white-space: nowrap; white-space: nowrap;
font-size: 80%; font-size: 80%;
} }
@@ -633,9 +659,10 @@ table.memberdecls {
.memtemplate { .memtemplate {
font-size: 80%; font-size: 80%;
color: #4665A2; color: #728dc2;
font-weight: normal; font-weight: bold;
margin-left: 9px; margin-left: 9px;
white-space: nowrap;
} }
.memnav { .memnav {
@@ -686,6 +713,12 @@ dl.reflist dd {
padding: 1em; padding: 1em;
} }
.memdoc p {
padding: 0.25em;
border-radius: 4px;
background-color: #3A3F49;
}
dl.reflist dt { dl.reflist dt {
padding: 5px; padding: 5px;
} }
@@ -857,6 +890,7 @@ div.directory {
font-family: Arial, Helvetica; font-family: Arial, Helvetica;
font-weight: bold; font-weight: bold;
font-size: 12px; font-size: 12px;
line-height: 16px;
height: 16px; height: 16px;
width: 16px; width: 16px;
display: inline-block; display: inline-block;
@@ -879,7 +913,7 @@ div.directory {
height: 18px; height: 18px;
margin-bottom: 4px; margin-bottom: 4px;
background-image: url("folderopen.png"); background-image: url("folderopen.png");
background-position: 0px -4px; /* background-position: 0px -4px; */
background-repeat: repeat-y; background-repeat: repeat-y;
vertical-align: top; vertical-align: top;
display: inline-block; display: inline-block;
@@ -890,7 +924,7 @@ div.directory {
height: 18px; height: 18px;
margin-bottom: 4px; margin-bottom: 4px;
background-image: url("folderclosed.png"); background-image: url("folderclosed.png");
background-position: 0px -4px; /* background-position: 0px -4px; */
background-repeat: repeat-y; background-repeat: repeat-y;
vertical-align: top; vertical-align: top;
display: inline-block; display: inline-block;
@@ -901,7 +935,7 @@ div.directory {
height: 18px; height: 18px;
margin-bottom: 4px; margin-bottom: 4px;
background-image: url("doc.png"); background-image: url("doc.png");
background-position: 0px -4px; /* background-position: 0px -4px; */
background-repeat: repeat-y; background-repeat: repeat-y;
vertical-align: top; vertical-align: top;
display: inline-block; display: inline-block;
@@ -950,7 +984,7 @@ table.doxtable th {
} }
table.fieldtable { table.fieldtable {
/*width: 100%;*/ width: fit-content;
margin-bottom: 10px; margin-bottom: 10px;
border: 1px solid #A8B8D9; border: 1px solid #A8B8D9;
border-spacing: 0px; border-spacing: 0px;
@@ -960,7 +994,6 @@ table.fieldtable {
-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
-webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
width: fit-content;
} }
.fieldtable td, .fieldtable td,
@@ -998,11 +1031,9 @@ table.fieldtable {
} }
.fieldtable th { .fieldtable th {
background-image: url("nav_f.png"); font-size: 100%;
background-repeat: repeat-x; color: #d7dee4;
background-color: #E2E8F2; background-color: #49515f;
font-size: 90%;
color: #253555;
padding-bottom: 4px; padding-bottom: 4px;
padding-top: 5px; padding-top: 5px;
text-align: left; text-align: left;
-37
View File
@@ -1,37 +0,0 @@
# Find Doxygen
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/html/index.html)
# Replace variables inside @@ with the current values.
set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile)
set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
# Copy the files needd by the documentation.
set(DOXYFILE_CSS ${CMAKE_CURRENT_SOURCE_DIR}/doxygen.css)
set(DOXYFILE_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/header.html)
set(DOXYFILE_FOOTER ${CMAKE_CURRENT_SOURCE_DIR}/footer.html)
# Doxygen won't create this for us.
file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
add_custom_command(
OUTPUT ${DOXYGEN_INDEX_FILE}
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN}
COMMENT "Generating docs"
)
add_custom_target(
doxygen_doc
DEPENDS
${DOXYGEN_INDEX_FILE}
${DOXYFILE_IN}
${DOXYFILE_CSS}
${DOXYFILE_HEADER}
${DOXYFILE_FOOTER}
)
endif (DOXYGEN_FOUND)
-2530
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-40
View File
@@ -1,40 +0,0 @@
<!-- HTML footer for doxygen 1.8.16-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath">
<!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen" />
</a> $doxygenversion
</li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<div class="footer">
<hr class="footer" />
<ul class="footer-info">
<li class="footer-info-lastmode">
This page was last modified on $datetime.
</li>
<li class="footer-info-copyright">
MentOs © 20142022 the MentOs-Team, and numerous contributors.<br>
It is available for use and modification under the&#160;
<a href="$relpath^md_LICENSE.html">MIT License</a>.<br>
</li>
</ul>
<hr class="footer" />
<address class="footer">
$generatedby&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen" />
</a> $doxygenversion
</address>
</div>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>
-66
View File
@@ -1,66 +0,0 @@
<!-- HTML header for doxygen 1.8.17-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<meta name="generator" content="Doxygen $doxygenversion" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--BEGIN PROJECT_NAME-->
<title>$projectname: $title</title>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<title>$title</title>
<!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<div id="top">
<!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo" /></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">$projectname
<!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span>
<!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF-->
<div id="projectbrief">$projectbrief</div>
<!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

+1
View File
@@ -0,0 +1 @@
Call `man` to have a list of all the commands.
+8
View File
@@ -0,0 +1,8 @@
SYNOPSIS
cat [FILE]
DESCRIPTION
Prints the content of the given file.
OPTIONS
-h --help : shows command help.
+5
View File
@@ -0,0 +1,5 @@
SYNOPSIS
clear
DESCRIPTION
Clears the screen.
+5
View File
@@ -0,0 +1,5 @@
SYNOPSIS
cpuid
DESCRIPTION
Not currently implemented.
+5
View File
@@ -0,0 +1,5 @@
SYNOPSIS
date
DESCRIPTION
Shows the current date.
+6
View File
@@ -0,0 +1,6 @@
SYNOPSIS
echo [STRING]
DESCRIPTION
Displays a line of text.
+3 -5
View File
@@ -1,6 +1,3 @@
NAME
ls - list directory contents
SYNOPSIS SYNOPSIS
ls [OPTIONS] [FILE/FOLDER] ls [OPTIONS] [FILE/FOLDER]
@@ -10,5 +7,6 @@ DESCRIPTION
inside the current folder. inside the current folder.
OPTIONS OPTIONS
-a : list all entries. -h --help : shows command help.
-l : show the entries as a detailed list. -a --all : list all entries.
-l --long : show the entries as a detailed long list.
+1 -1
View File
@@ -50,7 +50,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-but-set-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
# Set the compiler options. # Set the compiler options.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
+4
View File
@@ -22,6 +22,8 @@
#define bitmask_check(V, M) ((V) & (M)) ///< Checks if the bits identified by the mask are all 1. #define bitmask_check(V, M) ((V) & (M)) ///< Checks if the bits identified by the mask are all 1.
/// @brief Finds the first bit at zero, starting from the less significative bit. /// @brief Finds the first bit at zero, starting from the less significative bit.
/// @param value the value we need to analyze.
/// @return the position of the first zero bit.
static inline int find_first_zero(unsigned long value) static inline int find_first_zero(unsigned long value)
{ {
for (int i = 0; i < 32; ++i) for (int i = 0; i < 32; ++i)
@@ -31,6 +33,8 @@ static inline int find_first_zero(unsigned long value)
} }
/// @brief Finds the first bit not zero, starting from the less significative bit. /// @brief Finds the first bit not zero, starting from the less significative bit.
/// @param value the value we need to analyze.
/// @return the position of the first non-zero bit.
static inline int find_first_non_zero(unsigned long value) static inline int find_first_non_zero(unsigned long value)
{ {
for (int i = 0; i < 32; ++i) for (int i = 0; i < 32; ++i)
+9 -8
View File
@@ -21,22 +21,23 @@ enum {
DT_WHT = 14 DT_WHT = 14
}; };
/// @brief Characters describing the direactory entry.
static const char dt_char_array[] = { static const char dt_char_array[] = {
'?', // DT_UNKNOWN = 0, '?', // DT_UNKNOWN = 0,
'p', //DT_FIFO = 1, 'p', // DT_FIFO = 1,
'c', //DT_CHR = 2, 'c', // DT_CHR = 2,
'*', '*',
'd', //DT_DIR = 4, 'd', // DT_DIR = 4,
'*', '*',
'b', //DT_BLK = 6, 'b', // DT_BLK = 6,
'*', '*',
'-', //DT_REG = 8, '-', // DT_REG = 8,
'*', '*',
'l', //DT_LNK = 10, 'l', // DT_LNK = 10,
'*', '*',
's', //DT_SOCK = 12, 's', // DT_SOCK = 12,
'*', '*',
'?', //DT_WHT = 14 '?', // DT_WHT = 14
}; };
/// Directory entry. /// Directory entry.
+2 -2
View File
@@ -8,8 +8,8 @@
#include "signal.h" #include "signal.h"
#include "stdio.h" #include "stdio.h"
// Since there could be signal handlers listening for the abort, we /// @brief Since there could be signal handlers listening for the abort, we need
// need to keep track at which stage of the abort we are. /// to keep track at which stage of the abort we are.
static int stage = 0; static int stage = 0;
void abort(void) void abort(void)
+4
View File
@@ -14,6 +14,10 @@
static int __fd = -1; static int __fd = -1;
/// @brief It parses the line (as string) and saves its content inside the
/// group_t structure.
/// @param grp the struct where we store the information.
/// @param buf the buffer from which we extract the information.
static inline void __parse_line(group_t *grp, char *buf) static inline void __parse_line(group_t *grp, char *buf)
{ {
assert(grp && "Received null grp!"); assert(grp && "Received null grp!");
+1 -2
View File
@@ -33,7 +33,6 @@ inline uint32_t inportl(uint16_t port)
{ {
uint32_t rv; uint32_t rv;
__asm__ __volatile__("inl %%dx, %%eax" : "=a"(rv) : "dN"(port)); __asm__ __volatile__("inl %%dx, %%eax" : "=a"(rv) : "dN"(port));
return rv; return rv;
} }
@@ -49,7 +48,7 @@ inline void outports(uint16_t port, uint16_t data)
void outportsm(uint16_t port, uint8_t *data, uint16_t size) void outportsm(uint16_t port, uint8_t *data, uint16_t size)
{ {
asm volatile("rep outsw" : "+S"(data), "+c"(size) : "d"(port)); __asm__ __volatile__("rep outsw" : "+S"(data), "+c"(size) : "d"(port));
} }
inline void outportl(uint16_t port, uint32_t data) inline void outportl(uint16_t port, uint32_t data)
+7
View File
@@ -81,6 +81,13 @@ ssize_t __readline(int fd, char *buffer, size_t buflen)
return newline_len; return newline_len;
} }
/// @brief Searches for the given entry inside the buffer.
/// @param fd the file descriptor of the file.
/// @param buffer the support buffer we use to read the file.
/// @param buflen the length of the support buffer.
/// @param name the username we are looking for.
/// @param uid the user-id of the user we are looking for.
/// @return the buffer itself if we have found the entry, NULL otherwise.
static inline char *__search_entry(int fd, char *buffer, int buflen, const char *name, uid_t uid) static inline char *__search_entry(int fd, char *buffer, int buflen, const char *name, uid_t uid)
{ {
while (__readline(fd, buffer, buflen)) { while (__readline(fd, buffer, buflen)) {
+5
View File
@@ -13,6 +13,10 @@ char **environ;
static char **__environ = NULL; static char **__environ = NULL;
static size_t __environ_size = 0; static size_t __environ_size = 0;
/// @brief Finds the entry in the environ.
/// @param name the name of the entry we are looking for.
/// @param name_len the length of the name we received.
/// @return the index of the entry, or -1 if we did not find it.
static inline int __find_entry(const char *name, const size_t name_len) static inline int __find_entry(const char *name, const size_t name_len)
{ {
if (environ) { if (environ) {
@@ -24,6 +28,7 @@ static inline int __find_entry(const char *name, const size_t name_len)
return -1; return -1;
} }
/// @brief Makes a clone of the current environ.
static void __clone_environ() static void __clone_environ()
{ {
if (environ) { if (environ) {
+3
View File
@@ -12,6 +12,9 @@
/// malloc(), calloc() or realloc(). /// malloc(), calloc() or realloc().
#define MALLOC_MAGIC_NUMBER 0x600DC0DE #define MALLOC_MAGIC_NUMBER 0x600DC0DE
/// @brief Checks if the pointer is a valid malloc entry.
/// @param ptr the pointer we are checking.
/// @return 1 of success, 0 on failure.
static inline int __malloc_is_valid_ptr(void *ptr) static inline int __malloc_is_valid_ptr(void *ptr)
{ {
return (ptr && (((size_t *)ptr)[-1] == MALLOC_MAGIC_NUMBER)); return (ptr && (((size_t *)ptr)[-1] == MALLOC_MAGIC_NUMBER));
+2 -2
View File
@@ -67,7 +67,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-but-set-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
# Set the compiler options. # Set the compiler options.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
@@ -216,7 +216,7 @@ endif(ENABLE_ALLOC_TRACE)
# ============================================================================= # =============================================================================
# Set the list of valid scheduling options. # Set the list of valid scheduling options.
set(SCHEDULER_TYPES SCHEDULER_RR SCHEDULER_PRIORITY SCHEDULER_CFS SCHEDULER_EDF SCHEDULER_RM) set(SCHEDULER_TYPES SCHEDULER_RR SCHEDULER_PRIORITY SCHEDULER_CFS SCHEDULER_EDF SCHEDULER_RM SCHEDULER_AEDF)
# Add the scheduling option. # Add the scheduling option.
set(SCHEDULER_TYPE "SCHEDULER_RR" CACHE STRING "Chose the type of scheduler: ${SCHEDULER_TYPES}") set(SCHEDULER_TYPE "SCHEDULER_RR" CACHE STRING "Chose the type of scheduler: ${SCHEDULER_TYPES}")
# List of schedulers. # List of schedulers.
+2 -5
View File
@@ -1,17 +1,14 @@
OUTPUT_FORMAT("elf") OUTPUT_FORMAT("elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(boot_entry) ENTRY(boot_entry)
BOOTLOADER_PHYSICAL_ADDRESS = 0x00100000;
MEMORY { MEMORY {
BOOTLOADER_MEM : ORIGIN = 0x00000000, LENGTH = 128M BOOTLOADER_MEM : ORIGIN = 0x00000000, LENGTH = 128M
} }
SECTIONS SECTIONS
{ {
. = BOOTLOADER_PHYSICAL_ADDRESS; . = 0x00100000;
_bootloader_start = .; _bootloader_start = .;
.multiboot . : AT(ADDR(.multiboot)) .multiboot . : AT(ADDR(.multiboot))
{ {
+2 -3
View File
@@ -41,9 +41,8 @@
#pragma once #pragma once
/// @brief Assign the value to the given variable. /// @brief Assign the value to the given variable.
#define WRITE_ONCE(var, val) (*((volatile typeof(val) *)(&(var))) = (val)) #define WRITE_ONCE(var, val) (*((__volatile__ __typeof__(val) *)(&(var))) = (val))
/// @brief Read the value from the given variable. /// @brief Read the value from the given variable.
#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) #define READ_ONCE(var) (*((__volatile__ __typeof__(var) *)(&(var))))
+86 -96
View File
@@ -19,8 +19,7 @@ typedef struct list_head {
/// @param ptr The &list_head pointer. /// @param ptr The &list_head pointer.
/// @param type The type of the struct this is embedded in. /// @param type The type of the struct this is embedded in.
/// @param member The name of the list_head within the struct. /// @param member The name of the list_head within the struct.
#define list_entry(ptr, type, member) \ #define list_entry(ptr, type, member) container_of(ptr, type, member)
container_of(ptr, type, member)
/// @brief Iterates over a list. /// @brief Iterates over a list.
/// @param pos The &list_head to use as a loop cursor. /// @param pos The &list_head to use as a loop cursor.
@@ -49,124 +48,115 @@ typedef struct list_head {
for (list_head * (pos) = (head)->next; (pos) != (head); (pos) = (pos)->next) for (list_head * (pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
/// @brief Initializes the list_head. /// @brief Initializes the list_head.
/// @param head The head for your list. /// @param head The head of your list.
#define list_head_init(head) (head)->next = (head)->prev = (head) static inline void list_head_init(list_head *head)
/// @brief Initializes the list_head.
/// @param head The head for your list.
#define list_head_size(head) \
({ \
unsigned __list_head_size = 0; \
list_for_each_decl(it, head) __list_head_size += 1; \
__list_head_size; \
})
/// @brief Insert element l2 after l1.
static inline void list_head_insert_after(list_head *l1, list_head *l2)
{ {
// [La]->l1 La<-[l1]->Lb <-[l2]-> l1<-[Lb] head->next = head->prev = head;
list_head *l1_next = l1->next;
// [La]->l1 La<-[l1]->l2 <-[l2]-> l1<-[Lb]
l1->next = l2;
// [La]->l1 La<-[l1]->l2 l1<-[l2]-> l1<-[Lb]
l2->prev = l1;
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l1<-[Lb]
l2->next = l1_next;
// [La]->l1 La<-[l1]->l2 l1<-[l2]->Lb l2<-[Lb]
l1_next->prev = l2;
}
/// @brief Insert element l2 before l1.
static inline void list_head_insert_before(list_head *l1, list_head *l2)
{
// [La]->l1 [l2] La<-[l1]->Lb l1<-[Lb]
list_head *l1_prev = l1->prev;
// [La]->l2 [l2] La<-[l1]->Lb l1<-[Lb]
l1_prev->next = l2;
// [La]->l2 La<-[l2] La<-[l1]->Lb l1<-[Lb]
l2->prev = l1_prev;
// [La]->l2 La<-[l2]->l1 La<-[l1]->Lb l1<-[Lb]
l2->next = l1;
// [La]->l2 La<-[l2]->l1 l2<-[l1]->Lb l1<-[Lb]
l1->prev = l2;
}
/// @brief Remove l from the list.
/// @param l The element to remove.
static inline void list_head_del(list_head *l)
{
// [La]->l La<-[l]->Lb l<-[Lb]
// [La]->Lb La<-[l]->Lb l<-[Lb]
l->prev->next = l->next;
// [La]->Lb La<-[l]->Lb La<-[Lb]
l->next->prev = l->prev;
// [La]->Lb l<-[l]->l La<-[Lb]
l->next = l->prev = l;
} }
/// @brief Tests whether the given list is empty. /// @brief Tests whether the given list is empty.
/// @param head The list to check. /// @param head The list to check.
/// @return 1 if empty, 0 otherwise. /// @return 1 if empty, 0 otherwise.
static inline int list_head_empty(list_head const *head) static inline int list_head_empty(const list_head *head)
{ {
return head->next == head; return head->next == head;
} }
/// Insert a new entry between two known consecutive entries. /// @brief Initializes the list_head.
static inline void __list_add(list_head *new, list_head *prev, list_head *next) /// @param head The head for your list.
static inline unsigned list_head_size(const list_head *head)
{ {
// [prev]-> <-[new]-> <-[next] unsigned size = 0;
if (!list_head_empty(head))
// [prev]-> <-[new]-> new<-[next] list_for_each_decl(it, head) size += 1;
next->prev = new; return size;
// [prev]-> <-[new]->next new<-[next]
new->next = next;
// [prev]-> prev<-[new]->next new<-[next]
new->prev = prev;
// [prev]->new prev<-[new]->next new<-[next]
prev->next = new;
} }
/// @brief Insert element l2 before l1. /// @brief Insert the new entry after the given location.
static inline void list_head_add(list_head *new, list_head *head) /// @param new_entry the new element we want to insert.
/// @param location the element after which we insert.
static inline void list_head_insert_after(list_head *new_entry, list_head *location)
{ {
__list_add(new, head, head->next); // We store the old `next` element.
list_head *old_next = location->next;
// We insert our element.
location->next = new_entry;
// We update the `previous` link of our new entry.
new_entry->prev = location;
// We update the `next` link of our new entry.
new_entry->next = old_next;
// We link the previously `next` element to our new entry.
old_next->prev = new_entry;
} }
/// @brief Insert element l2 before l1. /// @brief Insert the new entry before the given location.
static inline void list_head_add_tail(list_head *new, list_head *head) /// @param new_entry the new element we want to insert.
/// @param location the element after which we insert.
static inline void list_head_insert_before(list_head *new_entry, list_head *location)
{ {
__list_add(new, head->prev, head); // We store the old `previous` element.
list_head *old_prev = location->prev;
// We link the old `previous` element to our new entry.
old_prev->next = new_entry;
// We update the `previous` link of our new entry.
new_entry->prev = old_prev;
// We update the `next` link of our new entry.
new_entry->next = location;
// Finally, we close the link with the old insertion location element.
location->prev = new_entry;
} }
/// @brief Removes an element from the list pointer, it's used when we have a possibly /// @brief Removes the given entry from the list it is contained in.
/// null list pointer and want to pop an element from it /// @param entry the entry we want to remove.
static inline list_head *list_head_pop(list_head *listp) static inline void list_head_remove(list_head *entry)
{ {
if (list_head_empty(listp)) // Check if the element is actually in a list.
return NULL; if (!list_head_empty(entry)) {
// We link the `previous` element to the `next` one.
list_head *value = listp->next; entry->prev->next = entry->next;
list_head_del(listp->next); // We link the `next` element to the `previous` one.
entry->next->prev = entry->prev;
return value; // We initialize the entry again.
list_head_init(entry);
}
} }
static inline list_head *list_head_front(list_head *listp) /// @brief Removes an element from the list, it's used when we have a possibly
/// null list pointer and want to pop an element from it.
/// @param head the head of the list.
/// @return a list_head pointing to the element we removed, NULL on failure.
static inline list_head *list_head_pop(list_head *head)
{ {
return listp->next; // Check if the list is not empty.
if (!list_head_empty(head)) {
// Store the pointer.
list_head *value = head->next;
// Remove the element from the list.
list_head_remove(head->next);
// Return the pointer to the element.
return value;
}
return NULL;
} }
/// Merges the elements of l2, into the elements of l1. /// @brief Append the `secondary` list at the end of the `main` list.
static inline void list_head_merge(list_head *l1, list_head *l2) /// @param main the main list where we append the secondary list.
/// @param secondary the secondary list, which gets appended, and re-initialized as empty.
static inline void list_head_append(list_head *main, list_head *secondary)
{ {
l1->prev->next = l2->next; // Check that both lists are actually filled with entries.
l2->next->prev = l1->prev; if (!list_head_empty(main) && !list_head_empty(secondary)) {
l2->prev->next = l1; // Connect the last element of the main list to the first one of the secondary list.
l1->prev = l2->prev; main->prev->next = secondary->next;
// Initialize the second list. // Connect the first element of the secondary list to the last one of the main list.
list_head_init(l2); secondary->next->prev = main->prev;
// Connect the last element of the secondary list to our main.
secondary->prev->next = main;
// Connect our main to the last element of the secondary list.
main->prev = secondary->prev;
// Re-initialize the secondary list.
list_head_init(secondary);
}
} }
+2 -2
View File
@@ -12,6 +12,6 @@
/// @brief Moves the pointer up. /// @brief Moves the pointer up.
#define __MOVE_PTR_UP(type, ptr) ((ptr) += sizeof(type)) #define __MOVE_PTR_UP(type, ptr) ((ptr) += sizeof(type))
/// @brief First, it moves the pointer down, and then it pushes the value at that memory location. /// @brief First, it moves the pointer down, and then it pushes the value at that memory location.
#define PUSH_VALUE_ON_STACK(ptr, value) (__ACCESS_PTR(typeof(value), __MOVE_PTR_DOWN(typeof(value), ptr)) = (value)) #define PUSH_VALUE_ON_STACK(ptr, value) (__ACCESS_PTR(__typeof__(value), __MOVE_PTR_DOWN(__typeof__(value), ptr)) = (value))
/// @brief First, it access the value at the given memory location, and then it moves the pointer up. /// @brief First, it access the value at the given memory location, and then it moves the pointer up.
#define POP_VALUE_FROM_STACK(value, ptr) ({value = __ACCESS_PTR(typeof(value), ptr); __MOVE_PTR_UP(typeof(value), ptr); }) #define POP_VALUE_FROM_STACK(value, ptr) ({value = __ACCESS_PTR(__typeof__(value), ptr); __MOVE_PTR_UP(__typeof__(value), ptr); })
-1
View File
@@ -162,4 +162,3 @@ static inline int test_bit(int offset, volatile unsigned long *base)
// is discouraged by many C/C++ groups. // is discouraged by many C/C++ groups.
// == xchg/xchgl ============================================================== // == xchg/xchgl ==============================================================
//
+12 -11
View File
@@ -23,29 +23,30 @@
/// @brief Page descriptor. Use as a bitmap to understand the order of the block /// @brief Page descriptor. Use as a bitmap to understand the order of the block
/// and if it is free or allocated. /// and if it is free or allocated.
typedef struct page_t { typedef struct page_t {
/// Array of flags encoding also the zone number to which the page frame /// @brief Array of flags encoding also the zone number to which the page
/// belongs. /// frame belongs.
unsigned long flags; unsigned long flags;
/// Page frames reference counter. 0 free, 1 used, 2+ copy on write /// @brief Page frames reference counter. 0 free, 1 used, 2+ copy on write
atomic_t count; atomic_t count;
/// Buddy system page definition /// @brief Buddy system page definition
bb_page_t bbpage; bb_page_t bbpage;
/// Contains pointers to the slabs doubly linked list of pages. /// @brief Contains pointers to the slabs doubly linked list of pages.
list_head slabs; list_head slabs;
// Slab allocator variables / Contains the total number of objects in this /// @brief Slab allocator variables / Contains the total number of objects
//page, 0 if not managed by the slub /// in this page, 0 if not managed by the slub.
unsigned int slab_objcnt; unsigned int slab_objcnt;
/// Tracks the number of free objects in the current page /// @brief Tracks the number of free objects in the current page
unsigned int slab_objfree; unsigned int slab_objfree;
/// Holds the first free object (if slab_objfree is > 0) /// @brief Holds the first free object (if slab_objfree is > 0)
list_head slab_freelist; list_head slab_freelist;
/// @brief This union can either contain the pointer to the slab main page /// @brief This union can either contain the pointer to the slab main page
/// that handles this page, or the cache that contains it. /// that handles this page, or the cache that contains it.
union { union {
/// Holds the slab page used to handle this memory region (root page) /// @brief Holds the slab page used to handle this memory region (root
/// page).
struct page_t *slab_main_page; struct page_t *slab_main_page;
/// Holds the slab cache pointer on the main page /// @brief Holds the slab cache pointer on the main page.
kmem_cache_t *slab_cache; kmem_cache_t *slab_cache;
} container; } container;
} page_t; } page_t;
+3 -1
View File
@@ -268,13 +268,15 @@ int sys_kill(pid_t pid, int sig);
/// @brief Sets the disposition of the signal signum to handler. /// @brief Sets the disposition of the signal signum to handler.
/// @param signum The signal number. /// @param signum The signal number.
/// @param handler The handler for the signal. /// @param handler The handler for the signal.
/// @param sigreturn_addr The address of the sigreturn function.
/// @return The previous value of the signal handler, or SIG_ERR on error. /// @return The previous value of the signal handler, or SIG_ERR on error.
sighandler_t sys_signal(int signum, sighandler_t handler, uint32_t sigreturn_addr); sighandler_t sys_signal(int signum, sighandler_t handler, uint32_t sigreturn_addr);
/// @brief Examine and change a signal action. /// @brief Examine and change a signal action.
/// @param signum Specifies the signal and can be any valid signal except SIGKILL and SIGSTOP. /// @param signum Specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.
/// @param act If non-NULL, the new action for signal signum is installed from act. /// @param act If non-NULL, the new action for signal signum is installed from act.
/// @param oldact If non-NULL, the previous action is saved in oldact. /// @param oldact If non-NULL, the previous action is saved in oldact.
/// @param sigreturn_addr The address of the sigreturn function.
/// @return returns 0 on success; on error, -1 is returned, and errno is set to indicate the error. /// @return returns 0 on success; on error, -1 is returned, and errno is set to indicate the error.
int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact, uint32_t sigreturn_addr); int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact, uint32_t sigreturn_addr);
+2 -2
View File
@@ -18,10 +18,10 @@
#define OS_MAJOR_VERSION 0 #define OS_MAJOR_VERSION 0
/// Minor version of the operating system. /// Minor version of the operating system.
#define OS_MINOR_VERSION 4 #define OS_MINOR_VERSION 5
/// Micro version of the operating system. /// Micro version of the operating system.
#define OS_MICRO_VERSION 0 #define OS_MICRO_VERSION 4
/// Helper to transform the given argument into a string. /// Helper to transform the given argument into a string.
#define OS_STR_HELPER(x) #x #define OS_STR_HELPER(x) #x
+3 -6
View File
@@ -1,20 +1,17 @@
OUTPUT_FORMAT("elf") OUTPUT_FORMAT("elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(kmain) ENTRY(kmain)
KERNEL_VIRTUAL_ADDRESS = 0xC0000000;
MEMORY { MEMORY {
USER_SPACE : ORIGIN = 0x00000000, LENGTH = 3072M USER_SPACE : ORIGIN = 0x00000000, LENGTH = 3072M
KERNEL_LOWMEM : ORIGIN = KERNEL_VIRTUAL_ADDRESS, LENGTH = 896M KERNEL_LOWMEM : ORIGIN = 0xC0000000, LENGTH = 896M
KERNEL_HIGHMEM : ORIGIN = 0xF8000000, LENGTH = 128M KERNEL_HIGHMEM : ORIGIN = 0xF8000000, LENGTH = 128M
} }
SECTIONS SECTIONS
{ {
. = KERNEL_VIRTUAL_ADDRESS; . = 0xC0000000;
/* Put the .text section. */ /* Put the .text section. */
.text . : AT(ADDR(.text)) .text . : AT(ADDR(.text))
{ {
+3 -3
View File
@@ -51,7 +51,7 @@ static inline irq_struct_t *__irq_struct_alloc()
/// @brief Destroys an irq struct. /// @brief Destroys an irq struct.
static inline void __irq_struct_dealloc(irq_struct_t *irq_struct) static inline void __irq_struct_dealloc(irq_struct_t *irq_struct)
{ {
list_head_del(&irq_struct->siblings); list_head_remove(&irq_struct->siblings);
kmem_cache_free(irq_struct); kmem_cache_free(irq_struct);
} }
@@ -81,7 +81,7 @@ int irq_install_handler(unsigned i, interrupt_handler_t handler, char *descripti
irq_struct->description = description; irq_struct->description = description;
irq_struct->handler = handler; irq_struct->handler = handler;
// Add the handler to the list of his siblings. // Add the handler to the list of his siblings.
list_head_add_tail(&irq_struct->siblings, &shared_interrupt_handlers[i]); list_head_insert_before(&irq_struct->siblings, &shared_interrupt_handlers[i]);
return 0; return 0;
} }
@@ -102,7 +102,7 @@ int irq_uninstall_handler(unsigned i, interrupt_handler_t handler)
irq_struct_t *irq_struct = list_entry(it, irq_struct_t, siblings); irq_struct_t *irq_struct = list_entry(it, irq_struct_t, siblings);
assert(irq_struct && "Something went wrong."); assert(irq_struct && "Something went wrong.");
if (irq_struct->handler == handler) { if (irq_struct->handler == handler) {
list_head_del(&irq_struct->siblings); list_head_remove(&irq_struct->siblings);
} }
__irq_struct_dealloc(irq_struct); __irq_struct_dealloc(irq_struct);
} }
+11 -11
View File
@@ -29,23 +29,23 @@ uint8_t saves[512] __attribute__((aligned(16)));
/// @param cw What to set the control word to. /// @param cw What to set the control word to.
static inline void __set_fpu_cw(const uint16_t cw) static inline void __set_fpu_cw(const uint16_t cw)
{ {
asm volatile("fldcw %0" ::"m"(cw)); __asm__ __volatile__("fldcw %0" ::"m"(cw));
} }
/// @brief Enable the FPU and SSE. /// @brief Enable the FPU and SSE.
static inline void __enable_fpu() static inline void __enable_fpu()
{ {
asm volatile("clts"); __asm__ __volatile__("clts");
size_t t; size_t t;
asm volatile("mov %%cr0, %0" __asm__ __volatile__("mov %%cr0, %0"
: "=r"(t)); : "=r"(t));
t &= ~(1U << 2U); t &= ~(1U << 2U);
t |= (1U << 1U); t |= (1U << 1U);
asm volatile("mov %0, %%cr0" ::"r"(t)); __asm__ __volatile__("mov %0, %%cr0" ::"r"(t));
asm volatile("mov %%cr4, %0" __asm__ __volatile__("mov %%cr4, %0"
: "=r"(t)); : "=r"(t));
t |= 3U << 9U; t |= 3U << 9U;
asm volatile("mov %0, %%cr4" ::"r"(t)); __asm__ __volatile__("mov %0, %%cr4" ::"r"(t));
} }
/// Disable FPU and SSE so it traps to the kernel. /// Disable FPU and SSE so it traps to the kernel.
@@ -53,12 +53,12 @@ static inline void __disable_fpu()
{ {
size_t t; size_t t;
asm volatile("mov %%cr0, %0" __asm__ __volatile__("mov %%cr0, %0"
: "=r"(t)); : "=r"(t));
t |= 1U << 3U; t |= 1U << 3U;
asm volatile("mov %0, %%cr0" ::"r"(t)); __asm__ __volatile__("mov %0, %%cr0" ::"r"(t));
} }
/// @brief Restore the FPU for a process. /// @brief Restore the FPU for a process.
@@ -68,7 +68,7 @@ static inline void __restore_fpu(task_struct *proc)
memcpy(&saves, (uint8_t *)&proc->thread.fpu_register, 512); memcpy(&saves, (uint8_t *)&proc->thread.fpu_register, 512);
asm volatile("fxrstor (%0)" ::"r"(saves)); __asm__ __volatile__("fxrstor (%0)" ::"r"(saves));
} }
/// Save the FPU for a process. /// Save the FPU for a process.
@@ -76,7 +76,7 @@ static inline void __save_fpu(task_struct *proc)
{ {
assert(proc && "Trying to save FPU of NULL process."); assert(proc && "Trying to save FPU of NULL process.");
asm volatile("fxsave (%0)" ::"r"(saves)); __asm__ __volatile__("fxsave (%0)" ::"r"(saves));
memcpy((uint8_t *)&proc->thread.fpu_register, &saves, 512); memcpy((uint8_t *)&proc->thread.fpu_register, &saves, 512);
} }
@@ -84,7 +84,7 @@ static inline void __save_fpu(task_struct *proc)
/// Initialize the FPU. /// Initialize the FPU.
static inline void __init_fpu() static inline void __init_fpu()
{ {
asm volatile("fninit"); __asm__ __volatile__("fninit");
} }
/// Kernel trap for FPU usage when FPU is disabled. /// Kernel trap for FPU usage when FPU is disabled.
+5 -4
View File
@@ -620,6 +620,7 @@ static void ext2_dump_inode(ext2_inode_t *inode)
pr_debug("Symlink : %s\n", inode->data.symlink); pr_debug("Symlink : %s\n", inode->data.symlink);
pr_debug("Generation : %u file_acl : %u dir_acl : %u\n", pr_debug("Generation : %u file_acl : %u dir_acl : %u\n",
inode->generation, inode->file_acl, inode->dir_acl); inode->generation, inode->file_acl, inode->dir_acl);
(void)timeinfo;
} }
/// @brief Dumps on debugging output the dirent. /// @brief Dumps on debugging output the dirent.
@@ -2259,7 +2260,7 @@ static vfs_file_t *ext2_creat(const char *path, mode_t permission)
goto close_parent_return_null; goto close_parent_return_null;
} }
// Add the vfs_file to the list of associated files. // Add the vfs_file to the list of associated files.
list_head_add_tail(&file->siblings, &fs->opened_files); list_head_insert_before(&file->siblings, &fs->opened_files);
} }
return file; return file;
} }
@@ -2378,7 +2379,7 @@ static vfs_file_t *ext2_open(const char *path, int flags, mode_t mode)
return NULL; return NULL;
} }
// Add the vfs_file to the list of associated files. // Add the vfs_file to the list of associated files.
list_head_add_tail(&file->siblings, &fs->opened_files); list_head_insert_before(&file->siblings, &fs->opened_files);
} }
return file; return file;
} }
@@ -2487,7 +2488,7 @@ static int ext2_close(vfs_file_t *file)
} }
pr_debug("ext2_close(ino: %d, file: \"%s\")\n", file->ino, file->name); pr_debug("ext2_close(ino: %d, file: \"%s\")\n", file->ino, file->name);
// Remove the file from the list of opened files. // Remove the file from the list of opened files.
list_head_del(&file->siblings); list_head_remove(&file->siblings);
// Free the cache. // Free the cache.
kmem_cache_free(file); kmem_cache_free(file);
return 0; return 0;
@@ -3040,7 +3041,7 @@ static vfs_file_t *ext2_mount(vfs_file_t *block_device, const char *path)
goto free_all; goto free_all;
} }
// Add the root to the list of opened files. // Add the root to the list of opened files.
list_head_add_tail(&fs->root->siblings, &fs->opened_files); list_head_insert_before(&fs->root->siblings, &fs->opened_files);
// Dump the filesystem details for debugging. // Dump the filesystem details for debugging.
ext2_dump_filesystem(fs); ext2_dump_filesystem(fs);
+7 -7
View File
@@ -253,7 +253,7 @@ static inline procfs_file_t *procfs_create_file(const char *path, unsigned flags
// List of all the PROCFS files. // List of all the PROCFS files.
list_head_init(&procfs_file->siblings); list_head_init(&procfs_file->siblings);
// Add the file to the list of opened files. // Add the file to the list of opened files.
list_head_add_tail(&procfs_file->siblings, &fs.files); list_head_insert_before(&procfs_file->siblings, &fs.files);
// Time of last access. // Time of last access.
procfs_file->atime = sys_time(NULL); procfs_file->atime = sys_time(NULL);
// Time of last data modification. // Time of last data modification.
@@ -282,7 +282,7 @@ static inline int procfs_destroy_file(procfs_file_t *procfs_file)
} }
pr_debug("procfs_destroy_file(%p) `%s`\n", procfs_file, procfs_file->name); pr_debug("procfs_destroy_file(%p) `%s`\n", procfs_file, procfs_file->name);
// Remove the file from the list of opened files. // Remove the file from the list of opened files.
list_head_del(&procfs_file->siblings); list_head_remove(&procfs_file->siblings);
// Free the cache. // Free the cache.
kmem_cache_free(procfs_file); kmem_cache_free(procfs_file);
// Decrease the number of files. // Decrease the number of files.
@@ -467,7 +467,7 @@ static vfs_file_t *procfs_open(const char *path, int flags, mode_t mode)
// Update file access. // Update file access.
procfs_file->atime = sys_time(NULL); procfs_file->atime = sys_time(NULL);
// Add the vfs_file to the list of associated files. // Add the vfs_file to the list of associated files.
list_head_add_tail(&vfs_file->siblings, &procfs_file->files); list_head_insert_before(&vfs_file->siblings, &procfs_file->files);
return vfs_file; return vfs_file;
} }
// Check if the user did not want to open a directory, but it is. // Check if the user did not want to open a directory, but it is.
@@ -486,7 +486,7 @@ static vfs_file_t *procfs_open(const char *path, int flags, mode_t mode)
// Update file access. // Update file access.
procfs_file->atime = sys_time(NULL); procfs_file->atime = sys_time(NULL);
// Add the vfs_file to the list of associated files. // Add the vfs_file to the list of associated files.
list_head_add_tail(&vfs_file->siblings, &procfs_file->files); list_head_insert_before(&vfs_file->siblings, &procfs_file->files);
return vfs_file; return vfs_file;
} }
// When both O_CREAT and O_DIRECTORY are specified in flags and the file // When both O_CREAT and O_DIRECTORY are specified in flags and the file
@@ -508,7 +508,7 @@ static vfs_file_t *procfs_open(const char *path, int flags, mode_t mode)
return NULL; return NULL;
} }
// Add the vfs_file to the list of associated files. // Add the vfs_file to the list of associated files.
list_head_add_tail(&vfs_file->siblings, &procfs_file->files); list_head_insert_before(&vfs_file->siblings, &procfs_file->files);
pr_debug("Created file `%s`.\n", path); pr_debug("Created file `%s`.\n", path);
return vfs_file; return vfs_file;
} }
@@ -523,7 +523,7 @@ static int procfs_close(vfs_file_t *file)
assert(file && "Received null file."); assert(file && "Received null file.");
//pr_debug("procfs_close(%p): VFS file : %p\n", file, file); //pr_debug("procfs_close(%p): VFS file : %p\n", file, file);
// Remove the file from the list of `files` inside its corresponding `procfs_file_t`. // Remove the file from the list of `files` inside its corresponding `procfs_file_t`.
list_head_del(&file->siblings); list_head_remove(&file->siblings);
// Free the memory of the file. // Free the memory of the file.
kmem_cache_free(file); kmem_cache_free(file);
return 0; return 0;
@@ -778,7 +778,7 @@ static vfs_file_t *procfs_mount_callback(const char *path, const char *device)
vfs_file_t *vfs_file = procfs_create_file_struct(procfs_file); vfs_file_t *vfs_file = procfs_create_file_struct(procfs_file);
assert(vfs_file && "Failed to create vfs_file."); assert(vfs_file && "Failed to create vfs_file.");
// Add the vfs_file to the list of associated files. // Add the vfs_file to the list of associated files.
list_head_add_tail(&vfs_file->siblings, &procfs_file->files); list_head_insert_before(&vfs_file->siblings, &procfs_file->files);
// Initialize the proc_root. // Initialize the proc_root.
return vfs_file; return vfs_file;
} }
+1 -1
View File
@@ -416,7 +416,7 @@ int vfs_mount(const char *path, vfs_file_t *new_fs_root)
// Set the pointer. // Set the pointer.
sb->root = new_fs_root; sb->root = new_fs_root;
// Add to the list. // Add to the list.
list_head_add(&sb->mounts, &vfs_super_blocks); list_head_insert_after(&sb->mounts, &vfs_super_blocks);
} }
spinlock_unlock(&vfs_spinlock); spinlock_unlock(&vfs_spinlock);
pr_debug("Correctly mounted '%s' on '%s'...\n", new_fs_root->name, path); pr_debug("Correctly mounted '%s' on '%s'...\n", new_fs_root->name, path);
+10 -7
View File
@@ -229,6 +229,7 @@ static void __print_tvec_slots(tvec_base_t *base, int tv_index)
} }
pr_debug("base->tv%d.vec:\n\t%s\n", tv_index, result); pr_debug("base->tv%d.vec:\n\t%s\n", tv_index, result);
(void) result;
} }
/// Dump all timer vector in base /// Dump all timer vector in base
@@ -314,7 +315,7 @@ static void __add_timer_tvec_base(tvec_base_t *base, struct timer_list *timer)
} }
pr_debug("Adding timer at time_index: %d in tv%d\n", index, tv_index); pr_debug("Adding timer at time_index: %d in tv%d\n", index, tv_index);
list_head_add_tail(&timer->entry, vec); list_head_insert_before(&timer->entry, vec);
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP #ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
__dump_all_tvec_slots(base); __dump_all_tvec_slots(base);
@@ -327,6 +328,7 @@ static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer)
int index = 0, tv_index = 0; int index = 0, tv_index = 0;
__find_tvec(base, timer, &index, &tv_index); __find_tvec(base, timer, &index, &tv_index);
// TODO: Check why we do not use vec.
struct list_head *vec; struct list_head *vec;
switch (tv_index) { switch (tv_index) {
case 1: case 1:
@@ -347,11 +349,12 @@ static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer)
} }
pr_debug("Removing timer at time_index: %d in tv%d\n", index, tv_index); pr_debug("Removing timer at time_index: %d in tv%d\n", index, tv_index);
list_head_del(&timer->entry); list_head_remove(&timer->entry);
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP #ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
__dump_all_tvec_slots(base); __dump_all_tvec_slots(base);
#endif #endif
(void)vec;
} }
/// Move all timers from tv up one level /// Move all timers from tv up one level
@@ -364,7 +367,7 @@ static int cascate(tvec_base_t *base, timer_vec *tv, int time_index, int tv_inde
struct list_head *it, *tmp; struct list_head *it, *tmp;
list_for_each_safe (it, tmp, tv->vec + time_index) { list_for_each_safe (it, tmp, tv->vec + time_index) {
struct timer_list *timer = list_entry(it, struct timer_list, entry); struct timer_list *timer = list_entry(it, struct timer_list, entry);
list_head_del(it); list_head_remove(it);
__add_timer_tvec_base(base, timer); __add_timer_tvec_base(base, timer);
} }
@@ -425,7 +428,7 @@ void run_timer_softirq()
spinlock_lock(&base->lock); spinlock_lock(&base->lock);
// Removes timer from list // Removes timer from list
list_head_del(it); list_head_remove(it);
kfree(timer); kfree(timer);
} }
} }
@@ -453,7 +456,7 @@ void run_timer_softirq()
// Removes timer from list // Removes timer from list
pr_debug("Removing dynamic timer...\n"); pr_debug("Removing dynamic timer...\n");
list_head_del(it); list_head_remove(it);
kfree(timer); kfree(timer);
} }
} }
@@ -479,7 +482,7 @@ void add_timer(struct timer_list *timer)
#ifdef ENABLE_REAL_TIMER_SYSTEM #ifdef ENABLE_REAL_TIMER_SYSTEM
__add_timer_tvec_base(base, timer); __add_timer_tvec_base(base, timer);
#else #else
list_head_add_tail(&timer->entry, &base->list); list_head_insert_before(&timer->entry, &base->list);
#endif #endif
} }
@@ -491,7 +494,7 @@ void del_timer(struct timer_list *timer)
#ifdef ENABLE_REAL_TIMER_SYSTEM #ifdef ENABLE_REAL_TIMER_SYSTEM
__rem_timer_tvec_base(base, timer); __rem_timer_tvec_base(base, timer);
#else #else
list_head_del(&timer->entry); list_head_remove(&timer->entry);
#endif #endif
} }
+1 -1
View File
@@ -57,7 +57,7 @@ inline void outports(uint16_t port, uint16_t data)
void outportsm(uint16_t port, uint8_t *data, uint16_t size) void outportsm(uint16_t port, uint8_t *data, uint16_t size)
{ {
asm volatile("rep outsw" __asm__ __volatile__("rep outsw"
: "+S"(data), "+c"(size) : "+S"(data), "+c"(size)
: "d"(port)); : "d"(port));
} }
+2 -3
View File
@@ -393,11 +393,10 @@ static inline ssize_t __procr_read(vfs_file_t *file, char *buffer, off_t offset,
char support[BUFSIZ]; char support[BUFSIZ];
memset(support, 0, BUFSIZ); memset(support, 0, BUFSIZ);
// Call the specific function. // Call the specific function.
int ret = 0;
if (strcmp(entry->name, "cmdline") == 0) if (strcmp(entry->name, "cmdline") == 0)
ret = __procr_do_cmdline(support, BUFSIZ, task); __procr_do_cmdline(support, BUFSIZ, task);
else if (strcmp(entry->name, "stat") == 0) else if (strcmp(entry->name, "stat") == 0)
ret = __procr_do_stat(support, BUFSIZ, task); __procr_do_stat(support, BUFSIZ, task);
// Copmute the amounts of bytes we want (and can) read. // Copmute the amounts of bytes we want (and can) read.
ssize_t bytes_to_read = max(0, min(strlen(support) - offset, nbyte)); ssize_t bytes_to_read = max(0, min(strlen(support) - offset, nbyte));
// Perform the read. // Perform the read.
+6 -6
View File
@@ -14,12 +14,12 @@ void mutex_lock(mutex_t *mutex, uint32_t owner)
while (mutex->state == 0 || failure || mutex->owner != owner) { while (mutex->state == 0 || failure || mutex->owner != owner) {
failure = 1; failure = 1;
if (mutex->state == 0) { if (mutex->state == 0) {
asm("movl $0x01,%%eax\n\t" // move 1 to eax __asm__ __volatile__("movl $0x01,%%eax\n\t" // move 1 to eax
"xchg %%eax,%0\n\t" // try to set the lock bit "xchg %%eax,%0\n\t" // try to set the lock bit
"mov %%eax,%1\n\t" // export our result to a test var "mov %%eax,%1\n\t" // export our result to a test var
: "=m"(mutex->state), "=r"(failure) : "=m"(mutex->state), "=r"(failure)
: "m"(mutex->state) : "m"(mutex->state)
: "%eax"); : "%eax");
} }
if (failure == 0) { if (failure == 0) {
mutex->owner = owner; //test to see if we got the lock bit mutex->owner = owner; //test to see if we got the lock bit
+4 -4
View File
@@ -112,7 +112,7 @@ ndtree_node_t *ndtree_get_root(ndtree_t *tree)
void ndtree_add_child_to_node(ndtree_t *tree, ndtree_node_t *parent, ndtree_node_t *child) void ndtree_add_child_to_node(ndtree_t *tree, ndtree_node_t *parent, ndtree_node_t *child)
{ {
child->parent = parent; child->parent = parent;
list_head_add(&child->siblings, &parent->children); list_head_insert_after(&child->siblings, &parent->children);
++tree->size; ++tree->size;
} }
@@ -172,7 +172,7 @@ static void __ndtree_tree_dealloc_rec(ndtree_t *tree, ndtree_node_t *node, ndtre
{ {
ndtree_node_t *entry = list_entry(it, ndtree_node_t, siblings); ndtree_node_t *entry = list_entry(it, ndtree_node_t, siblings);
it_save = it->prev; it_save = it->prev;
list_head_del(it); list_head_remove(it);
it = it_save; it = it_save;
__ndtree_tree_dealloc_rec(tree, entry, node_cb); __ndtree_tree_dealloc_rec(tree, entry, node_cb);
} }
@@ -249,7 +249,7 @@ int ndtree_tree_remove_node_with_cb(ndtree_t *tree, ndtree_node_t *node, ndtree_
{ {
if (tree && node) { if (tree && node) {
// Remove the node from the parent list. // Remove the node from the parent list.
list_head_del(&node->siblings); list_head_remove(&node->siblings);
// If the node has children, we need to migrate them. // If the node has children, we need to migrate them.
if (!list_head_empty(&node->children)) { if (!list_head_empty(&node->children)) {
// The new parent, by default it is NULL. // The new parent, by default it is NULL.
@@ -269,7 +269,7 @@ int ndtree_tree_remove_node_with_cb(ndtree_t *tree, ndtree_node_t *node, ndtree_
child->parent = new_parent; child->parent = new_parent;
} }
// Merge the lists. // Merge the lists.
list_head_merge(new_list, &node->children); list_head_append(new_list, &node->children);
} }
if (node_cb) if (node_cb)
node_cb(tree, node); node_cb(tree, node);
+6 -6
View File
@@ -148,7 +148,7 @@ block_found:
page = list_entry(/* ... */, /* ... */, /* ... */); page = list_entry(/* ... */, /* ... */, /* ... */);
// Remove the descriptor of its first page frame. // Remove the descriptor of its first page frame.
list_head_del(&/* ... */); list_head_remove(&/* ... */);
// Set the page as allocated, thus, remove the flag FREE_PAGE. // Set the page as allocated, thus, remove the flag FREE_PAGE.
__bb_clear_flag(/* ... */, /* ... */); __bb_clear_flag(/* ... */, /* ... */);
@@ -182,7 +182,7 @@ block_found:
assert(/* ... */ &&!/* ... */); assert(/* ... */ &&!/* ... */);
// Insert buddy as first element in the list of available blocks (free_list). // Insert buddy as first element in the list of available blocks (free_list).
list_head_add(&/* ... */.siblings, &/* ... */); list_head_insert_after(&/* ... */.siblings, &/* ... */);
// Increase the number of free block of the free_area_t. // Increase the number of free block of the free_area_t.
/* ... */ += 1; /* ... */ += 1;
@@ -277,7 +277,7 @@ void bb_free_pages(bb_instance_t *instance, bb_page_t *page)
/* ... */; /* ... */;
// Insert coalesced as first element in the free list. // Insert coalesced as first element in the free list.
list_head_add(&/* ... */, &/* ... */); list_head_insert_after(&/* ... */, &/* ... */);
// Increase the number of free block of the free_area_t. // Increase the number of free block of the free_area_t.
/* ... */; /* ... */;
@@ -342,7 +342,7 @@ void buddy_system_init(bb_instance_t *instance,
// Set the page as root. // Set the page as root.
__bb_set_flag(page, ROOT_PAGE); __bb_set_flag(page, ROOT_PAGE);
// Insert the page inside the list of free pages of the area. // Insert the page inside the list of free pages of the area.
list_head_add_tail(&page->location.siblings, &area->free_list); list_head_insert_before(&page->location.siblings, &area->free_list);
// Increase the number of free block of the area. // Increase the number of free block of the area.
area->nr_free++; area->nr_free++;
// Move to the next page. // Move to the next page.
@@ -388,7 +388,7 @@ static void __cache_extend(bb_instance_t *instance, int count)
{ {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
bb_page_t *page = bb_alloc_pages(instance, 0); bb_page_t *page = bb_alloc_pages(instance, 0);
list_head_add(&page->location.cache, &instance->free_pages_cache_list); list_head_insert_after(&page->location.cache, &instance->free_pages_cache_list);
instance->free_pages_cache_size++; instance->free_pages_cache_size++;
} }
} }
@@ -417,7 +417,7 @@ static bb_page_t *__cached_alloc(bb_instance_t *instance)
static void __cached_free(bb_instance_t *instance, bb_page_t *page) static void __cached_free(bb_instance_t *instance, bb_page_t *page)
{ {
list_head_add(&page->location.cache, &instance->free_pages_cache_list); list_head_insert_after(&page->location.cache, &instance->free_pages_cache_list);
if (instance->free_pages_cache_size > HIGH_WATERMARK_LEVEL) { if (instance->free_pages_cache_size > HIGH_WATERMARK_LEVEL) {
// Free pages to the buddy system // Free pages to the buddy system
+1 -1
View File
@@ -846,7 +846,6 @@ void kheap_dump()
(char *)it + OVERHEAD + blkmngr_get_real_size(it->size)); (char *)it + OVERHEAD + blkmngr_get_real_size(it->size));
total += blkmngr_get_real_size(it->size); total += blkmngr_get_real_size(it->size);
total_overhead += OVERHEAD; total_overhead += OVERHEAD;
it = it->next; it = it->next;
} }
pr_debug("\nTotal usable bytes : %d", total); pr_debug("\nTotal usable bytes : %d", total);
@@ -857,4 +856,5 @@ void kheap_dump()
pr_debug("(%p)->", it); pr_debug("(%p)->", it);
} }
pr_debug("\n\n"); pr_debug("\n\n");
(void) total, (void) total_overhead;
} }
+9 -9
View File
@@ -104,7 +104,7 @@ uint32_t create_vm_area(mm_struct_t *mm,
new_segment->vm_mm = mm; new_segment->vm_mm = mm;
// Update memory descriptor list of vm_area_struct. // Update memory descriptor list of vm_area_struct.
list_head_add(&new_segment->vm_list, &mm->mmap_list); list_head_insert_after(&new_segment->vm_list, &mm->mmap_list);
mm->mmap_cache = new_segment; mm->mmap_cache = new_segment;
// Update memory descriptor info. // Update memory descriptor info.
@@ -152,7 +152,7 @@ uint32_t clone_vm_area(mm_struct_t *mm, vm_area_struct_t *area, int cow, uint32_
} }
// Update memory descriptor list of vm_area_struct. // Update memory descriptor list of vm_area_struct.
list_head_add(&new_segment->vm_list, &mm->mmap_list); list_head_insert_after(&new_segment->vm_list, &mm->mmap_list);
mm->mmap_cache = new_segment; mm->mmap_cache = new_segment;
// Update memory descriptor info. // Update memory descriptor info.
@@ -165,12 +165,12 @@ uint32_t clone_vm_area(mm_struct_t *mm, vm_area_struct_t *area, int cow, uint32_
static void __init_pagedir(page_directory_t *pdir) static void __init_pagedir(page_directory_t *pdir)
{ {
*pdir = (page_directory_t){ 0 }; *pdir = (page_directory_t){ {0} };
} }
static void __init_pagetable(page_table_t *ptable) static void __init_pagetable(page_table_t *ptable)
{ {
*ptable = (page_table_t){ 0 }; *ptable = (page_table_t){ {0} };
} }
void paging_init(boot_info_t *info) void paging_init(boot_info_t *info)
@@ -221,7 +221,7 @@ static inline void __set_pg_table_flags(page_table_entry_t *table, uint32_t flag
/// @param addr The faulting address. /// @param addr The faulting address.
static void __page_fault_panic(pt_regs *f, uint32_t addr) static void __page_fault_panic(pt_regs *f, uint32_t addr)
{ {
asm volatile("cli"); __asm__ __volatile__("cli");
// Gather fault info and print to screen // Gather fault info and print to screen
pr_err("Faulting address (cr2): 0x%p\n", addr); pr_err("Faulting address (cr2): 0x%p\n", addr);
@@ -250,7 +250,7 @@ static void __page_fault_panic(pt_regs *f, uint32_t addr)
// main_mm->pgd->entries[addr/(1024*4096)].user = 1; // main_mm->pgd->entries[addr/(1024*4096)].user = 1;
// main_directory->entries[addr/(1024*4096)]. = 1; // main_directory->entries[addr/(1024*4096)]. = 1;
asm volatile("cli"); __asm__ __volatile__("cli");
} }
static void __page_handle_cow(page_table_entry_t *entry) static void __page_handle_cow(page_table_entry_t *entry)
@@ -327,8 +327,8 @@ void page_fault_handler(pt_regs *f)
// When the exception occurs, the CPU control unit stores that // When the exception occurs, the CPU control unit stores that
// value in the cr2 control register. // value in the cr2 control register.
uint32_t faulting_addr; uint32_t faulting_addr;
asm volatile("mov %%cr2, %0" __asm__ __volatile__("mov %%cr2, %0"
: "=r"(faulting_addr)); : "=r"(faulting_addr));
// Get the physical address of the current page directory. // Get the physical address of the current page directory.
uint32_t phy_dir = (uint32_t)paging_get_current_directory(); uint32_t phy_dir = (uint32_t)paging_get_current_directory();
// Get the page directory. // Get the page directory.
@@ -607,7 +607,7 @@ void destroy_process_image(mm_struct_t *mm)
// Delete segment from the mmap // Delete segment from the mmap
it = segment->vm_list.next; it = segment->vm_list.next;
list_head_del(&segment->vm_list); list_head_remove(&segment->vm_list);
--mm->map_count; --mm->map_count;
kmem_cache_free(segment); kmem_cache_free(segment);
+13 -13
View File
@@ -71,11 +71,11 @@ static int __alloc_slab_page(kmem_cache_t *cachep, gfp_t flags)
// Build the objects structures // Build the objects structures
for (unsigned int i = 0; i < page->slab_objcnt; i++) { for (unsigned int i = 0; i < page->slab_objcnt; i++) {
kmem_obj *obj = KMEM_OBJ(cachep, pg_addr + cachep->size * i); kmem_obj *obj = KMEM_OBJ(cachep, pg_addr + cachep->size * i);
list_head_add(&obj->objlist, &page->slab_freelist); list_head_insert_after(&obj->objlist, &page->slab_freelist);
} }
// Add the page to the slab list and update the counters // Add the page to the slab list and update the counters
list_head_add(&page->slabs, &cachep->slabs_free); list_head_insert_after(&page->slabs, &cachep->slabs_free);
cachep->total_num += page->slab_objcnt; cachep->total_num += page->slab_objcnt;
cachep->free_num += page->slab_objcnt; cachep->free_num += page->slab_objcnt;
@@ -132,7 +132,7 @@ static void __kmem_cache_create(kmem_cache_t *cachep, const char *name, unsigned
__kmem_cache_refill(cachep, start_count, flags); __kmem_cache_refill(cachep, start_count, flags);
list_head_add(&cachep->cache_list, &kmem_caches_list); list_head_insert_after(&cachep->cache_list, &kmem_caches_list);
} }
static inline void *__kmem_cache_alloc_slab(kmem_cache_t *cachep, page_t *slab_page) static inline void *__kmem_cache_alloc_slab(kmem_cache_t *cachep, page_t *slab_page)
@@ -161,7 +161,7 @@ static inline void __kmem_cache_free_slab(kmem_cache_t *cachep, page_t *slab_pag
cachep->free_num -= slab_page->slab_objfree; cachep->free_num -= slab_page->slab_objfree;
cachep->total_num -= slab_page->slab_objcnt; cachep->total_num -= slab_page->slab_objcnt;
// Clear objcnt, used as a flag to check if the page belongs to the slab // Clear objcnt, used as a flag to check if the page belongs to the slab
slab_page->slab_objcnt = 0; slab_page->slab_objcnt = 0;
slab_page->container.slab_main_page = NULL; slab_page->container.slab_main_page = NULL;
// Reset all non-root slab pages // Reset all non-root slab pages
@@ -225,7 +225,7 @@ void kmem_cache_destroy(kmem_cache_t *cachep)
} }
kmem_cache_free(cachep); kmem_cache_free(cachep);
list_head_del(&cachep->cache_list); list_head_remove(&cachep->cache_list);
} }
#ifdef ENABLE_CACHE_TRACE #ifdef ENABLE_CACHE_TRACE
@@ -251,16 +251,16 @@ void *kmem_cache_alloc(kmem_cache_t *cachep, gfp_t flags)
// Add a free slab to partial list because in any case an element will // Add a free slab to partial list because in any case an element will
// be removed before the function returns // be removed before the function returns
list_head *free_slab = list_head_pop(&cachep->slabs_free); list_head *free_slab = list_head_pop(&cachep->slabs_free);
list_head_add(free_slab, &cachep->slabs_partial); list_head_insert_after(free_slab, &cachep->slabs_partial);
} }
page_t *slab_page = list_entry(list_head_front(&cachep->slabs_partial), page_t, slabs); page_t *slab_page = list_entry(cachep->slabs_partial.next, page_t, slabs);
void *ptr = __kmem_cache_alloc_slab(cachep, slab_page); void *ptr = __kmem_cache_alloc_slab(cachep, slab_page);
// If the slab is now full, add it to the full slabs list // If the slab is now full, add it to the full slabs list
if (slab_page->slab_objfree == 0) { if (slab_page->slab_objfree == 0) {
list_head *slab_full_elem = list_head_pop(&cachep->slabs_partial); list_head *slab_full_elem = list_head_pop(&cachep->slabs_partial);
list_head_add(slab_full_elem, &cachep->slabs_full); list_head_insert_after(slab_full_elem, &cachep->slabs_full);
} }
#ifdef ENABLE_CACHE_TRACE #ifdef ENABLE_CACHE_TRACE
pr_notice("CHACE-ALLOC 0x%p in %-20s at %s:%d\n", ptr, cachep->name, file, line); pr_notice("CHACE-ALLOC 0x%p in %-20s at %s:%d\n", ptr, cachep->name, file, line);
@@ -292,23 +292,23 @@ void kmem_cache_free(void *ptr)
kmem_obj *obj = KMEM_OBJ(cachep, ptr); kmem_obj *obj = KMEM_OBJ(cachep, ptr);
// Add object to the free list // Add object to the free list
list_head_add(&obj->objlist, &slab_page->slab_freelist); list_head_insert_after(&obj->objlist, &slab_page->slab_freelist);
slab_page->slab_objfree++; slab_page->slab_objfree++;
cachep->free_num++; cachep->free_num++;
// Now page is completely free // Now page is completely free
if (slab_page->slab_objfree == slab_page->slab_objcnt) { if (slab_page->slab_objfree == slab_page->slab_objcnt) {
// Remove page from partial list // Remove page from partial list
list_head_del(&slab_page->slabs); list_head_remove(&slab_page->slabs);
// Add page to free list // Add page to free list
list_head_add(&slab_page->slabs, &cachep->slabs_free); list_head_insert_after(&slab_page->slabs, &cachep->slabs_free);
} }
// Now page is not full, so change its list // Now page is not full, so change its list
else if (slab_page->slab_objfree == 1) { else if (slab_page->slab_objfree == 1) {
// Remove page from full list // Remove page from full list
list_head_del(&slab_page->slabs); list_head_remove(&slab_page->slabs);
// Add page to partial list // Add page to partial list
list_head_add(&slab_page->slabs, &cachep->slabs_partial); list_head_insert_after(&slab_page->slabs, &cachep->slabs_partial);
} }
} }
+1 -1
View File
@@ -171,7 +171,7 @@ static inline task_struct *__alloc_task(task_struct *source, task_struct *parent
// If we have a parent, set the sibling child relation. // If we have a parent, set the sibling child relation.
if (parent) { if (parent) {
// Set the new_process as child of current. // Set the new_process as child of current.
list_head_add_tail(&proc->sibling, &parent->children); list_head_insert_before(&proc->sibling, &parent->children);
} }
if (source) if (source)
memcpy(&proc->thread, &source->thread, sizeof(thread_struct_t)); memcpy(&proc->thread, &source->thread, sizeof(thread_struct_t));
+4 -4
View File
@@ -108,7 +108,7 @@ void scheduler_enqueue_task(task_struct *process)
runqueue.curr = process; runqueue.curr = process;
} }
// Add the new process at the end. // Add the new process at the end.
list_head_add_tail(&process->run_list, &runqueue.queue); list_head_insert_before(&process->run_list, &runqueue.queue);
// Increment the number of active processes. // Increment the number of active processes.
++runqueue.num_active; ++runqueue.num_active;
} }
@@ -116,7 +116,7 @@ void scheduler_enqueue_task(task_struct *process)
void scheduler_dequeue_task(task_struct *process) void scheduler_dequeue_task(task_struct *process)
{ {
// Delete the process from the list of running processes. // Delete the process from the list of running processes.
list_head_del(&process->run_list); list_head_remove(&process->run_list);
// Decrement the number of active processes. // Decrement the number of active processes.
--runqueue.num_active; --runqueue.num_active;
if (process->se.is_periodic) if (process->se.is_periodic)
@@ -484,7 +484,7 @@ pid_t sys_waitpid(pid_t pid, int *status, int options)
// Finalize the VFS structures. // Finalize the VFS structures.
vfs_destroy_task(entry); vfs_destroy_task(entry);
// Remove entry from children of parent. // Remove entry from children of parent.
list_head_del(&entry->sibling); list_head_remove(&entry->sibling);
// Remove entry from the scheduling queue. // Remove entry from the scheduling queue.
scheduler_dequeue_task(entry); scheduler_dequeue_task(entry);
// Delete the task_struct. // Delete the task_struct.
@@ -535,7 +535,7 @@ void sys_exit(int exit_code)
} }
pr_debug("}\n"); pr_debug("}\n");
// Plug the list of children. // Plug the list of children.
list_head_merge(&init_proc->children, &runqueue.curr->children); list_head_append(&init_proc->children, &runqueue.curr->children);
// Print the list of children. // Print the list of children.
pr_debug("New list of init children (%d): {\n", init_proc->pid); pr_debug("New list of init children (%d): {\n", init_proc->pid);
list_for_each_decl(it, &init_proc->children) list_for_each_decl(it, &init_proc->children)
+109 -46
View File
@@ -22,78 +22,136 @@
/// @param task the task to update. /// @param task the task to update.
static void __update_task_statistics(task_struct *task); static void __update_task_statistics(task_struct *task);
/// @brief Checks if the given task is actually a periodic task.
/// @param task the task to check.
/// @return true if the task is periodic, false otherwise.
static inline bool_t __is_periodic_task(task_struct *task)
{
// Check if the task is a periodic one and it is not under analysis.
return task->se.is_periodic && !task->se.is_under_analysis;
}
/// @brief Employs time-sharing, giving each job a timeslice, and is also /// @brief Employs time-sharing, giving each job a timeslice, and is also
/// preemptive since the scheduler forces the task out of the CPU once /// preemptive since the scheduler forces the task out of the CPU once
/// the timeslice expires. /// the timeslice expires.
/// @param runqueue list of all processes. /// @param runqueue list of all processes.
/// @param skip_periodic tells the algorithm if there are periodic processes /// @param skip_periodic tells the algorithm if there are periodic processes in
/// in the list, and in that case it needs to skip them. /// the list, and in that case it needs to skip them.
/// @return the next task on success, NULL on failure. /// @return the next task on success, NULL on failure.
static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_periodic) static inline task_struct *__scheduler_rr(runqueue_t *runqueue, bool_t skip_periodic)
{ {
// If there is just one task, return it. // If there is just one task, return it; no need to do anything.
if ((runqueue->curr->run_list.next == &runqueue->queue) && if (list_head_size(&runqueue->curr->run_list) <= 1) {
(runqueue->curr->run_list.prev == &runqueue->queue)) {
return runqueue->curr; return runqueue->curr;
} }
// By default, the next task is the current one. // Search for the next task (we do not start from the head, so INSIDE, skip the head).
task_struct *next = NULL, *entry = NULL;
// Search for the next task (BEWARE: We do not start from the head, so INSIDE skip the head).
list_for_each_decl(it, &runqueue->curr->run_list) list_for_each_decl(it, &runqueue->curr->run_list)
{ {
// Check if we reached the head of list_head, and skip it. // Check if we reached the head of list_head, and skip it.
if (it == &runqueue->queue) if (it == &runqueue->queue)
continue; continue;
// Get the current entry. // Get the current entry.
entry = list_entry(it, task_struct, run_list); task_struct *entry = list_entry(it, task_struct, run_list);
// We consider only runnable processes // We consider only runnable processes
if (entry->state != TASK_RUNNING) if (entry->state != TASK_RUNNING)
continue; continue;
// If entry is a periodic task, and we were asked to skip periodic tasks, skip it.
// Skip the task if it is a periodic one, we are issued to skip if (__is_periodic_task(entry) && skip_periodic)
// periodic tasks, and the entry is not a periodic task under
// analysis.
if (entry->se.is_periodic && skip_periodic && !entry->se.is_under_analysis)
continue; continue;
// We have our next entry. // We have our next entry.
next = entry; return entry;
break;
} }
return next; return NULL;
} }
/// @brief Is a non-preemptive algorithm, where each task is assigned a /// @brief Is a non-preemptive algorithm, where each task is assigned a
/// priority. Processes with highest priority are executed first, while /// priority. Processes with highest priority are executed first, while
/// processes with same priority are executed on first-come/first-served /// processes with same priority are executed on first-come/first-served basis.
/// basis. Priority can be decided based on memory requirements, time /// Priority can be decided based on memory requirements, time requirements or
/// requirements or any other resource requirement. /// any other resource requirement.
/// @param runqueue list of all processes. /// @param runqueue list of all processes.
/// @param skip_periodic tells the algorithm if there are periodic processes /// @param skip_periodic tells the algorithm if there are periodic processes in
/// in the list, and in that case it needs to skip them. /// the list, and in that case it needs to skip them.
/// @return the next task on success, NULL on failure. /// @return the next task on success, NULL on failure.
static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t skip_periodic) static inline task_struct *__scheduler_priority(runqueue_t *runqueue, bool_t skip_periodic)
{ {
#ifdef SCHEDULER_PRIORITY
// Get the first element of the list.
task_struct *next = list_entry(runqueue->queue.next, struct task_struct, run_list);
// Get its static priority.
time_t min = /*...*/;
// Search for the task with the smallest static priority.
list_for_each_decl(it, &runqueue->curr->run_list)
{
// Check if we reached the head of list_head, and skip it.
if (it == &runqueue->queue)
continue;
// Get the current entry.
task_struct *entry = list_entry(it, task_struct, run_list);
// We consider only runnable processes
if (entry->state != TASK_RUNNING)
continue;
// If entry is a periodic task, and we were asked to skip periodic tasks, skip it.
if (__is_periodic_task(entry) && skip_periodic)
continue;
// Check if the entry has a lower priority.
if (/*...*/) {
// Chose the `entry` as the `next` task.
/*...*/
}
}
return next;
#else
return __scheduler_rr(runqueue, skip_periodic); return __scheduler_rr(runqueue, skip_periodic);
#endif
} }
/// @brief It aims at giving a fair share of CPU time to processes, and /// @brief It aims at giving a fair share of CPU time to processes, and achieves
/// achieves that by associating a virtual runtime to each of them. It always /// that by associating a virtual runtime to each of them. It always tries to
/// tries to run the task with the smallest vruntime (i.e., the task which /// run the task with the smallest vruntime (i.e., the task which executed least
/// executed least so far). It always tries to split up CPU time between /// so far). It always tries to split up CPU time between runnable tasks as
/// runnable tasks as close to "ideal multitasking hardware" as possible. /// close to "ideal multitasking hardware" as possible.
/// @param runqueue list of all processes. /// @param runqueue list of all processes.
/// @param skip_periodic tells the algorithm if there are periodic processes /// @param skip_periodic tells the algorithm if there are periodic processes in
/// in the list, and in that case it needs to skip them. /// the list, and in that case it needs to skip them.
/// @return the next task on success, NULL on failure. /// @return the next task on success, NULL on failure.
static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_periodic) static inline task_struct *__scheduler_cfs(runqueue_t *runqueue, bool_t skip_periodic)
{ {
#ifdef SCHEDULER_CFS
// Get the first element of the list.
task_struct *next = list_entry(runqueue->queue.next, struct task_struct, run_list);
// Get its virtual runtime.
time_t min = /* ... */;
// Search for the task with the smallest vruntime value.
list_for_each_decl(it, &runqueue->curr->run_list)
{
// Check if we reached the head of list_head, and skip it.
if (it == &runqueue->queue)
continue;
// Get the current entry.
task_struct *entry = list_entry(it, task_struct, run_list);
// We consider only runnable processes
if (entry->state != TASK_RUNNING)
continue;
// If entry is a periodic task, and we were asked to skip periodic tasks, skip it.
if (__is_periodic_task(entry) && skip_periodic)
continue;
// Check if the element in the list has a smaller vruntime value.
/* ... */
}
return next;
#else
return __scheduler_rr(runqueue, skip_periodic); return __scheduler_rr(runqueue, skip_periodic);
#endif
} }
/// @brief Executes the task with the earliest absolute deadline among all /// @brief Executes the task with the earliest absolute deadline among all the
/// the ready tasks. /// ready tasks.
/// @param runqueue list of all processes. /// @param runqueue list of all processes.
/// @return the next task on success, NULL on failure. /// @return the next task on success, NULL on failure.
static inline task_struct *__scheduler_aedf(runqueue_t *runqueue) static inline task_struct *__scheduler_aedf(runqueue_t *runqueue)
@@ -101,10 +159,10 @@ static inline task_struct *__scheduler_aedf(runqueue_t *runqueue)
return __scheduler_rr(runqueue, false); return __scheduler_rr(runqueue, false);
} }
/// @brief Executes the task with the earliest absolute DEADLINE among all /// @brief Executes the task with the earliest absolute DEADLINE among all the
/// the ready tasks. When a task was executed, and its period is starting /// ready tasks. When a task was executed, and its period is starting again, it
/// again, it must be set as 'executable again', and its deadline and next_period /// must be set as 'executable again', and its deadline and next_period must be
/// must be updated. /// updated.
/// @param runqueue list of all processes. /// @param runqueue list of all processes.
/// @return the next task on success, NULL on failure. /// @return the next task on success, NULL on failure.
static inline task_struct *__scheduler_edf(runqueue_t *runqueue) static inline task_struct *__scheduler_edf(runqueue_t *runqueue)
@@ -112,11 +170,11 @@ static inline task_struct *__scheduler_edf(runqueue_t *runqueue)
return __scheduler_rr(runqueue, false); return __scheduler_rr(runqueue, false);
} }
/// @brief Executes the task with the earliest next PERIOD among all the /// @brief Executes the task with the earliest next PERIOD among all the ready
/// ready tasks. /// tasks.
/// @details When a task was executed, and its period is starting again, it /// @details When a task was executed, and its period is starting again, it must
/// must be set as 'executable again', and its deadline and next_period must /// be set as 'executable again', and its deadline and next_period must be
/// be updated. /// updated.
/// @param runqueue list of all processes. /// @param runqueue list of all processes.
/// @return the next task on success, NULL on failure. /// @return the next task on success, NULL on failure.
static inline task_struct *__scheduler_rm(runqueue_t *runqueue) static inline task_struct *__scheduler_rm(runqueue_t *runqueue)
@@ -157,6 +215,8 @@ task_struct *scheduler_pick_next_task(runqueue_t *runqueue)
static void __update_task_statistics(task_struct *task) static void __update_task_statistics(task_struct *task)
{ {
// See `prio.h` for more support functions.
#if defined(SCHEDULER_CFS) || defined(SCHEDULER_EDF) || defined(SCHEDULER_RM) || defined(SCHEDULER_AEDF)
assert(task && "Current task is not valid."); assert(task && "Current task is not valid.");
// While periodic task is under analysis is executed with aperiodic // While periodic task is under analysis is executed with aperiodic
@@ -165,6 +225,8 @@ static void __update_task_statistics(task_struct *task)
// if is a more pessimistic evaluation. // if is a more pessimistic evaluation.
// Update the delta exec. // Update the delta exec.
task->se.exec_runtime = timer_get_ticks() - task->se.exec_start; task->se.exec_runtime = timer_get_ticks() - task->se.exec_start;
// Perform timer-related checks.
update_process_profiling_timer(task); update_process_profiling_timer(task);
// Set the sum_exec_runtime. // Set the sum_exec_runtime.
@@ -173,15 +235,16 @@ static void __update_task_statistics(task_struct *task)
// If the task is not a periodic task we have to update the virtual runtime. // If the task is not a periodic task we have to update the virtual runtime.
if (!task->se.is_periodic) { if (!task->se.is_periodic) {
// Get the weight of the current task. // Get the weight of the current task.
time_t weight = GET_WEIGHT(task->se.prio); time_t weight = /* ... */;
// If the weight is different from the default load, compute it. // If the weight is different from the default load, compute it.
if (weight != NICE_0_LOAD) { if (weight != NICE_0_LOAD) {
// Get the multiplicative factor for its delta_exec. // Get the multiplicative factor for its delta_exec.
double factor = ((double)NICE_0_LOAD) / ((double)weight); double factor = /* ... */;
// Weight the delta_exec with the multiplicative factor. // Weight the delta_exec with the multiplicative factor.
task->se.exec_runtime = (int)(((double)task->se.exec_runtime) * factor); task->se.exec_runtime = /* ... */;
} }
// Update vruntime of the current task. // Update vruntime of the current task.
task->se.vruntime += task->se.exec_runtime; task->se.vruntime += /* ... */;
} }
#endif
} }
+2 -2
View File
@@ -14,12 +14,12 @@
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq) static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq)
{ {
list_head_add_tail(&wq->task_list, &head->task_list); list_head_insert_before(&wq->task_list, &head->task_list);
} }
static inline void __remove_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq) static inline void __remove_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq)
{ {
list_head_del(&wq->task_list); list_head_remove(&wq->task_list);
} }
void init_waitqueue_entry(wait_queue_entry_t *wq, struct task_struct *task) void init_waitqueue_entry(wait_queue_entry_t *wq, struct task_struct *task)
+2 -2
View File
@@ -10,6 +10,6 @@ void kernel_panic(const char *msg)
{ {
pr_emerg("\nPANIC:\n%s\n\nWelcome to Kernel Debugging Land...\n\n", msg); pr_emerg("\nPANIC:\n%s\n\nWelcome to Kernel Debugging Land...\n\n", msg);
pr_emerg("\n"); pr_emerg("\n");
asm("cli"); // Disable interrupts __asm__ __volatile__("cli"); // Disable interrupts
for (;;) asm("hlt"); // Decrease power consumption with hlt for (;;) __asm__ __volatile__("hlt"); // Decrease power consumption with hlt
} }
+3 -3
View File
@@ -157,7 +157,7 @@ static int __send_signal(int sig, siginfo_t *info, struct task_struct *t)
__unlock_task_sighand(t); __unlock_task_sighand(t);
return -EAGAIN; return -EAGAIN;
} }
list_head_add_tail(&q->list, &t->pending.list); list_head_insert_before(&q->list, &t->pending.list);
if (info != SEND_SIG_NOINFO) if (info != SEND_SIG_NOINFO)
memcpy(&q->info, info, sizeof(siginfo_t)); memcpy(&q->info, info, sizeof(siginfo_t));
// Set that there is a signal pending. // Set that there is a signal pending.
@@ -219,7 +219,7 @@ static inline void __collect_signal(int sig, sigpending_t *list, siginfo_t *info
if (queue_entry) { if (queue_entry) {
pr_debug("__collect_signal(%d, %p, %p) : Remove and delete sigqueue entry : %p.\n", sig, list, info, queue_entry); pr_debug("__collect_signal(%d, %p, %p) : Remove and delete sigqueue entry : %p.\n", sig, list, info, queue_entry);
// Remove the entry from the queue. // Remove the entry from the queue.
list_head_del(&queue_entry->list); list_head_remove(&queue_entry->list);
// Copy the details about the entry inside the info structure. // Copy the details about the entry inside the info structure.
__copy_siginfo(info, &queue_entry->info); __copy_siginfo(info, &queue_entry->info);
// Free the memory for the queue entry. // Free the memory for the queue entry.
@@ -346,7 +346,7 @@ static void __rm_from_queue(sigset_t *mask, sigpending_t *q)
int sig = entry->info.si_signo; int sig = entry->info.si_signo;
if (sigismember(mask, sig)) { if (sigismember(mask, sig)) {
list_head_del(it); list_head_remove(it);
kfree(entry); kfree(entry);
} }
} }
+2 -1
View File
@@ -25,7 +25,8 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-but-set-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument")
# Set the compiler options. # Set the compiler options.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
+1 -1
View File
@@ -19,7 +19,7 @@ int main(int argc, char **argv)
} }
// Check if `--help` is provided. // Check if `--help` is provided.
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--help") == 0) { if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-h") == 0)) {
printf("Prints the content of the given file.\n"); printf("Prints the content of the given file.\n");
printf("Usage:\n"); printf("Usage:\n");
printf(" cat <file>\n\n"); printf(" cat <file>\n\n");
+48 -29
View File
@@ -12,24 +12,15 @@
#define CTRL_KEY(k) ((k)&0x1f) #define CTRL_KEY(k) ((k)&0x1f)
#define BUFFER_SIZE 4096 #define BUFFER_SIZE 4096
static struct termios _original_termios, _termios; static inline void __set_echo(bool_t active)
static inline void die(const char *s)
{ {
printf("error: %s\n", s); struct termios _termios;
exit(1); tcgetattr(STDIN_FILENO, &_termios);
} if (active) {
_termios.c_lflag |= (ICANON | ECHO);
static inline void disable_raw_mode() } else {
{ _termios.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, 0, &_original_termios); }
}
static inline void enable_raw_mode()
{
tcgetattr(STDIN_FILENO, &_original_termios);
_termios = _original_termios;
_termios.c_lflag &= ~(ICANON | ECHO | IEXTEN | ISIG);
tcsetattr(STDIN_FILENO, 0, &_termios); tcsetattr(STDIN_FILENO, 0, &_termios);
} }
@@ -72,33 +63,61 @@ int main(int argc, char *argv[])
// Close the file descriptor. // Close the file descriptor.
close(fd); close(fd);
enable_raw_mode(); struct termios _termios;
tcgetattr(STDIN_FILENO, &_termios);
_termios.c_lflag &= ~ISIG;
tcsetattr(STDIN_FILENO, 0, &_termios);
__set_echo(false);
int c;
do { do {
c = getchar(); int c = getchar();
// Return Key // Return Key
if (c == '\n') { if (c == '\n') {
putchar('\n'); putchar('\n');
// Break the while loop.
continue;
} else if (c == '\033') { } else if (c == '\033') {
c = getchar(); c = getchar();
if (c == '[') { if (c == '[') {
c = getchar(); c = getchar(); // Get the char.
if (c == 'D') { if ((c == 'A') || (c == 'B')) {
puts("\033[1D"); pr_debug("UP\n");
} else if (c == 'D') {
pr_debug("RIGHT\n");
} else if (c == 'C') { } else if (c == 'C') {
puts("\033[1C"); pr_debug("LEFT\n");
} else if (c == 'H') { } else if (c == 'H') {
printf("\033[%dD", 0); pr_debug("HOME\n");
} else if (c == 'F') { } else if (c == 'F') {
printf("\033[%dC", 60); pr_debug("END\n");
} else if (c == '3') {
pr_debug("NO-IDEA\n");
} }
} }
} else { } else if (c == '\b') {
putchar('\b');
} else if (c == '\t') {
pr_debug("TAB\n");
} else if (c == 127) {
pr_debug("127\n");
putchar(127);
} else if (iscntrl(c)) {
if (c == CTRL('C')) {
pr_debug("CTRL(C)\n");
break;
} else if (c == CTRL('U')) {
pr_debug("CTRL(U)\n");
} else if (c == CTRL('D')) {
pr_debug("CTRL(D)\n");
}
} else if ((c > 0) && (c != '\n')) {
putchar(c); putchar(c);
} else {
pr_debug("Unrecognized character %02x (%c)\n", c, c);
} }
} while (c != 'q'); } while (true);
disable_raw_mode(); __set_echo(true);
return 0; return 0;
} }
+2
View File
@@ -205,6 +205,8 @@ int main(int argc, char **argv)
// Set the user id. // Set the user id.
setuid(pwd->pw_uid); setuid(pwd->pw_uid);
printf("\n");
// Print /etc/motd if it exists. // Print /etc/motd if it exists.
__print_message_file("/etc/motd"); __print_message_file("/etc/motd");
+5 -7
View File
@@ -122,18 +122,16 @@ int main(int argc, char *argv[])
uint32_t flags = 0; uint32_t flags = 0;
// Check the number of arguments. // Check the number of arguments.
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--help") == 0) { if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-h") == 0)) {
printf("List information about files inside a given directory.\n"); printf("List information about files inside a given directory.\n");
printf("Usage:\n"); printf("Usage:\n");
printf(" ls [options] [directory]\n\n"); printf(" ls [options] [directory]\n\n");
return 0; return 0;
} else if (argv[i][0] == '-') { } else if (argv[i][0] == '-') {
for (int j = 0; j < strlen(argv[i]); ++j) { if ((strcmp(argv[i], "-l") == 0) || (strcmp(argv[i], "--long") == 0))
if (argv[i][j] == 'l') bitmask_set_assign(flags, FLAG_L);
bitmask_set_assign(flags, FLAG_L); else if ((strcmp(argv[i], "-a") == 0) || (strcmp(argv[i], "--all") == 0))
else if (argv[i][j] == 'a') bitmask_set_assign(flags, FLAG_A);
bitmask_set_assign(flags, FLAG_A);
}
} }
} }
+2 -1
View File
@@ -25,7 +25,8 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-but-set-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument")
# Set the compiler options. # Set the compiler options.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
+1 -1
View File
@@ -11,7 +11,7 @@
#include <strerror.h> #include <strerror.h>
#include <sys/wait.h> #include <sys/wait.h>
#define cpu_relax() asm volatile("pause\n" \ #define cpu_relax() __asm__ __volatile__("pause\n" \
: \ : \
: \ : \
: "memory") : "memory")
+1
View File
@@ -46,4 +46,5 @@ int main(int argc, char *argv[])
d /= e; d /= e;
e -= 1; e -= 1;
} }
printf("d: %d, e: %d\n", d, e);
} }
+1
View File
@@ -47,4 +47,5 @@ int main(int argc, char *argv[])
d /= e; d /= e;
e -= 1; e -= 1;
} }
printf("d: %d, e: %d\n", d, e);
} }