Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9cbc8e8a61 | |||
| 24367a58ae | |||
| f40c4a6630 | |||
| 7ad283d36a | |||
| e630f89547 | |||
| 34eeedcbcf | |||
| 90ab346195 | |||
| 5ce583fdd8 | |||
| c2f660f885 | |||
| 80af9c93fb | |||
| 8b678be2b7 | |||
| ef92ba670b | |||
| 6f4d3b57f9 | |||
| 13441daa37 | |||
| dd39e93194 | |||
| 275cbbe7b3 | |||
| 290ed59d0b | |||
| 3e51197ae4 | |||
| 3d49f0abf6 | |||
| 391bba92a6 | |||
| e96c13ff70 | |||
| 9ef117cbc6 | |||
| af95af6f3a | |||
| d2fd6654eb | |||
| 3fcc0f8964 | |||
| 327e29791e | |||
| f24b962e2b | |||
| 40e4faad90 | |||
| f4c35a09de | |||
| 42d84be2c3 | |||
| 28c00fd9ed | |||
| 379950fb45 | |||
| 4292149567 | |||
| 030c16d29e | |||
| 29e9d2ff11 | |||
| 24b2182bec | |||
| a8cfac3c1f | |||
| 654a3165c0 | |||
| c8544ad6a4 | |||
| 61e6954265 | |||
| 237bfcefb3 | |||
| b7c32fc102 | |||
| 2ec77db77a |
@@ -1,36 +0,0 @@
|
|||||||
name: MacOS
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- "releases/**"
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
- ".gitignore"
|
|
||||||
- "**/ubuntu.yml"
|
|
||||||
- "**/windows.yml"
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
- ".gitignore"
|
|
||||||
- "**/ubuntu.yml"
|
|
||||||
- "**/windows.yml"
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Build
|
|
||||||
runs-on: macos-latest
|
|
||||||
# Set environment variables
|
|
||||||
#env:
|
|
||||||
# We globally set CC and CXX.
|
|
||||||
# CC: x86_64-elf-gcc
|
|
||||||
# CXX: x86_64-elf-g++
|
|
||||||
steps:
|
|
||||||
- name: Clone repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
brew install git cmake nasm
|
|
||||||
# x86_64-elf-binutils x86_64-elf-gcc
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
cmake -B build
|
|
||||||
cmake --build build --parallel 2
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
name: Windows
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- "releases/**"
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
- ".gitignore"
|
|
||||||
- "**/macos.yml"
|
|
||||||
- "**/ubuntu.yml"
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
- ".gitignore"
|
|
||||||
- "**/macos.yml"
|
|
||||||
- "**/ubuntu.yml"
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: Build
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- name: Clone repo
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
choco install nasm
|
|
||||||
echo "C:\Program Files\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
|
||||||
- name: Set up MinGW
|
|
||||||
uses: egor-tensin/setup-mingw@v2
|
|
||||||
with:
|
|
||||||
version: latest
|
|
||||||
platform: x32
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
cmake -B build
|
|
||||||
cmake --build build --parallel 2
|
|
||||||
+69
-23
@@ -61,6 +61,54 @@ else()
|
|||||||
set(CMAKE_LINKER ld)
|
set(CMAKE_LINKER ld)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Enable the assembly language.
|
||||||
|
enable_language(ASM)
|
||||||
|
# Find the NASM compiler.
|
||||||
|
find_program(ASM_COMPILER NAMES nasm HINTS /usr/bin/ /usr/local/bin/)
|
||||||
|
# Mark the variable ASM_COMPILER as advanced.
|
||||||
|
mark_as_advanced(ASM_COMPILER)
|
||||||
|
# Check that we have found the compiler.
|
||||||
|
if(NOT ASM_COMPILER)
|
||||||
|
message(FATAL_ERROR "ASM compiler not found!")
|
||||||
|
endif(NOT ASM_COMPILER)
|
||||||
|
|
||||||
|
# Set the assembly compiler flags.
|
||||||
|
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -m32")
|
||||||
|
# Warning flags.
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
||||||
|
# Disable some specific warnings.
|
||||||
|
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-unknown-pragmas")
|
||||||
|
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(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-protector")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-pic")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffreestanding")
|
||||||
|
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
||||||
|
endif()
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
||||||
|
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
||||||
|
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# COMPILATION
|
# COMPILATION
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -135,8 +183,8 @@ set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -drive file=${CMAKE_BINARY_DIR}/rootfs.img,
|
|||||||
add_custom_target(
|
add_custom_target(
|
||||||
qemu
|
qemu
|
||||||
COMMAND test -e ${CMAKE_BINARY_DIR}/rootfs.img || ${CMAKE_COMMAND} -E cmake_echo_color --red "No filesystem file detected, you need to run: make filesystem"
|
COMMAND test -e ${CMAKE_BINARY_DIR}/rootfs.img || ${CMAKE_COMMAND} -E cmake_echo_color --red "No filesystem file detected, you need to run: make filesystem"
|
||||||
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} -kernel ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin
|
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} -kernel ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin
|
||||||
DEPENDS kernel-bootloader.bin
|
DEPENDS kernel_bootloader.bin
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -147,17 +195,17 @@ add_custom_target(
|
|||||||
# executables.
|
# executables.
|
||||||
add_custom_target(
|
add_custom_target(
|
||||||
gdbinit
|
gdbinit
|
||||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/.gdbinit ${CMAKE_BINARY_DIR}/gdb.run
|
BYPRODUCTS ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
# Create the generic gdb configuration.
|
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/mentos/kernel.bin > ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND echo "add-symbol-file ${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 echo "add-symbol-file ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/programs/tests/test_* >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND ls -1 ${CMAKE_BINARY_DIR}/programs/tests/test_* | sed 's/^/add-symbol-file /' >> ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/programs/prog_* >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND ls -1 ${CMAKE_BINARY_DIR}/programs/prog_* | sed 's/^/add-symbol-file /' >> ${CMAKE_BINARY_DIR}/.gdbinit
|
|
||||||
COMMAND echo "break boot.c: boot_main" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND echo "break boot.c: boot_main" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
COMMAND echo "break kernel.c: kmain" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
COMMAND echo "break kernel.c: kmain" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||||
# Create the GDB connection file.
|
# Create the GDB connection file.
|
||||||
COMMAND echo "target remote localhost:1234" >> ${CMAKE_BINARY_DIR}/gdb.run
|
COMMAND echo "target remote localhost:1234" > ${CMAKE_BINARY_DIR}/gdb.run
|
||||||
DEPENDS kernel-bootloader.bin
|
DEPENDS ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin
|
||||||
|
DEPENDS ${CMAKE_BINARY_DIR}/mentos/kernel.bin
|
||||||
DEPENDS all_programs
|
DEPENDS all_programs
|
||||||
DEPENDS all_tests
|
DEPENDS all_tests
|
||||||
DEPENDS libc
|
DEPENDS libc
|
||||||
@@ -169,17 +217,15 @@ add_custom_target(
|
|||||||
add_custom_target(
|
add_custom_target(
|
||||||
qemu-gdb
|
qemu-gdb
|
||||||
COMMAND test -e ${CMAKE_BINARY_DIR}/rootfs.img || ${CMAKE_COMMAND} -E cmake_echo_color --red "No filesystem file detected, you need to run: make filesystem"
|
COMMAND test -e ${CMAKE_BINARY_DIR}/rootfs.img || ${CMAKE_COMMAND} -E cmake_echo_color --red "No filesystem file detected, you need to run: make filesystem"
|
||||||
COMMAND echo ""
|
COMMAND echo "\n\n"
|
||||||
COMMAND echo "Now, QEMU has loaded the kernel, and it is waiting that you"
|
COMMAND echo "Now, QEMU has loaded the kernel, and it is waiting that you\n"
|
||||||
COMMAND echo "remotely connect to it. To start debugging, open a new shell"
|
COMMAND echo "remotely connect to it. To start debugging, open a new shell\n"
|
||||||
COMMAND echo "in THIS same folder, and just type:"
|
COMMAND echo "in THIS same folder, and just type :\n"
|
||||||
COMMAND echo " gdb --quiet --command=gdb.run"
|
COMMAND printf " cgdb -q -iex %q" "add-auto-load-safe-path ."
|
||||||
COMMAND echo "or if you want to use cgdb, type:"
|
COMMAND echo "\n\n"
|
||||||
COMMAND echo " cgdb --quiet --command=gdb.run"
|
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} -s -S -kernel ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin
|
||||||
COMMAND echo ""
|
DEPENDS kernel_bootloader.bin
|
||||||
COMMAND ${EMULATOR} ${EMULATOR_FLAGS} -s -S -kernel ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin
|
DEPENDS .gdbinit
|
||||||
DEPENDS kernel-bootloader.bin
|
|
||||||
DEPENDS gdbinit
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -190,9 +236,9 @@ add_custom_target(
|
|||||||
add_custom_target(
|
add_custom_target(
|
||||||
cdrom.iso
|
cdrom.iso
|
||||||
COMMAND cp -rf ${CMAKE_SOURCE_DIR}/iso .
|
COMMAND cp -rf ${CMAKE_SOURCE_DIR}/iso .
|
||||||
COMMAND cp ${CMAKE_BINARY_DIR}/mentos/kernel-bootloader.bin ${CMAKE_BINARY_DIR}/iso/boot
|
COMMAND cp ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin ${CMAKE_BINARY_DIR}/iso/boot
|
||||||
COMMAND grub-mkrescue -o ${CMAKE_BINARY_DIR}/cdrom.iso ${CMAKE_BINARY_DIR}/iso
|
COMMAND grub-mkrescue -o ${CMAKE_BINARY_DIR}/cdrom.iso ${CMAKE_BINARY_DIR}/iso
|
||||||
DEPENDS kernel-bootloader.bin
|
DEPENDS kernel_bootloader.bin
|
||||||
)
|
)
|
||||||
|
|
||||||
# This third target runs the emualtor, but this time, the kernel binary file is
|
# This third target runs the emualtor, but this time, the kernel binary file is
|
||||||
|
|||||||
@@ -5,24 +5,29 @@
|
|||||||
[](https://forthebadge.com)
|
[](https://forthebadge.com)
|
||||||
|
|
||||||
[](https://github.com/mentos-team/MentOS/actions/workflows/ubuntu.yml)
|
[](https://github.com/mentos-team/MentOS/actions/workflows/ubuntu.yml)
|
||||||
[](https://github.com/mentos-team/MentOS/actions/workflows/macos.yml)
|
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
1. [What is MentOS](#1-what-is-mentos)
|
- [MentOS (Mentoring Operating System)](#mentos-mentoring-operating-system)
|
||||||
2. [Implemented features](#2-implemented-features)
|
- [Table of Contents](#table-of-contents)
|
||||||
3. [Prerequisites](#3-prerequisites)
|
- [What is MentOS](#what-is-mentos)
|
||||||
4. [Compiling MentOS](#4-compiling-mentos)
|
- [Implemented features](#implemented-features)
|
||||||
5. [Generating the EXT2 filesystem](#5-generating-the-ext2-filesystem)
|
- [Prerequisites](#prerequisites)
|
||||||
6. [Running MentOS](#6-running-mentos)
|
- [Installing the prerequisites](#installing-the-prerequisites)
|
||||||
7. [Running MentOS from GRUB](#7-running-mentos-from-grub)
|
- [Compiling MentOS](#compiling-mentos)
|
||||||
8. [Running and adding new programs to MentOS](#8-running-and-adding-new-programs-to-mentos)
|
- [Generating the EXT2 filesystem](#generating-the-ext2-filesystem)
|
||||||
9. [Kernel logging](#9-kernel-logging)
|
- [Running MentOS](#running-mentos)
|
||||||
10. [Change the scheduling algorithm](#10-change-the-scheduling-algorithm)
|
- [Running MentOS from GRUB](#running-mentos-from-grub)
|
||||||
11. [Debugging the kernel](#11-debugging-the-kernel)
|
- [Running and adding new programs to MentOS](#running-and-adding-new-programs-to-mentos)
|
||||||
12. [Contributors](#12-contributors)
|
- [Create a new program](#create-a-new-program)
|
||||||
|
- [Add the new program to the list of compiled sources](#add-the-new-program-to-the-list-of-compiled-sources)
|
||||||
|
- [Running a program or a test](#running-a-program-or-a-test)
|
||||||
|
- [Kernel logging](#kernel-logging)
|
||||||
|
- [Change the scheduling algorithm](#change-the-scheduling-algorithm)
|
||||||
|
- [Debugging the kernel](#debugging-the-kernel)
|
||||||
|
- [Contributors](#contributors)
|
||||||
|
|
||||||
## 1. What is MentOS
|
## What is MentOS
|
||||||
|
|
||||||
MentOS (Mentoring Operating System) is an open source educational operating
|
MentOS (Mentoring Operating System) is an open source educational operating
|
||||||
system. The goal of MentOS is to provide a project environment that is realistic
|
system. The goal of MentOS is to provide a project environment that is realistic
|
||||||
@@ -46,7 +51,8 @@ Gualandri.
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 2. Implemented features
|
## Implemented features
|
||||||
|
|
||||||
Follows the list of implemented features:
|
Follows the list of implemented features:
|
||||||
|
|
||||||
**Processes and Events**
|
**Processes and Events**
|
||||||
@@ -91,22 +97,18 @@ I will try to keep it updated...
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 3. Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
MentOS is compatible with the main **unix-based** operating systems. It has been
|
MentOS is compatible with the main **unix-based** operating systems. It has been
|
||||||
tested with *Ubuntu*, *WSL1*, *WSL2*, and *MacOS*.
|
tested with *Ubuntu*, and under Windows with *WSL1* and *WSL2*.
|
||||||
|
|
||||||
### 3.1. Generic Prerequisites
|
For **compiling** the system we need:
|
||||||
|
|
||||||
#### 3.1.1. Compile
|
- git
|
||||||
|
|
||||||
For compiling the system:
|
|
||||||
|
|
||||||
- nasm
|
|
||||||
- gcc
|
- gcc
|
||||||
|
- nasm
|
||||||
- make
|
- make
|
||||||
- cmake
|
- cmake
|
||||||
- git
|
|
||||||
- ccmake (suggested)
|
- ccmake (suggested)
|
||||||
- e2fsprogs (should be already installed)
|
- e2fsprogs (should be already installed)
|
||||||
|
|
||||||
@@ -115,43 +117,29 @@ Under **MacOS**, for compiling, you have additional dependencies:
|
|||||||
- i386-elf-binutils
|
- i386-elf-binutils
|
||||||
- i386-elf-gcc
|
- i386-elf-gcc
|
||||||
|
|
||||||
#### 3.1.2. Execute
|
For **executing** the operating system we need:
|
||||||
|
|
||||||
To execute the operating system, you need to install:
|
|
||||||
|
|
||||||
- qemu-system-i386 (or qemu-system-x86)
|
- qemu-system-i386 (or qemu-system-x86)
|
||||||
|
|
||||||
#### 3.1.3. Debug
|
For **debugging** we suggest using:
|
||||||
|
|
||||||
For debugging we suggest using:
|
|
||||||
|
|
||||||
- gdb or cgdb
|
- gdb or cgdb
|
||||||
|
|
||||||
### 3.2. installation Prerequisites
|
### Installing the prerequisites
|
||||||
|
|
||||||
Under **Ubuntu**, you can type the following commands:
|
Under **Ubuntu**, you can type the following commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get update && sudo apt-get upgrade -y
|
sudo apt-get update && sudo apt-get upgrade -y
|
||||||
sudo apt-get install -y build-essential git cmake qemu-system-x86 nasm e2fsprogs
|
sudo apt-get install -y git build-essential nasm make cmake cmake-curses-gui e2fsprogs
|
||||||
|
sudo apt-get install -y qemu-system-x86
|
||||||
sudo apt-get install -y gdb cgdb
|
sudo apt-get install -y gdb cgdb
|
||||||
```
|
```
|
||||||
Note: Older versions might have `qemu-system-i386` instead of `qemu-system-x86`.
|
Note: Older versions might have `qemu-system-i386` instead of `qemu-system-x86`.
|
||||||
|
|
||||||
Under **MacOS** you also need to install the i386-elf cross-compiler. The
|
|
||||||
simplest installation method is through Homebrew package manager.
|
|
||||||
Install [Homebrew](https://brew.sh/index_it) if you don't already have it, and
|
|
||||||
then type the following commands:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew update && brew upgrade
|
|
||||||
brew install i386-elf-binutils i386-elf-gcc git cmake qemu nasm e2fsprogs
|
|
||||||
brew install gdb cgdb #<- for debug only
|
|
||||||
```
|
|
||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 4. Compiling MentOS
|
## Compiling MentOS
|
||||||
|
|
||||||
Compile MentOS with:
|
Compile MentOS with:
|
||||||
|
|
||||||
@@ -165,7 +153,7 @@ make
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 5. Generating the EXT2 filesystem
|
## Generating the EXT2 filesystem
|
||||||
|
|
||||||
Generate the EXT2 filesystem with:
|
Generate the EXT2 filesystem with:
|
||||||
|
|
||||||
@@ -176,7 +164,7 @@ you just need to generate the filesystem once. If you change a `program` you nee
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 6. Running MentOS
|
## Running MentOS
|
||||||
|
|
||||||
Boot MentOS with qemu:
|
Boot MentOS with qemu:
|
||||||
|
|
||||||
@@ -188,7 +176,7 @@ To login, use one of the usernames listed in `files/etc/passwd`.
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 7. Running MentOS from GRUB
|
## Running MentOS from GRUB
|
||||||
|
|
||||||
For booting MentOS from GRUB in QEMU we need the following tools:
|
For booting MentOS from GRUB in QEMU we need the following tools:
|
||||||
|
|
||||||
@@ -211,11 +199,11 @@ make qemu-grub
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 8. Running and adding new programs to MentOS
|
## Running and adding new programs to MentOS
|
||||||
|
|
||||||
This section explains how to add a new program to MentOS, and also how to run programs in mentos. It also explains how to add new tests, which are located in the `programs/tests` folder.
|
This section explains how to add a new program to MentOS, and also how to run programs in mentos. It also explains how to add new tests, which are located in the `programs/tests` folder.
|
||||||
|
|
||||||
### 8.1. Create a new program
|
### Create a new program
|
||||||
|
|
||||||
Head to the `programs` (or the `programs/tests`) folder. Create and open a new program, for instance a file called `hello_world.c`, with your preferred editor, and add this content to the file:
|
Head to the `programs` (or the `programs/tests`) folder. Create and open a new program, for instance a file called `hello_world.c`, with your preferred editor, and add this content to the file:
|
||||||
```C
|
```C
|
||||||
@@ -228,7 +216,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 8.2. Add the new program to the list of compiled sources
|
### Add the new program to the list of compiled sources
|
||||||
Now we can add the program to the list of files which are compiled and placed inside MentOS filesystem.
|
Now we can add the program to the list of files which are compiled and placed inside MentOS filesystem.
|
||||||
The following procedure is the same for both `programs` and `programs/tests`, what changes is which `CMakeLists.txt` file we modify.
|
The following procedure is the same for both `programs` and `programs/tests`, what changes is which `CMakeLists.txt` file we modify.
|
||||||
|
|
||||||
@@ -253,7 +241,7 @@ set(TESTS
|
|||||||
|
|
||||||
That's it, the `hello_world.c` file will be compiled and will appear inside the `/bin` or `/bin/tests` folder of MentOS.
|
That's it, the `hello_world.c` file will be compiled and will appear inside the `/bin` or `/bin/tests` folder of MentOS.
|
||||||
|
|
||||||
### 8.3. Running a program or a test
|
### Running a program or a test
|
||||||
Once you login into MentOS, if you placed your source code in `programs`, you can execute the program by simply typing:
|
Once you login into MentOS, if you placed your source code in `programs`, you can execute the program by simply typing:
|
||||||
```bash
|
```bash
|
||||||
hello_world
|
hello_world
|
||||||
@@ -268,7 +256,7 @@ However, the `/bin/tests` folder is not listed in `PATH`, so, if you want to exe
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 9. Kernel logging
|
## Kernel logging
|
||||||
The kernel provides ways of printing logging messages *from* inside the kernel code *to* the bash where you executed the `make qemu`.
|
The kernel provides ways of printing logging messages *from* inside the kernel code *to* the bash where you executed the `make qemu`.
|
||||||
|
|
||||||
These *logging* functions are:
|
These *logging* functions are:
|
||||||
@@ -322,7 +310,7 @@ This example sets the `__DEBUG_LEVEL__`, so that all the messages from `INFO` an
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 10. Change the scheduling algorithm
|
## Change the scheduling algorithm
|
||||||
|
|
||||||
MentOS supports scheduling algorithms for aperiodic:
|
MentOS supports scheduling algorithms for aperiodic:
|
||||||
|
|
||||||
@@ -390,7 +378,7 @@ make qemu
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 11. Debugging the kernel
|
## Debugging the kernel
|
||||||
|
|
||||||
If you want to use GDB to debug MentOS, first you need to compile everything:
|
If you want to use GDB to debug MentOS, first you need to compile everything:
|
||||||
|
|
||||||
@@ -450,7 +438,7 @@ to connect to the running process.
|
|||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|
||||||
## 12. Contributors
|
## Contributors
|
||||||
|
|
||||||
Project Manager:
|
Project Manager:
|
||||||
|
|
||||||
@@ -472,5 +460,9 @@ Developers:
|
|||||||
- Soft IRQs
|
- Soft IRQs
|
||||||
- Timer
|
- Timer
|
||||||
- Signals
|
- Signals
|
||||||
|
* And many other valuable contributors
|
||||||
|
* [rouseabout](https://github.com/rouseabout)
|
||||||
|
* [seekbytes](https://github.com/seekbytes)
|
||||||
|
* [fischerling](https://github.com/fischerling)
|
||||||
|
|
||||||
*[Back to the Table of Contents](#table-of-contents)*
|
*[Back to the Table of Contents](#table-of-contents)*
|
||||||
|
|||||||
+67
-143
@@ -1,146 +1,70 @@
|
|||||||
# =============================================================================
|
# Add the libc library.
|
||||||
# Author: Enrico Fraccaroli
|
add_library(libc
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/stdio.c
|
||||||
# Set the minimum required version of cmake.
|
${PROJECT_SOURCE_DIR}/libc/src/ctype.c
|
||||||
cmake_minimum_required(VERSION 3.1...3.22)
|
${PROJECT_SOURCE_DIR}/libc/src/string.c
|
||||||
# Initialize the project.
|
${PROJECT_SOURCE_DIR}/libc/src/stdlib.c
|
||||||
project(libc C ASM)
|
${PROJECT_SOURCE_DIR}/libc/src/math.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/fcvt.c
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/time.c
|
||||||
# ASSEMBLY
|
${PROJECT_SOURCE_DIR}/libc/src/strerror.c
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/termios.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/libgen.c
|
||||||
# Enable the assembly language.
|
${PROJECT_SOURCE_DIR}/libc/src/vsprintf.c
|
||||||
enable_language(ASM)
|
${PROJECT_SOURCE_DIR}/libc/src/vscanf.c
|
||||||
# Find the NASM compiler.
|
${PROJECT_SOURCE_DIR}/libc/src/pwd.c
|
||||||
find_program(ASM_COMPILER NAMES nasm HINTS /usr/bin/ /usr/local/bin/)
|
${PROJECT_SOURCE_DIR}/libc/src/grp.c
|
||||||
# Mark the variable ASM_COMPILER as advanced.
|
${PROJECT_SOURCE_DIR}/libc/src/sched.c
|
||||||
mark_as_advanced(ASM_COMPILER)
|
${PROJECT_SOURCE_DIR}/libc/src/readline.c
|
||||||
# Check that we have found the compiler.
|
${PROJECT_SOURCE_DIR}/libc/src/setenv.c
|
||||||
if(NOT ASM_COMPILER)
|
${PROJECT_SOURCE_DIR}/libc/src/assert.c
|
||||||
message(FATAL_ERROR "ASM compiler not found!")
|
${PROJECT_SOURCE_DIR}/libc/src/abort.c
|
||||||
endif(NOT ASM_COMPILER)
|
${PROJECT_SOURCE_DIR}/libc/src/io/mm_io.c
|
||||||
# Set the asm compiler.
|
${PROJECT_SOURCE_DIR}/libc/src/io/debug.c
|
||||||
set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
|
${PROJECT_SOURCE_DIR}/libc/src/sys/ipc.c
|
||||||
# Set the assembly compiler flags.
|
${PROJECT_SOURCE_DIR}/libc/src/sys/unistd.c
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
${PROJECT_SOURCE_DIR}/libc/src/sys/errno.c
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -f elf -g -O0 -F dwarf -o <OBJECT> <SOURCE>")
|
${PROJECT_SOURCE_DIR}/libc/src/sys/utsname.c
|
||||||
else()
|
${PROJECT_SOURCE_DIR}/libc/src/sys/mman.c
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -f elf -g -O3 -o <OBJECT> <SOURCE>")
|
${PROJECT_SOURCE_DIR}/libc/src/sys/ioctl.c
|
||||||
endif()
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/creat.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getppid.c
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getpid.c
|
||||||
# C WARNINGs
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/exit.c
|
||||||
# =============================================================================
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/setsid.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getsid.c
|
||||||
# Warning flags.
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/setpgid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getpgid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/setgid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getgid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/setuid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getuid.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/fork.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/read.c
|
||||||
# Disable some specific warnings.
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/write.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/exec.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/nice.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/open.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/reboot.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/waitpid.c
|
||||||
# Set the compiler options.
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/chdir.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getcwd.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/close.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/stat.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/rmdir.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-protector")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/mkdir.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-pic")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/unlink.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/getdents.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/lseek.c
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/kill.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/signal.c
|
||||||
endif()
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/interval.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/symlink.c
|
||||||
|
${PROJECT_SOURCE_DIR}/libc/src/unistd/readlink.c
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
${PROJECT_SOURCE_DIR}/libc/src/libc_start.c
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
${PROJECT_SOURCE_DIR}/libc/src/crt0.s
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Add the library.
|
|
||||||
add_library(
|
|
||||||
${PROJECT_NAME}
|
|
||||||
|
|
||||||
${PROJECT_SOURCE_DIR}/src/stdio.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/ctype.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/string.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/stdlib.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/math.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/fcvt.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/time.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/strerror.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/termios.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/libgen.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/vsprintf.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/vscanf.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/pwd.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/grp.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sched.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/readline.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/setenv.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/assert.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/abort.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/io/mm_io.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/io/debug.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/ipc.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/unistd.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/errno.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/utsname.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/mman.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/ioctl.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/creat.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getppid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getpid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/exit.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/setsid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getsid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/setpgid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getpgid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/setgid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getgid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/setuid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getuid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/fork.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/read.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/write.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/exec.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/nice.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/open.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/reboot.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/waitpid.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/chdir.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getcwd.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/close.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/stat.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/rmdir.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/mkdir.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/unlink.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/getdents.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/lseek.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/kill.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/signal.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/interval.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/symlink.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/unistd/readlink.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/libc_start.c
|
|
||||||
${PROJECT_SOURCE_DIR}/src/crt0.S
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add the includes.
|
# Add the includes.
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC inc)
|
target_include_directories(libc PRIVATE ${PROJECT_SOURCE_DIR}/libc/inc)
|
||||||
|
|
||||||
# Remove the 'lib' prefix.
|
# Remove the 'lib' prefix.
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
set_target_properties(libc PROPERTIES PREFIX "")
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
.extern main
|
||||||
|
.extern __libc_start_main
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
_start: # _start is the entry point known to the linker
|
||||||
|
mov $0, %ebp # Set ebp to 0 as x86 programs require
|
||||||
|
push $main
|
||||||
|
call __libc_start_main # Call the libc initialization function.
|
||||||
|
mov %eax, %ebx # Move `main` return value to ebx.
|
||||||
|
mov $1, %eax # Call the `exit` function by using `int 80` (i.e., a system call)
|
||||||
|
int $0x80
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/// @file waitpid.c
|
/// @file waitpid.c
|
||||||
/// @brief
|
/// @brief
|
||||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
/// @copyright (c) 2014-2024 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include "sys/unistd.h"
|
#include "sys/unistd.h"
|
||||||
@@ -18,19 +18,17 @@ pid_t waitpid(pid_t pid, int *status, int options)
|
|||||||
int __status = 0;
|
int __status = 0;
|
||||||
do {
|
do {
|
||||||
__inline_syscall3(__res, waitpid, pid, &__status, options);
|
__inline_syscall3(__res, waitpid, pid, &__status, options);
|
||||||
if (__res < 0) {
|
if (__res != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (__status == EXIT_ZOMBIE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (options && WNOHANG) {
|
if (options && WNOHANG) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
*status = __status;
|
*status = __status;
|
||||||
}
|
}
|
||||||
__syscall_return(pid_t, __res);
|
__syscall_return(pid_t, __res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+116
-169
@@ -1,15 +1,9 @@
|
|||||||
# =============================================================================
|
|
||||||
# Set the minimum required version of cmake.
|
|
||||||
cmake_minimum_required(VERSION 3.1...3.22)
|
|
||||||
# Initialize the project.
|
|
||||||
project(kernel C ASM)
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Set the main file names.
|
# Set the main file names.
|
||||||
set(KERNEL_NAME kernel)
|
set(KERNEL_NAME kernel)
|
||||||
set(BOOTLOADER_NAME kernel_bootloader)
|
set(BOOTLOADER_NAME kernel_bootloader)
|
||||||
set(BUDDY_SYSTEM_NAME kernel_memory)
|
set(BUDDY_SYSTEM_NAME kernel_memory)
|
||||||
set(BUDDY_SYSTEM_FILE ${PROJECT_SOURCE_DIR}/src/mem/libbuddysystem.a)
|
set(BUDDY_SYSTEM_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/mem/libbuddysystem.a)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
@@ -24,166 +18,103 @@ option(ENABLE_ALLOC_TRACE "Enables memory allocation tracing." OFF)
|
|||||||
# Enables scheduling feedback on terminal.
|
# Enables scheduling feedback on terminal.
|
||||||
option(ENABLE_SCHEDULER_FEEDBACK "Enables scheduling feedback on terminal." OFF)
|
option(ENABLE_SCHEDULER_FEEDBACK "Enables scheduling feedback on terminal." OFF)
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# ASSEMBLY
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Enable the assembly language.
|
|
||||||
enable_language(ASM)
|
|
||||||
# Find the NASM compiler.
|
|
||||||
find_program(ASM_COMPILER NAMES nasm HINTS /usr/bin/ /usr/local/bin/)
|
|
||||||
# Mark the variable ASM_COMPILER as advanced.
|
|
||||||
mark_as_advanced(ASM_COMPILER)
|
|
||||||
# Check that we have found the compiler.
|
|
||||||
if(NOT ASM_COMPILER)
|
|
||||||
message(FATAL_ERROR "ASM compiler not found!")
|
|
||||||
endif(NOT ASM_COMPILER)
|
|
||||||
# Set the asm compiler.
|
|
||||||
set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
|
|
||||||
# Set the assembly compiler flags.
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -f elf -g -O0 -F dwarf -o <OBJECT> <SOURCE>")
|
|
||||||
else()
|
|
||||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -f elf -g -O3 -o <OBJECT> <SOURCE>")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# C WARNINGs
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Warning flags.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
|
||||||
|
|
||||||
# Disable some specific warnings.
|
|
||||||
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-unknown-pragmas")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
|
|
||||||
|
|
||||||
# Set the compiler options.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-protector")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-pic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
|
||||||
endif()
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# SOURCES
|
# SOURCES
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
# Define the list of files.
|
# Define the list of files.
|
||||||
set(KERNEL_SOURCES
|
set(KERNEL_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/src/kernel.c
|
${PROJECT_SOURCE_DIR}/mentos/src/kernel.c
|
||||||
${PROJECT_SOURCE_DIR}/src/multiboot.c
|
${PROJECT_SOURCE_DIR}/mentos/src/multiboot.c
|
||||||
${PROJECT_SOURCE_DIR}/src/devices/pci.c
|
${PROJECT_SOURCE_DIR}/mentos/src/devices/pci.c
|
||||||
${PROJECT_SOURCE_DIR}/src/devices/fpu.c
|
${PROJECT_SOURCE_DIR}/mentos/src/devices/fpu.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/ata.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/ata.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/rtc.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/rtc.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/fdc.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/fdc.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/mouse.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/mouse.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/ps2.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/ps2.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/keyboard/keyboard.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/keyboard/keyboard.c
|
||||||
${PROJECT_SOURCE_DIR}/src/drivers/keyboard/keymap.c
|
${PROJECT_SOURCE_DIR}/mentos/src/drivers/keyboard/keymap.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/vfs.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/vfs.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/read_write.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/read_write.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/open.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/open.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/stat.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/stat.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/readdir.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/readdir.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/procfs.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/procfs.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/ioctl.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/ioctl.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/namei.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/namei.c
|
||||||
${PROJECT_SOURCE_DIR}/src/fs/ext2.c
|
${PROJECT_SOURCE_DIR}/mentos/src/fs/ext2.c
|
||||||
${PROJECT_SOURCE_DIR}/src/hardware/timer.c
|
${PROJECT_SOURCE_DIR}/mentos/src/hardware/timer.c
|
||||||
${PROJECT_SOURCE_DIR}/src/hardware/cpuid.c
|
${PROJECT_SOURCE_DIR}/mentos/src/hardware/cpuid.c
|
||||||
${PROJECT_SOURCE_DIR}/src/hardware/pic8259.c
|
${PROJECT_SOURCE_DIR}/mentos/src/hardware/pic8259.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/debug.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/debug.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/mm_io.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/mm_io.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/video.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/video.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/stdio.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/stdio.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_video.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_video.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_running.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_running.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_feedback.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_feedback.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_system.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_system.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/proc_ipc.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/proc_ipc.c
|
||||||
${PROJECT_SOURCE_DIR}/src/io/vga/vga.c
|
${PROJECT_SOURCE_DIR}/mentos/src/io/vga/vga.c
|
||||||
${PROJECT_SOURCE_DIR}/src/ipc/ipc.c
|
${PROJECT_SOURCE_DIR}/mentos/src/ipc/ipc.c
|
||||||
${PROJECT_SOURCE_DIR}/src/ipc/msg.c
|
${PROJECT_SOURCE_DIR}/mentos/src/ipc/msg.c
|
||||||
${PROJECT_SOURCE_DIR}/src/ipc/sem.c
|
${PROJECT_SOURCE_DIR}/mentos/src/ipc/sem.c
|
||||||
${PROJECT_SOURCE_DIR}/src/ipc/shm.c
|
${PROJECT_SOURCE_DIR}/mentos/src/ipc/shm.c
|
||||||
${PROJECT_SOURCE_DIR}/src/kernel/sys.c
|
${PROJECT_SOURCE_DIR}/mentos/src/kernel/sys.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/assert.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/assert.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/ctype.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/ctype.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/mutex.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/mutex.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/string.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/string.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/vsprintf.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/vsprintf.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/vscanf.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/vscanf.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/time.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/time.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/libgen.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/libgen.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/strerror.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/strerror.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/math.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/math.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/fcvt.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/fcvt.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/spinlock.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/spinlock.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/stdlib.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/stdlib.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/rbtree.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/rbtree.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/ndtree.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/ndtree.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/hashmap.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/hashmap.c
|
||||||
${PROJECT_SOURCE_DIR}/src/klib/list.c
|
${PROJECT_SOURCE_DIR}/mentos/src/klib/list.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/kheap.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/kheap.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/paging.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/paging.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/slab.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/slab.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/vmem_map.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/vmem_map.c
|
||||||
${PROJECT_SOURCE_DIR}/src/mem/zone_allocator.c
|
${PROJECT_SOURCE_DIR}/mentos/src/mem/zone_allocator.c
|
||||||
${PROJECT_SOURCE_DIR}/src/elf/elf.c
|
${PROJECT_SOURCE_DIR}/mentos/src/elf/elf.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/gdt.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/gdt.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/gdt.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/gdt.s
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/interrupt.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/interrupt.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/exception.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/exception.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/interrupt.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/interrupt.s
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/exception.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/exception.s
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/idt.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/idt.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/idt.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/idt.s
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/tss.c
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/tss.c
|
||||||
${PROJECT_SOURCE_DIR}/src/descriptor_tables/tss.S
|
${PROJECT_SOURCE_DIR}/mentos/src/descriptor_tables/tss.s
|
||||||
${PROJECT_SOURCE_DIR}/src/process/scheduler_algorithm.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/scheduler_algorithm.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/scheduler_feedback.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/scheduler_feedback.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/scheduler.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/scheduler.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/process.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/process.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/wait.c
|
${PROJECT_SOURCE_DIR}/mentos/src/process/wait.c
|
||||||
${PROJECT_SOURCE_DIR}/src/process/user.S
|
${PROJECT_SOURCE_DIR}/mentos/src/process/user.s
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/utsname.c
|
${PROJECT_SOURCE_DIR}/mentos/src/sys/utsname.c
|
||||||
${PROJECT_SOURCE_DIR}/src/sys/module.c
|
${PROJECT_SOURCE_DIR}/mentos/src/sys/module.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/errno.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/errno.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/panic.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/panic.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/printk.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/printk.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/signal.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/signal.c
|
||||||
${PROJECT_SOURCE_DIR}/src/system/syscall.c
|
${PROJECT_SOURCE_DIR}/mentos/src/system/syscall.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Add kernel library.
|
# Add kernel library.
|
||||||
if(USE_BUDDY_SYSTEM)
|
if(USE_BUDDY_SYSTEM)
|
||||||
# Add the library with `buddysystem.c`.
|
# Add the library with `buddysystem.c`.
|
||||||
add_library(${KERNEL_NAME} ${KERNEL_SOURCES} src/mem/buddysystem.c)
|
add_library(${KERNEL_NAME} ${KERNEL_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src/mem/buddysystem.c)
|
||||||
else(USE_BUDDY_SYSTEM)
|
else(USE_BUDDY_SYSTEM)
|
||||||
# Add the library without `buddysystem.c`.
|
# Add the library without `buddysystem.c`.
|
||||||
add_library(${KERNEL_NAME} ${KERNEL_SOURCES})
|
add_library(${KERNEL_NAME} ${KERNEL_SOURCES})
|
||||||
@@ -201,6 +132,17 @@ target_compile_definitions(
|
|||||||
${KERNEL_NAME} PUBLIC
|
${KERNEL_NAME} PUBLIC
|
||||||
__KERNEL__
|
__KERNEL__
|
||||||
)
|
)
|
||||||
|
# Link the kernel.
|
||||||
|
add_custom_target(
|
||||||
|
${KERNEL_NAME}.bin
|
||||||
|
COMMAND ${CMAKE_LINKER} -melf_i386 -static --oformat elf32-i386 --output ${KERNEL_NAME}.bin --script ${CMAKE_CURRENT_SOURCE_DIR}/kernel.lds -Map ${KERNEL_NAME}.map -u kmain
|
||||||
|
$<TARGET_FILE_NAME:${KERNEL_NAME}> ${BUDDY_SYSTEM_FILE}
|
||||||
|
COMMAND objcopy -I binary -O elf32-i386 -B i386 ${KERNEL_NAME}.bin ${KERNEL_NAME}.bin.o
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/kernel.lds
|
||||||
|
DEPENDS ${KERNEL_NAME}
|
||||||
|
BYPRODUCTS ${KERNEL_NAME}.bin ${KERNEL_NAME}.bin.o
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Enables cache tracing.
|
# Enables cache tracing.
|
||||||
@@ -278,8 +220,8 @@ endif()
|
|||||||
# Add bootloader library.
|
# Add bootloader library.
|
||||||
add_library(
|
add_library(
|
||||||
${BOOTLOADER_NAME}
|
${BOOTLOADER_NAME}
|
||||||
src/boot.c
|
${CMAKE_CURRENT_SOURCE_DIR}/src/boot.c
|
||||||
src/boot.S
|
${CMAKE_CURRENT_SOURCE_DIR}/src/boot.s
|
||||||
)
|
)
|
||||||
# Add the includes.
|
# Add the includes.
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
@@ -292,16 +234,21 @@ target_compile_definitions(
|
|||||||
${BOOTLOADER_NAME} PUBLIC
|
${BOOTLOADER_NAME} PUBLIC
|
||||||
__KERNEL__
|
__KERNEL__
|
||||||
)
|
)
|
||||||
|
add_dependencies(
|
||||||
# =============================================================================
|
${BOOTLOADER_NAME}
|
||||||
# Build the kernel.
|
${KERNEL_NAME}
|
||||||
add_custom_target(
|
)
|
||||||
kernel-bootloader.bin ALL
|
target_link_libraries(
|
||||||
COMMAND ${CMAKE_LINKER} -melf_i386 -static --oformat elf32-i386 --output kernel.bin --script ${CMAKE_CURRENT_SOURCE_DIR}/kernel.lds -Map kernel.map -u kmain
|
${BOOTLOADER_NAME} PUBLIC
|
||||||
$<TARGET_FILE_NAME:${KERNEL_NAME}> ${BUDDY_SYSTEM_FILE}
|
${KERNEL_NAME}
|
||||||
COMMAND objcopy -I binary -O elf32-i386 -B i386 kernel.bin kernel.bin.o
|
)
|
||||||
COMMAND ${CMAKE_LINKER} -melf_i386 -static --oformat elf32-i386 --output kernel-bootloader.bin --script ${CMAKE_CURRENT_SOURCE_DIR}/boot.lds -Map kernel-bootloader.map
|
# Link the bootloader.
|
||||||
kernel.bin.o $<TARGET_FILE_NAME:${BOOTLOADER_NAME}>
|
add_custom_target(
|
||||||
DEPENDS ${KERNEL_NAME}
|
${BOOTLOADER_NAME}.bin
|
||||||
DEPENDS ${BOOTLOADER_NAME}
|
COMMAND ${CMAKE_LINKER} -melf_i386 -static --output ${BOOTLOADER_NAME}.bin --script ${CMAKE_CURRENT_SOURCE_DIR}/boot.lds -Map ${BOOTLOADER_NAME}.map ${KERNEL_NAME}.bin.o $<TARGET_FILE_NAME:${BOOTLOADER_NAME}>
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/boot.lds
|
||||||
|
DEPENDS ${BOOTLOADER_NAME}
|
||||||
|
DEPENDS ${KERNEL_NAME}.bin
|
||||||
|
BYPRODUCTS ${BOOTLOADER_NAME}.bin
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
|||||||
+5
-13
@@ -9,45 +9,37 @@ MEMORY {
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x00100000;
|
. = 0x00100000;
|
||||||
_bootloader_start = .;
|
|
||||||
|
_bootloader_start = .;
|
||||||
|
|
||||||
.multiboot . : AT(ADDR(.multiboot))
|
.multiboot . : AT(ADDR(.multiboot))
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_multiboot_header_start = .;
|
|
||||||
*(.multiboot_header)
|
*(.multiboot_header)
|
||||||
_multiboot_header_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Put the .text section. */
|
/* Put the .text section. */
|
||||||
.text . : AT(ADDR(.text))
|
.text . : AT(ADDR(.text))
|
||||||
{
|
{
|
||||||
_text_start = .;
|
|
||||||
*(.text)
|
*(.text)
|
||||||
_text_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Read-only data. */
|
/* Read-only data. */
|
||||||
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
||||||
{
|
{
|
||||||
_rodata_start = .;
|
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
_rodata_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Read-write data (initialized) */
|
/* Read-write data (initialized) */
|
||||||
.data ALIGN(4K) : AT(ADDR(.data))
|
.data ALIGN(4K) : AT(ADDR(.data))
|
||||||
{
|
{
|
||||||
_data_start = .;
|
|
||||||
*(.data)
|
*(.data)
|
||||||
_data_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Read-write data (uninitialized) and stack */
|
/* Read-write data (uninitialized) and stack */
|
||||||
.bss ALIGN(4K) : AT(ADDR(.bss))
|
.bss ALIGN(4K) : AT(ADDR(.bss))
|
||||||
{
|
{
|
||||||
_bss_start = .;
|
|
||||||
*(.bss*)
|
*(.bss*)
|
||||||
_bss_end = .;
|
|
||||||
} > BOOTLOADER_MEM
|
} > BOOTLOADER_MEM
|
||||||
|
|
||||||
/* Put a symbol end here, it tells us where all the kernel code/data ends,
|
/* Put a symbol end here, it tells us where all the kernel code/data ends,
|
||||||
|
|||||||
@@ -112,3 +112,7 @@ int sys_waitperiod(void);
|
|||||||
/// @param gid ID of the group
|
/// @param gid ID of the group
|
||||||
/// @return 1 if the group is orphan, 0 otherwise.
|
/// @return 1 if the group is orphan, 0 otherwise.
|
||||||
int is_orphaned_pgrp(pid_t gid);
|
int is_orphaned_pgrp(pid_t gid);
|
||||||
|
|
||||||
|
/// @brief Exit the current process with status
|
||||||
|
/// @param status The exit status of the current process
|
||||||
|
void do_exit(int status);
|
||||||
|
|||||||
@@ -15,33 +15,25 @@ SECTIONS
|
|||||||
/* Put the .text section. */
|
/* Put the .text section. */
|
||||||
.text . : AT(ADDR(.text))
|
.text . : AT(ADDR(.text))
|
||||||
{
|
{
|
||||||
_text_start = .;
|
|
||||||
EXCLUDE_FILE(*boot.*.o) *(.text)
|
EXCLUDE_FILE(*boot.*.o) *(.text)
|
||||||
_text_end = .;
|
|
||||||
} > KERNEL_LOWMEM
|
} > KERNEL_LOWMEM
|
||||||
|
|
||||||
/* Read-only data. */
|
/* Read-only data. */
|
||||||
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
||||||
{
|
{
|
||||||
_rodata_start = .;
|
|
||||||
EXCLUDE_FILE(*boot.*.o) *(.rodata)
|
EXCLUDE_FILE(*boot.*.o) *(.rodata)
|
||||||
_rodata_end = .;
|
|
||||||
} > KERNEL_LOWMEM
|
} > KERNEL_LOWMEM
|
||||||
|
|
||||||
/* Read-write data (initialized) */
|
/* Read-write data (initialized) */
|
||||||
.data ALIGN(4K) : AT(ADDR(.data))
|
.data ALIGN(4K) : AT(ADDR(.data))
|
||||||
{
|
{
|
||||||
_data_start = .;
|
|
||||||
EXCLUDE_FILE(*boot.*.o) *(.data)
|
EXCLUDE_FILE(*boot.*.o) *(.data)
|
||||||
_data_end = .;
|
|
||||||
} > KERNEL_LOWMEM
|
} > KERNEL_LOWMEM
|
||||||
|
|
||||||
/* Read-write data (uninitialized) and stack */
|
/* Read-write data (uninitialized) and stack */
|
||||||
.bss ALIGN(4K) : AT(ADDR(.bss))
|
.bss ALIGN(4K) : AT(ADDR(.bss))
|
||||||
{
|
{
|
||||||
_bss_start = .;
|
|
||||||
*(.bss*)
|
*(.bss*)
|
||||||
_bss_end = .;
|
|
||||||
} > KERNEL_LOWMEM
|
} > KERNEL_LOWMEM
|
||||||
|
|
||||||
/* Put a symbol end here, it tells us where all the kernel code/data ends,
|
/* Put a symbol end here, it tells us where all the kernel code/data ends,
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file boot.asm
|
|
||||||
; @brief Kernel start location, multiboot header
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
bits 32 ; All instructions should be 32-bit.
|
|
||||||
extern boot_main ; The start point of our C code
|
|
||||||
|
|
||||||
; The magic field should contain this.
|
|
||||||
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
|
|
||||||
; This should be in %eax.
|
|
||||||
MULTIBOOT_BOOTLOADER_MAGIC equ 0x2BADB002
|
|
||||||
|
|
||||||
; = Specify what GRUB should PROVIDE =========================================
|
|
||||||
; Align the kernel and kernel modules on i386 page (4KB) boundaries.
|
|
||||||
MULTIBOOT_PAGE_ALIGN equ 0x00000001
|
|
||||||
; Provide the kernel with memory information.
|
|
||||||
MULTIBOOT_MEMORY_INFO equ 0x00000002
|
|
||||||
; Must pass video information to OS.
|
|
||||||
MULTIBOOT_VIDEO_MODE equ 0x00000004
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; This is the flag combination that we prepare for Grub
|
|
||||||
; to read at kernel load time.
|
|
||||||
MULTIBOOT_HEADER_FLAGS equ (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO)
|
|
||||||
; Grub reads this value to make sure it loads a kernel
|
|
||||||
; and not just garbage.
|
|
||||||
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
|
||||||
|
|
||||||
LOAD_MEMORY_ADDRESS equ 0x00000000
|
|
||||||
; reserve (1024*1024) for the stack on a doubleword boundary
|
|
||||||
KERNEL_STACK_SIZE equ 0x100000
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (multiboot_header)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .multiboot_header
|
|
||||||
align 4
|
|
||||||
; This is the GRUB Multiboot header.
|
|
||||||
multiboot_header:
|
|
||||||
; magic
|
|
||||||
dd MULTIBOOT_HEADER_MAGIC
|
|
||||||
; flags
|
|
||||||
dd MULTIBOOT_HEADER_FLAGS
|
|
||||||
; checksum
|
|
||||||
dd MULTIBOOT_CHECKSUM
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (data)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; section .data nobits
|
|
||||||
; align 4096
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
global boot_entry
|
|
||||||
boot_entry:
|
|
||||||
; Clear interrupt flag [IF = 0]; 0xFA
|
|
||||||
cli
|
|
||||||
; To set up a stack, we simply set the esp register to point to the top of
|
|
||||||
; our stack (as it grows downwards).
|
|
||||||
mov esp, stack_top
|
|
||||||
; pass the initial ESP
|
|
||||||
push esp
|
|
||||||
; pass Multiboot info structure
|
|
||||||
push ebx
|
|
||||||
; pass Multiboot magic number
|
|
||||||
push eax
|
|
||||||
; Call the boot_main() function inside boot.c
|
|
||||||
call boot_main
|
|
||||||
; Set interrupt flag [IF = 1]; 0xFA
|
|
||||||
; Clear interrupts and hang if we return from boot_main
|
|
||||||
cli
|
|
||||||
hang:
|
|
||||||
hlt
|
|
||||||
jmp hang
|
|
||||||
|
|
||||||
global boot_kernel
|
|
||||||
boot_kernel:
|
|
||||||
mov edx, [esp + 4] ; stack_pointer
|
|
||||||
mov ebx, [esp + 8] ; entry
|
|
||||||
mov eax, [esp + 12] ; boot info
|
|
||||||
mov esp, edx ; set stack pointer
|
|
||||||
push eax ; push the boot info
|
|
||||||
call ebx ; call the kernel main
|
|
||||||
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (bss)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .bss
|
|
||||||
align 16
|
|
||||||
|
|
||||||
global stack_bottom
|
|
||||||
stack_bottom:
|
|
||||||
resb KERNEL_STACK_SIZE
|
|
||||||
|
|
||||||
global stack_top
|
|
||||||
stack_top:
|
|
||||||
; the top of the stack is the bottom because the stack counts down
|
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file boot.asm
|
||||||
|
# @brief Kernel start location, multiboot header
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
# All instructions should be 32-bit.
|
||||||
|
.extern boot_main # The start point of our C code
|
||||||
|
|
||||||
|
# The magic field should contain this.
|
||||||
|
.equ MULTIBOOT_HEADER_MAGIC, 0x1BADB002
|
||||||
|
# This should be in %eax.
|
||||||
|
.equ MULTIBOOT_BOOTLOADER_MAGIC, 0x2BADB002
|
||||||
|
|
||||||
|
# = Specify what GRUB should PROVIDE =========================================
|
||||||
|
# Align the kernel and kernel modules on i386 page (4KB) boundaries.
|
||||||
|
.equ MULTIBOOT_PAGE_ALIGN, 0x00000001
|
||||||
|
# Provide the kernel with memory information.
|
||||||
|
.equ MULTIBOOT_MEMORY_INFO, 0x00000002
|
||||||
|
# Must pass video information to OS.
|
||||||
|
.equ MULTIBOOT_VIDEO_MODE, 0x00000004
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# This is the flag combination that we prepare for Grub
|
||||||
|
# to read at kernel load time.
|
||||||
|
.equ MULTIBOOT_HEADER_FLAGS, (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO)
|
||||||
|
# Grub reads this value to make sure it loads a kernel
|
||||||
|
# and not just garbage.
|
||||||
|
.equ MULTIBOOT_CHECKSUM, -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||||
|
|
||||||
|
.equ LOAD_MEMORY_ADDRESS, 0x00000000
|
||||||
|
# reserve (1024*1024) for the stack on a doubleword boundary
|
||||||
|
.equ KERNEL_STACK_SIZE, 0x100000
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.pushsection .note.name, "a", @note
|
||||||
|
.align 4
|
||||||
|
.long 2f - 1f /* namesz */
|
||||||
|
.long 4f - 3f /* descsz */
|
||||||
|
.long 18 /* type */
|
||||||
|
1:.asciz "MentOS" /* name */
|
||||||
|
2:.align 4
|
||||||
|
3:.long boot_entry /* desc */
|
||||||
|
4:.align 4
|
||||||
|
.popsection
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (multiboot_header)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.globl multiboot_header
|
||||||
|
.align 4
|
||||||
|
# This is the GRUB Multiboot header.
|
||||||
|
multiboot_header:
|
||||||
|
# magic
|
||||||
|
.long MULTIBOOT_HEADER_MAGIC
|
||||||
|
# flags
|
||||||
|
.long MULTIBOOT_HEADER_FLAGS
|
||||||
|
# checksum
|
||||||
|
.long MULTIBOOT_CHECKSUM
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (data)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# section .data nobits
|
||||||
|
# align 4096
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
.global boot_entry
|
||||||
|
boot_entry:
|
||||||
|
# Clear interrupt flag [IF = 0]; 0xFA
|
||||||
|
cli
|
||||||
|
# To set up a stack, we simply set the esp register to point to the top of
|
||||||
|
# our stack (as it grows downwards).
|
||||||
|
mov $stack_top, %esp
|
||||||
|
# pass the initial ESP
|
||||||
|
push %esp
|
||||||
|
# pass Multiboot info structure
|
||||||
|
push %ebx
|
||||||
|
# pass Multiboot magic number
|
||||||
|
push %eax
|
||||||
|
# Call the boot_main() function inside boot.c
|
||||||
|
call boot_main
|
||||||
|
# Set interrupt flag [IF = 1]; 0xFA
|
||||||
|
# Clear interrupts and hang if we return from boot_main
|
||||||
|
cli
|
||||||
|
hang:
|
||||||
|
hlt
|
||||||
|
jmp hang
|
||||||
|
|
||||||
|
.global boot_kernel
|
||||||
|
boot_kernel:
|
||||||
|
mov 4(%esp),%edx # stack_pointer
|
||||||
|
mov 8(%esp),%ebx # entry
|
||||||
|
mov 12(%esp),%eax # boot info
|
||||||
|
mov %edx,%esp # set stack pointer
|
||||||
|
push %eax # push the boot info
|
||||||
|
call *%ebx # call the kernel main
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (bss)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.global stack_bottom
|
||||||
|
.global stack_top
|
||||||
|
.bss
|
||||||
|
.align 16
|
||||||
|
stack_bottom:
|
||||||
|
.skip KERNEL_STACK_SIZE
|
||||||
|
stack_top:
|
||||||
|
# the top of the stack is the bottom because the stack counts down
|
||||||
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file exception.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
extern isr_handler
|
|
||||||
|
|
||||||
; Macro used to define a ISR which does not push an error code.
|
|
||||||
%macro ISR_NOERR 1
|
|
||||||
global INT_%1
|
|
||||||
INT_%1:
|
|
||||||
cli
|
|
||||||
; A normal ISR stub that pops a dummy error code to keep a
|
|
||||||
; uniform stack frame
|
|
||||||
push 0
|
|
||||||
push %1
|
|
||||||
jmp isr_common
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
; Macro used to define a ISR which pushes an error code.
|
|
||||||
%macro ISR_ERR 1
|
|
||||||
global INT_%1
|
|
||||||
INT_%1:
|
|
||||||
cli
|
|
||||||
push %1
|
|
||||||
jmp isr_common
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
; Standard X86 interrupt service routines
|
|
||||||
ISR_NOERR 0
|
|
||||||
ISR_NOERR 1
|
|
||||||
ISR_NOERR 2
|
|
||||||
ISR_NOERR 3
|
|
||||||
ISR_NOERR 4
|
|
||||||
ISR_NOERR 5
|
|
||||||
ISR_NOERR 6
|
|
||||||
ISR_NOERR 7
|
|
||||||
ISR_ERR 8
|
|
||||||
ISR_NOERR 9
|
|
||||||
ISR_ERR 10
|
|
||||||
ISR_ERR 11
|
|
||||||
ISR_ERR 12
|
|
||||||
ISR_ERR 13
|
|
||||||
ISR_ERR 14
|
|
||||||
ISR_NOERR 15
|
|
||||||
ISR_NOERR 16
|
|
||||||
ISR_NOERR 17
|
|
||||||
ISR_NOERR 18
|
|
||||||
ISR_NOERR 19
|
|
||||||
ISR_NOERR 20
|
|
||||||
ISR_NOERR 21
|
|
||||||
ISR_NOERR 22
|
|
||||||
ISR_NOERR 23
|
|
||||||
ISR_NOERR 24
|
|
||||||
ISR_NOERR 25
|
|
||||||
ISR_NOERR 26
|
|
||||||
ISR_NOERR 27
|
|
||||||
ISR_NOERR 28
|
|
||||||
ISR_NOERR 29
|
|
||||||
ISR_NOERR 30
|
|
||||||
ISR_NOERR 31
|
|
||||||
|
|
||||||
ISR_NOERR 80
|
|
||||||
|
|
||||||
isr_common:
|
|
||||||
; Save all registers (eax, ecx, edx, ebx, esp, ebp, esi, edi)
|
|
||||||
pusha
|
|
||||||
|
|
||||||
; Save segment registers
|
|
||||||
push ds
|
|
||||||
push es
|
|
||||||
push fs
|
|
||||||
push gs
|
|
||||||
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
; CLD - Azzera la flag di Direzione
|
|
||||||
; Questa istruzione forza semplicemente a zero la flag di Direzione.
|
|
||||||
; Quando la flag di direzione vale 0 tutte le istruzioni per la
|
|
||||||
; manipolazione delle stringhe agiscono in avanti, cioè dagli indirizzi più
|
|
||||||
; bassi a quelli più alti.
|
|
||||||
; L'istruzione agisce dunque sui puntatori SI e DI producendo su essi un
|
|
||||||
; autoincremento proporzionale alla dimensione degli operandi trattati.
|
|
||||||
; Le sue caratteristiche sono riassunte nella seguente tabella (leggi le
|
|
||||||
; istruzioni Legenda della Tabella):
|
|
||||||
cld
|
|
||||||
|
|
||||||
; Call the interrupt handler.
|
|
||||||
push esp
|
|
||||||
call isr_handler
|
|
||||||
add esp, 0x4
|
|
||||||
|
|
||||||
; Restore segment registers.
|
|
||||||
pop gs
|
|
||||||
pop fs
|
|
||||||
pop es
|
|
||||||
pop ds
|
|
||||||
|
|
||||||
; Restore all registers (eax, ecx, edx, ebx, esp, ebp, esi, edi).
|
|
||||||
popa
|
|
||||||
|
|
||||||
; Cleanup error code and IRQ #
|
|
||||||
add esp, 0x8
|
|
||||||
|
|
||||||
|
|
||||||
iret ; pops 5 things at once:
|
|
||||||
; CS, EIP, EFLAGS, SS, and ESP
|
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file exception.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.extern isr_handler
|
||||||
|
|
||||||
|
# Macro used to define a ISR which does not push an error code.
|
||||||
|
.macro ISR_NOERR ARG1
|
||||||
|
.globl INT_&ARG1
|
||||||
|
INT_&ARG1:
|
||||||
|
cli
|
||||||
|
# A normal ISR stub that pops a dummy error code to keep a
|
||||||
|
# uniform stack frame
|
||||||
|
push $0
|
||||||
|
push &ARG1
|
||||||
|
jmp isr_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
# Macro used to define a ISR which pushes an error code.
|
||||||
|
.macro ISR_ERR ARG1
|
||||||
|
.globl INT_&ARG1
|
||||||
|
INT_&ARG1:
|
||||||
|
cli
|
||||||
|
push &ARG1
|
||||||
|
jmp isr_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
# Standard X86 interrupt service routines
|
||||||
|
ISR_NOERR 0
|
||||||
|
ISR_NOERR 1
|
||||||
|
ISR_NOERR 2
|
||||||
|
ISR_NOERR 3
|
||||||
|
ISR_NOERR 4
|
||||||
|
ISR_NOERR 5
|
||||||
|
ISR_NOERR 6
|
||||||
|
ISR_NOERR 7
|
||||||
|
ISR_ERR 8
|
||||||
|
ISR_NOERR 9
|
||||||
|
ISR_ERR 10
|
||||||
|
ISR_ERR 11
|
||||||
|
ISR_ERR 12
|
||||||
|
ISR_ERR 13
|
||||||
|
ISR_ERR 14
|
||||||
|
ISR_NOERR 15
|
||||||
|
ISR_NOERR 16
|
||||||
|
ISR_NOERR 17
|
||||||
|
ISR_NOERR 18
|
||||||
|
ISR_NOERR 19
|
||||||
|
ISR_NOERR 20
|
||||||
|
ISR_NOERR 21
|
||||||
|
ISR_NOERR 22
|
||||||
|
ISR_NOERR 23
|
||||||
|
ISR_NOERR 24
|
||||||
|
ISR_NOERR 25
|
||||||
|
ISR_NOERR 26
|
||||||
|
ISR_NOERR 27
|
||||||
|
ISR_NOERR 28
|
||||||
|
ISR_NOERR 29
|
||||||
|
ISR_NOERR 30
|
||||||
|
ISR_NOERR 31
|
||||||
|
ISR_NOERR 80
|
||||||
|
|
||||||
|
isr_common:
|
||||||
|
# Save all registers (eax, ecx, edx, ebx, esp, ebp, esi, edi)
|
||||||
|
pusha
|
||||||
|
|
||||||
|
# Save segment registers
|
||||||
|
push %ds
|
||||||
|
push %es
|
||||||
|
push %fs
|
||||||
|
push %gs
|
||||||
|
|
||||||
|
mov $0x10,%ax
|
||||||
|
mov %ax,%ds
|
||||||
|
mov %ax,%es
|
||||||
|
mov %ax,%fs
|
||||||
|
mov %ax,%gs
|
||||||
|
# CLD - Azzera la flag di Direzione
|
||||||
|
# Questa istruzione forza semplicemente a zero la flag di Direzione.
|
||||||
|
# Quando la flag di direzione vale 0 tutte le istruzioni per la
|
||||||
|
# manipolazione delle stringhe agiscono in avanti, cioè dagli indirizzi più
|
||||||
|
# bassi a quelli più alti.
|
||||||
|
# L'istruzione agisce dunque sui puntatori SI e DI producendo su essi un
|
||||||
|
# autoincremento proporzionale alla dimensione degli operandi trattati.
|
||||||
|
# Le sue caratteristiche sono riassunte nella seguente tabella (leggi le
|
||||||
|
# istruzioni Legenda della Tabella):
|
||||||
|
cld
|
||||||
|
|
||||||
|
# Call the interrupt handler.
|
||||||
|
push %esp
|
||||||
|
call isr_handler
|
||||||
|
add $0x4,%esp
|
||||||
|
|
||||||
|
# Restore segment registers.
|
||||||
|
pop %gs
|
||||||
|
pop %fs
|
||||||
|
pop %es
|
||||||
|
pop %ds
|
||||||
|
|
||||||
|
# Restore all registers (eax, ecx, edx, ebx, esp, ebp, esi, edi).
|
||||||
|
popa
|
||||||
|
|
||||||
|
# Cleanup error code and IRQ #
|
||||||
|
add $0x8,%esp
|
||||||
|
|
||||||
|
|
||||||
|
iret # pops 5 things at once:
|
||||||
|
# CS, EIP, EFLAGS, SS, and ESP
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file gdt.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
global gdt_flush ; Allows the C code to call gdt_flush().
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
gdt_flush:
|
|
||||||
mov eax, [esp+4] ; Get the pointer to the GDT, passed as a parameter.
|
|
||||||
lgdt [eax] ; Load the new GDT pointer
|
|
||||||
|
|
||||||
; The data segments selectors (registers), can be easily modified using
|
|
||||||
; simple mov instruction, but the cs can't be used with mov, so you use:
|
|
||||||
jmp 0x08:flush
|
|
||||||
; to load the segment configurations into the the code segment selector.
|
|
||||||
|
|
||||||
flush:
|
|
||||||
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
|
|
||||||
mov ds, ax ; Load all data segment selectors
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
mov ss, ax
|
|
||||||
ret
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file gdt.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.global gdt_flush # Allows the C code to call gdt_flush().
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
gdt_flush:
|
||||||
|
mov 4(%esp),%eax # Get the pointer to the GDT, passed as a parameter.
|
||||||
|
lgdt (%eax)
|
||||||
|
|
||||||
|
# The data segments selectors (registers), can be easily modified using
|
||||||
|
# simple mov instruction, but the cs can't be used with mov, so you use:
|
||||||
|
mov $0x10,%ax # 0x10 is the offset in the GDT to our data segment
|
||||||
|
mov %ax,%ds # Load all data segment selectors
|
||||||
|
mov %ax,%es
|
||||||
|
mov %ax,%fs
|
||||||
|
mov %ax,%gs
|
||||||
|
mov %ax,%ss
|
||||||
|
|
||||||
|
# to load the segment configurations into the the code segment selector.
|
||||||
|
ret
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file idt.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
global idt_flush ; Allows the C code to call idt_flush().
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
idt_flush:
|
|
||||||
mov eax, [esp+4] ; Get the pointer to the IDT, passed as a parameter.
|
|
||||||
lidt [eax] ; Load the IDT pointer.
|
|
||||||
ret
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file idt.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.global idt_flush # Allows the C code to call idt_flush().
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
idt_flush:
|
||||||
|
mov 4(%esp),%eax # Get the pointer to the IDT, passed as a parameter.
|
||||||
|
lidt (%eax)
|
||||||
|
ret
|
||||||
@@ -1,28 +1,26 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
# MentOS, The Mentoring Operating system project
|
||||||
; @file interrupt.asm
|
# @file interrupt.asm
|
||||||
; @brief
|
# @brief
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
; See LICENSE.md for details.
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
extern irq_handler
|
.extern irq_handler
|
||||||
|
|
||||||
%macro IRQ 2
|
.macro IRQ ARG1, ARG2
|
||||||
global IRQ_%1
|
.globl IRQ_&ARG1
|
||||||
IRQ_%1:
|
IRQ_&ARG1:
|
||||||
cli ; disable interrupt line
|
cli # disable interrupt line
|
||||||
; A normal ISR stub that pops a dummy error code to keep a
|
push $0
|
||||||
; uniform stack frame
|
push &ARG2
|
||||||
push 0
|
|
||||||
push %2 ; irq number
|
|
||||||
jmp irq_common
|
jmp irq_common
|
||||||
%endmacro
|
.endm
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
; SECTION (text)
|
# SECTION (text)
|
||||||
; -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
section .text
|
.text
|
||||||
|
|
||||||
; 32 is the first irq, 47 is the last one. DO NOT CHANGE THESE NUMBERS.
|
# 32 is the first irq, 47 is the last one. DO NOT CHANGE THESE NUMBERS.
|
||||||
IRQ 0, 32
|
IRQ 0, 32
|
||||||
IRQ 1, 33
|
IRQ 1, 33
|
||||||
IRQ 2, 34
|
IRQ 2, 34
|
||||||
@@ -41,51 +39,51 @@ IRQ 14, 46
|
|||||||
IRQ 15, 47
|
IRQ 15, 47
|
||||||
|
|
||||||
irq_common:
|
irq_common:
|
||||||
;==== Save CPU registers ===================================================
|
# ==== Save CPU registers ===================================================
|
||||||
; when an irq occurs, the following registers are already pushed on stack:
|
# when an irq occurs, the following registers are already pushed on stack:
|
||||||
; eip, cs, eflags, useresp, ss
|
# eip, cs, eflags, useresp, ss
|
||||||
|
|
||||||
; Save registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
# Save registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
; Save segment registers
|
# Save segment registers
|
||||||
push ds
|
push %ds
|
||||||
push es
|
push %es
|
||||||
push fs
|
push %fs
|
||||||
push gs
|
push %gs
|
||||||
;---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
;==== ensure we are using kernel data segment ==============================
|
# ==== ensure we are using kernel data segment ==============================
|
||||||
mov ax, 0x10
|
mov $0x10,%ax
|
||||||
mov ds, ax
|
mov %ax,%ds
|
||||||
mov es, ax
|
mov %ax,%es
|
||||||
mov fs, ax
|
mov %ax,%fs
|
||||||
mov gs, ax
|
mov %ax,%gs
|
||||||
cld
|
cld
|
||||||
;---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
;==== Call the interrupt handler ===========================================
|
# ==== Call the interrupt handler ===========================================
|
||||||
; The argument passed is a pointer to an Interrupt_State struct,
|
# The argument passed is a pointer to an Interrupt_State struct,
|
||||||
; which describes the stack layout for all interrupts.
|
# which describes the stack layout for all interrupts.
|
||||||
push esp
|
push %esp
|
||||||
call irq_handler
|
call irq_handler
|
||||||
add esp, $4 ; remove esp from stack
|
add $0x04, %esp # remove esp from stack
|
||||||
;---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
;==== Restore registers ====================================================
|
# ==== Restore registers ====================================================
|
||||||
; restore segment registers
|
# restore segment registers
|
||||||
pop gs
|
pop %gs
|
||||||
pop fs
|
pop %fs
|
||||||
pop es
|
pop %es
|
||||||
pop ds
|
pop %ds
|
||||||
|
|
||||||
; restore registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
# restore registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||||
popa
|
popa
|
||||||
;---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
; Cleanup error code and IRQ #
|
# Cleanup error code and IRQ #
|
||||||
add esp, $8
|
add $0x08, %esp
|
||||||
|
|
||||||
; return to process
|
# return to process
|
||||||
iret ; pops 5 things at once:
|
iret # pops 5 things at once:
|
||||||
; CS, EIP, EFLAGS, SS, and ESP
|
# CS, EIP, EFLAGS, SS, and ESP
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file interrupt.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.extern irq_handler
|
||||||
|
|
||||||
|
.macro IRQ ARG1, ARG2
|
||||||
|
.globl IRQ_&ARG1
|
||||||
|
IRQ_&ARG1:
|
||||||
|
cli # disable interrupt line
|
||||||
|
push $0
|
||||||
|
push &ARG2
|
||||||
|
jmp irq_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
# 32 is the first irq, 47 is the last one. DO NOT CHANGE THESE NUMBERS.
|
||||||
|
IRQ 0, 32
|
||||||
|
IRQ 1, 33
|
||||||
|
IRQ 2, 34
|
||||||
|
IRQ 3, 35
|
||||||
|
IRQ 4, 36
|
||||||
|
IRQ 5, 37
|
||||||
|
IRQ 6, 38
|
||||||
|
IRQ 7, 39
|
||||||
|
IRQ 8, 40
|
||||||
|
IRQ 9, 41
|
||||||
|
IRQ 10, 42
|
||||||
|
IRQ 11, 43
|
||||||
|
IRQ 12, 44
|
||||||
|
IRQ 13, 45
|
||||||
|
IRQ 14, 46
|
||||||
|
IRQ 15, 47
|
||||||
|
|
||||||
|
irq_common:
|
||||||
|
# ==== Save CPU registers ===================================================
|
||||||
|
# when an irq occurs, the following registers are already pushed on stack:
|
||||||
|
# eip, cs, eflags, useresp, ss
|
||||||
|
|
||||||
|
# Save registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||||
|
pusha
|
||||||
|
|
||||||
|
# Save segment registers
|
||||||
|
push %ds
|
||||||
|
push %es
|
||||||
|
push %fs
|
||||||
|
push %gs
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== ensure we are using kernel data segment ==============================
|
||||||
|
mov $0x10,%ax
|
||||||
|
mov %ax,%ds
|
||||||
|
mov %ax,%es
|
||||||
|
mov %ax,%fs
|
||||||
|
mov %ax,%gs
|
||||||
|
cld
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== Call the interrupt handler ===========================================
|
||||||
|
# The argument passed is a pointer to an Interrupt_State struct,
|
||||||
|
# which describes the stack layout for all interrupts.
|
||||||
|
push %esp
|
||||||
|
call irq_handler
|
||||||
|
add $0x04, %esp # remove esp from stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== Restore registers ====================================================
|
||||||
|
# restore segment registers
|
||||||
|
pop %gs
|
||||||
|
pop %fs
|
||||||
|
pop %es
|
||||||
|
pop %ds
|
||||||
|
|
||||||
|
# restore registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||||
|
popa
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Cleanup error code and IRQ #
|
||||||
|
add $0x08, %esp
|
||||||
|
|
||||||
|
# return to process
|
||||||
|
iret # pops 5 things at once:
|
||||||
|
# CS, EIP, EFLAGS, SS, and ESP
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file tss.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
global tss_flush
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
tss_flush:
|
|
||||||
mov ax, 0x28
|
|
||||||
ltr ax
|
|
||||||
ret
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file tss.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
.global tss_flush
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
tss_flush:
|
||||||
|
mov $0x28,%ax
|
||||||
|
ltr %ax
|
||||||
|
ret
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
// Setup the logging for this file (do this before any other include).
|
// Setup the logging for this file (do this before any other include).
|
||||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||||
#define __DEBUG_HEADER__ "[ELF ]" ///< Change header.
|
#define __DEBUG_HEADER__ "[ELF ]" ///< Change header.
|
||||||
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE ///< Set log level.
|
#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG ///< Set log level.
|
||||||
#include "io/debug.h" // Include debugging functions.
|
#include "io/debug.h" // Include debugging functions.
|
||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|||||||
+23
-45
@@ -43,28 +43,6 @@ char *module_start[MAX_MODULES];
|
|||||||
/// Describe end address of grub multiboot modules.
|
/// Describe end address of grub multiboot modules.
|
||||||
char *module_end[MAX_MODULES];
|
char *module_end[MAX_MODULES];
|
||||||
|
|
||||||
// Everything is defined in kernel.ld.
|
|
||||||
|
|
||||||
/// Points at the multiheader grub info, starting address.
|
|
||||||
extern uint32_t _multiboot_header_start;
|
|
||||||
/// Points at the multiheader grub info, ending address.
|
|
||||||
extern uint32_t _multiboot_header_end;
|
|
||||||
/// Points at the kernel code, starting address.
|
|
||||||
extern uint32_t _text_start;
|
|
||||||
/// Points at the kernel code, ending address.
|
|
||||||
extern uint32_t _text_end;
|
|
||||||
/// Points at the read-only kernel data, starting address.
|
|
||||||
extern uint32_t _rodata_start;
|
|
||||||
/// Points at the read-only kernel data, ending address.
|
|
||||||
extern uint32_t _rodata_end;
|
|
||||||
/// Points at the read-write kernel data initialized, starting address.
|
|
||||||
extern uint32_t _data_start;
|
|
||||||
/// Points at the read-write kernel data initialized, ending address.
|
|
||||||
extern uint32_t _data_end;
|
|
||||||
/// Points at the read-write kernel data uninitialized an kernel stack, starting address.
|
|
||||||
extern uint32_t _bss_start;
|
|
||||||
/// Points at the read-write kernel data uninitialized an kernel stack, ending address.
|
|
||||||
extern uint32_t _bss_end;
|
|
||||||
/// Points at the top of the kernel stack.
|
/// Points at the top of the kernel stack.
|
||||||
extern uint32_t stack_top;
|
extern uint32_t stack_top;
|
||||||
/// Points at the bottom of the kernel stack.
|
/// Points at the bottom of the kernel stack.
|
||||||
@@ -107,8 +85,8 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
boot_info = *boot_informations;
|
boot_info = *boot_informations;
|
||||||
// Am I booted by a Multiboot-compliant boot loader?
|
// Am I booted by a Multiboot-compliant boot loader?
|
||||||
if (boot_info.magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
if (boot_info.magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||||
printf("Invalid magic number: 0x%x\n", boot_info.magic);
|
pr_emerg("Invalid magic number: 0x%x\n", boot_info.magic);
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
// Set the initial esp.
|
// Set the initial esp.
|
||||||
initial_esp = boot_info.stack_base;
|
initial_esp = boot_info.stack_base;
|
||||||
@@ -131,7 +109,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize modules...");
|
printf("Initialize modules...");
|
||||||
if (!init_modules(boot_info.multiboot_header)) {
|
if (!init_modules(boot_info.multiboot_header)) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -140,7 +118,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize physical memory manager...");
|
printf("Initialize physical memory manager...");
|
||||||
if (!pmmngr_init(&boot_info)) {
|
if (!pmmngr_init(&boot_info)) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -216,7 +194,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize ATA devices...");
|
printf("Initialize ATA devices...");
|
||||||
if (ata_initialize()) {
|
if (ata_initialize()) {
|
||||||
pr_emerg("Failed to initialize ATA devices!\n");
|
pr_emerg("Failed to initialize ATA devices!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -225,7 +203,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize EXT2 filesystem...");
|
printf("Initialize EXT2 filesystem...");
|
||||||
if (ext2_initialize()) {
|
if (ext2_initialize()) {
|
||||||
pr_emerg("Failed to initialize EXT2 filesystem!\n");
|
pr_emerg("Failed to initialize EXT2 filesystem!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -234,7 +212,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Mount EXT2 filesystem...");
|
printf("Mount EXT2 filesystem...");
|
||||||
if (do_mount("ext2", "/", "/dev/hda")) {
|
if (do_mount("ext2", "/", "/dev/hda")) {
|
||||||
pr_emerg("Failed to mount EXT2 filesystem...\n");
|
pr_emerg("Failed to mount EXT2 filesystem...\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -244,7 +222,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (procfs_module_init()) {
|
if (procfs_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to register `procfs`!\n");
|
pr_emerg("Failed to register `procfs`!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -253,7 +231,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf(" Mounting 'procfs'...");
|
printf(" Mounting 'procfs'...");
|
||||||
if (do_mount("procfs", "/proc", NULL)) {
|
if (do_mount("procfs", "/proc", NULL)) {
|
||||||
pr_emerg("Failed to mount procfs at `/proc`!\n");
|
pr_emerg("Failed to mount procfs at `/proc`!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -263,7 +241,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (procv_module_init()) {
|
if (procv_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize `/proc/video`!\n");
|
pr_emerg("Failed to initialize `/proc/video`!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -273,7 +251,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (procs_module_init()) {
|
if (procs_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize proc system entries!\n");
|
pr_emerg("Failed to initialize proc system entries!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -283,7 +261,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (procipc_module_init()) {
|
if (procipc_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize the IPC information system!\n");
|
pr_emerg("Failed to initialize the IPC information system!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -293,7 +271,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (sem_init()) {
|
if (sem_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize the IPC/SEM system!\n");
|
pr_emerg("Failed to initialize the IPC/SEM system!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -303,7 +281,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (msq_init()) {
|
if (msq_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize the IPC/MSQ system!\n");
|
pr_emerg("Failed to initialize the IPC/MSQ system!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -313,7 +291,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (shm_init()) {
|
if (shm_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize the IPC/SHM system!\n");
|
pr_emerg("Failed to initialize the IPC/SHM system!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -328,7 +306,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
if (ps2_initialize()) {
|
if (ps2_initialize()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
pr_emerg("Failed to initialize proc system entries!\n");
|
pr_emerg("Failed to initialize proc system entries!\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -365,7 +343,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Init process management...");
|
printf("Init process management...");
|
||||||
if (!init_tasking()) {
|
if (!init_tasking()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -375,7 +353,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize scheduler feedback system...");
|
printf("Initialize scheduler feedback system...");
|
||||||
if (!scheduler_feedback_init()) {
|
if (!scheduler_feedback_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
#endif
|
#endif
|
||||||
@@ -385,7 +363,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize scheduler feedback system (2)...");
|
printf("Initialize scheduler feedback system (2)...");
|
||||||
if (procfb_module_init()) {
|
if (procfb_module_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -395,7 +373,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
task_struct *init_p = process_create_init("/bin/init");
|
task_struct *init_p = process_create_init("/bin/init");
|
||||||
if (!init_p) {
|
if (!init_p) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -404,7 +382,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize floating point unit...");
|
printf("Initialize floating point unit...");
|
||||||
if (!fpu_install()) {
|
if (!fpu_install()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -413,7 +391,7 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
printf("Initialize signals...");
|
printf("Initialize signals...");
|
||||||
if (!signals_init()) {
|
if (!signals_init()) {
|
||||||
print_fail();
|
print_fail();
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
print_ok();
|
print_ok();
|
||||||
|
|
||||||
@@ -432,5 +410,5 @@ int kmain(boot_info_t *boot_informations)
|
|||||||
for (;;) {}
|
for (;;) {}
|
||||||
// We should not be here.
|
// We should not be here.
|
||||||
pr_emerg("Dear developer, we have to talk...\n");
|
pr_emerg("Dear developer, we have to talk...\n");
|
||||||
return 1;
|
while (1) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
// Setup the logging for this file (do this before any other include).
|
// Setup the logging for this file (do this before any other include).
|
||||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||||
#define __DEBUG_HEADER__ "[PROC ]" ///< Change header.
|
#define __DEBUG_HEADER__ "[PROC ]" ///< Change header.
|
||||||
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE ///< Set log level.
|
#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG ///< Set log level.
|
||||||
#include "io/debug.h" // Include debugging functions.
|
#include "io/debug.h" // Include debugging functions.
|
||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "elf/elf.h"
|
#include "elf/elf.h"
|
||||||
@@ -91,11 +91,15 @@ static int __reset_process(task_struct *task)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr_debug("Switching to task page directory.\n");
|
||||||
|
|
||||||
// Save the current page directory.
|
// Save the current page directory.
|
||||||
page_directory_t *crtdir = paging_get_current_directory();
|
page_directory_t *crtdir = paging_get_current_directory();
|
||||||
// FIXME: Now to clear the stack a pgdir switch is made, it should be a kernel mmapping.
|
// FIXME: Now to clear the stack a pgdir switch is made, it should be a kernel mmapping.
|
||||||
paging_switch_directory_va(task->mm->pgd);
|
paging_switch_directory_va(task->mm->pgd);
|
||||||
|
|
||||||
|
pr_debug("Clean stack (%p).\n", task->mm->start_stack);
|
||||||
|
|
||||||
// Clean stack space.
|
// Clean stack space.
|
||||||
memset((char *)task->mm->start_stack, 0, DEFAULT_STACK_SIZE);
|
memset((char *)task->mm->start_stack, 0, DEFAULT_STACK_SIZE);
|
||||||
// Set the base address of the stack.
|
// Set the base address of the stack.
|
||||||
@@ -105,6 +109,8 @@ static int __reset_process(task_struct *task)
|
|||||||
// Enable the interrupts.
|
// Enable the interrupts.
|
||||||
task->thread.regs.eflags = task->thread.regs.eflags | EFLAG_IF;
|
task->thread.regs.eflags = task->thread.regs.eflags | EFLAG_IF;
|
||||||
|
|
||||||
|
pr_debug("Switching to previous page directory.\n");
|
||||||
|
|
||||||
// Restore previous pgdir
|
// Restore previous pgdir
|
||||||
paging_switch_directory(crtdir);
|
paging_switch_directory(crtdir);
|
||||||
|
|
||||||
|
|||||||
@@ -517,7 +517,7 @@ pid_t sys_waitpid(pid_t pid, int *status, int options)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_exit(int exit_code)
|
void do_exit(int exit_code)
|
||||||
{
|
{
|
||||||
// Get the current task.
|
// Get the current task.
|
||||||
if (runqueue.curr == NULL) {
|
if (runqueue.curr == NULL) {
|
||||||
@@ -573,6 +573,11 @@ void sys_exit(int exit_code)
|
|||||||
pr_debug("Process %d exited with value %d\n", runqueue.curr->pid, exit_code);
|
pr_debug("Process %d exited with value %d\n", runqueue.curr->pid, exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sys_exit(int exit_code)
|
||||||
|
{
|
||||||
|
do_exit(exit_code << 8);
|
||||||
|
}
|
||||||
|
|
||||||
int sys_sched_setparam(pid_t pid, const sched_param_t *param)
|
int sys_sched_setparam(pid_t pid, const sched_param_t *param)
|
||||||
{
|
{
|
||||||
list_head *it;
|
list_head *it;
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
; MentOS, The Mentoring Operating system project
|
|
||||||
; @file user.asm
|
|
||||||
; @brief
|
|
||||||
; @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
||||||
; See LICENSE.md for details.
|
|
||||||
|
|
||||||
; Enter userspace (ring3) (from Ring 0, namely Kernel)
|
|
||||||
; Usage: enter_userspace(uintptr_t location, uintptr_t stack);
|
|
||||||
; On stack
|
|
||||||
; | stack | [ebp + 0x0C] ARG1
|
|
||||||
; | location | [ebp + 0x08] ARG0
|
|
||||||
; | return address | [ebp + 0x04]
|
|
||||||
; | EBP | [ebp + 0x00]
|
|
||||||
; | SS |
|
|
||||||
; | ESP |
|
|
||||||
; | EFLAGS |
|
|
||||||
; | CS |
|
|
||||||
; | EIP |
|
|
||||||
|
|
||||||
; We can use the following macros to access the arguments ONLY AFTER 0x23 is
|
|
||||||
; pushed onto the stack, in fact, the first argument is after 0x08 because
|
|
||||||
; we just pushed first `ebp` and then `0x23`.
|
|
||||||
%define ARG0 [ebp + 0x08] ; Argument 0
|
|
||||||
%define ARG1 [ebp + 0x0C] ; Argument 1
|
|
||||||
%define ARG2 [ebp + 0x10] ; Argument 2
|
|
||||||
%define ARG3 [ebp + 0x14] ; Argument 3
|
|
||||||
%define ARG4 [ebp + 0x18] ; Argument 4
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; SECTION (text)
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
section .text
|
|
||||||
|
|
||||||
global enter_userspace ; Allows the C code to call enter_userspace(...).
|
|
||||||
|
|
||||||
enter_userspace:
|
|
||||||
|
|
||||||
push ebp ; Save current ebp
|
|
||||||
mov ebp, esp ; open a new stack frame
|
|
||||||
|
|
||||||
;==== Segment selector =====================================================
|
|
||||||
mov ax, 0x23
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
; we don't need to worry about SS. it's handled by iret
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; We have to prepare the following stack before executing iret
|
|
||||||
; SS --> Segment selector
|
|
||||||
; ESP --> Stack address
|
|
||||||
; EFLAGS --> CPU state flgas
|
|
||||||
; CS --> Code segment
|
|
||||||
; EIP --> Entry point
|
|
||||||
;
|
|
||||||
|
|
||||||
;==== User data segmenet with bottom 2 bits set for ring3 ?=================
|
|
||||||
push 0x23 ; push SS on Kernel's stack
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;==== (ESP) Stack address ==================================================
|
|
||||||
mov eax, ARG1 ; get uintptr_t stack
|
|
||||||
push eax ; push process's stack address on Kernel's stack
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;==== (EFLAGS) =============================================================
|
|
||||||
pushf ; push EFLAGS into Kernel's stack
|
|
||||||
pop eax ; pop EFLAGS into eax
|
|
||||||
or eax, 0x200 ; enable interrupt
|
|
||||||
push eax ; push new EFLAGS on Kernel's stack
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;==== (CS) Code Segment ====================================================
|
|
||||||
push 0x1b ;
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
;==== (EIP) Entry point ====================================================
|
|
||||||
mov eax, ARG0 ; get uintptr_t location
|
|
||||||
push eax ; push uintptr_t location on Kernel's stack
|
|
||||||
;---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
iret ; interrupt return
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
; WE SHOULD NOT STILL BE HERE! :(p
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# MentOS, The Mentoring Operating system project
|
||||||
|
# @file user.asm
|
||||||
|
# @brief
|
||||||
|
# @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
||||||
|
# See LICENSE.md for details.
|
||||||
|
|
||||||
|
# Enter userspace (ring3) (from Ring 0, namely Kernel)
|
||||||
|
# Usage: enter_userspace(uintptr_t location, uintptr_t stack);
|
||||||
|
# On stack
|
||||||
|
# | stack | [ebp + 0x0C] ARG1
|
||||||
|
# | location | [ebp + 0x08] ARG0
|
||||||
|
# | return address | [ebp + 0x04]
|
||||||
|
# | EBP | [ebp + 0x00]
|
||||||
|
# | SS |
|
||||||
|
# | ESP |
|
||||||
|
# | EFLAGS |
|
||||||
|
# | CS |
|
||||||
|
# | EIP |
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# SECTION (text)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
.text
|
||||||
|
|
||||||
|
.global enter_userspace # Allows the C code to call enter_userspace(...).
|
||||||
|
|
||||||
|
enter_userspace:
|
||||||
|
|
||||||
|
push %ebp # Save current ebp
|
||||||
|
mov %esp,%ebp # open a new stack frame
|
||||||
|
|
||||||
|
# ==== Segment selector =====================================================
|
||||||
|
mov $0x23,%ax
|
||||||
|
mov %ax,%ds
|
||||||
|
mov %ax,%es
|
||||||
|
mov %ax,%fs
|
||||||
|
mov %ax,%gs
|
||||||
|
# we don't need to worry about SS. it's handled by iret
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# We have to prepare the following stack before executing iret
|
||||||
|
# SS --> Segment selector
|
||||||
|
# ESP --> Stack address
|
||||||
|
# EFLAGS --> CPU state flgas
|
||||||
|
# CS --> Code segment
|
||||||
|
# EIP --> Entry point
|
||||||
|
#
|
||||||
|
|
||||||
|
# ==== User data segmenet with bottom 2 bits set for ring3 ?=================
|
||||||
|
push $0x23 # push SS on Kernel's stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== (ESP) Stack address ==================================================
|
||||||
|
mov 0x0C(%ebp),%eax # get uintptr_t stack
|
||||||
|
push %eax # push process's stack address on Kernel's stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== (EFLAGS) =============================================================
|
||||||
|
pushf # push EFLAGS into Kernel's stack
|
||||||
|
pop %eax # pop EFLAGS into eax
|
||||||
|
or $0x200,%eax # enable interrupt
|
||||||
|
push %eax # push new EFLAGS on Kernel's stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== (CS) Code Segment ====================================================
|
||||||
|
push $0x1b #
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ==== (EIP) Entry point ====================================================
|
||||||
|
mov 0x08(%ebp),%eax # get uintptr_t location
|
||||||
|
push %eax # push uintptr_t location on Kernel's stack
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
iret # interrupt return
|
||||||
|
pop %ebp
|
||||||
|
ret
|
||||||
|
|
||||||
|
# WE SHOULD NOT STILL BE HERE! :(p
|
||||||
+10
-10
@@ -495,38 +495,38 @@ int do_signal(struct pt_regs *f)
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
case SIGQUIT:
|
case SIGQUIT:
|
||||||
sys_exit(GET_EXIT_STATUS(1));
|
do_exit(GET_EXIT_STATUS(1));
|
||||||
continue;
|
continue;
|
||||||
case SIGILL:
|
case SIGILL:
|
||||||
sys_exit(GET_EXIT_STATUS(132));
|
do_exit(GET_EXIT_STATUS(132));
|
||||||
continue;
|
continue;
|
||||||
case SIGTRAP:
|
case SIGTRAP:
|
||||||
sys_exit(GET_EXIT_STATUS(133));
|
do_exit(GET_EXIT_STATUS(133));
|
||||||
continue;
|
continue;
|
||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
sys_exit(GET_EXIT_STATUS(134));
|
do_exit(GET_EXIT_STATUS(134));
|
||||||
continue;
|
continue;
|
||||||
case SIGFPE:
|
case SIGFPE:
|
||||||
sys_exit(GET_EXIT_STATUS(136) | signr);
|
do_exit(GET_EXIT_STATUS(136) | signr);
|
||||||
__unlock_task_sighand(current_process);
|
__unlock_task_sighand(current_process);
|
||||||
return 1;
|
return 1;
|
||||||
case SIGBUS:
|
case SIGBUS:
|
||||||
sys_exit(GET_EXIT_STATUS(138) | signr);
|
do_exit(GET_EXIT_STATUS(138) | signr);
|
||||||
__unlock_task_sighand(current_process);
|
__unlock_task_sighand(current_process);
|
||||||
return 1;
|
return 1;
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
sys_exit(GET_EXIT_STATUS(139) | signr);
|
do_exit(GET_EXIT_STATUS(139) | signr);
|
||||||
__unlock_task_sighand(current_process);
|
__unlock_task_sighand(current_process);
|
||||||
return 1;
|
return 1;
|
||||||
case SIGXCPU:
|
case SIGXCPU:
|
||||||
sys_exit(GET_EXIT_STATUS(158) | signr);
|
do_exit(GET_EXIT_STATUS(158) | signr);
|
||||||
__unlock_task_sighand(current_process);
|
__unlock_task_sighand(current_process);
|
||||||
case SIGXFSZ:
|
case SIGXFSZ:
|
||||||
sys_exit(GET_EXIT_STATUS(159) | signr);
|
do_exit(GET_EXIT_STATUS(159) | signr);
|
||||||
__unlock_task_sighand(current_process);
|
__unlock_task_sighand(current_process);
|
||||||
case SIGSYS:
|
case SIGSYS:
|
||||||
default:
|
default:
|
||||||
sys_exit(GET_EXIT_STATUS(exit_code) | signr);
|
do_exit(GET_EXIT_STATUS(exit_code) | signr);
|
||||||
__unlock_task_sighand(current_process);
|
__unlock_task_sighand(current_process);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+97
-75
@@ -1,15 +1,42 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Author: Enrico Fraccaroli
|
# BUILD
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Set the minimum required version of cmake.
|
# Add the executables (manually).
|
||||||
cmake_minimum_required(VERSION 3.1...3.22)
|
set(PROGRAMS
|
||||||
# Initialize the project.
|
nice.c
|
||||||
project(programs C)
|
ls.c
|
||||||
|
mkdir.c
|
||||||
# =============================================================================
|
ipcrm.c
|
||||||
# List of programs.
|
login.c
|
||||||
# =============================================================================
|
man.c
|
||||||
# Add your file in this list.
|
logo.c
|
||||||
|
shell.c
|
||||||
|
cpuid.c
|
||||||
|
clear.c
|
||||||
|
rmdir.c
|
||||||
|
poweroff.c
|
||||||
|
rm.c
|
||||||
|
cat.c
|
||||||
|
init.c
|
||||||
|
ps.c
|
||||||
|
kill.c
|
||||||
|
edit.c
|
||||||
|
sleep.c
|
||||||
|
date.c
|
||||||
|
echo.c
|
||||||
|
showpid.c
|
||||||
|
uname.c
|
||||||
|
ipcs.c
|
||||||
|
touch.c
|
||||||
|
uptime.c
|
||||||
|
pwd.c
|
||||||
|
env.c
|
||||||
|
)
|
||||||
|
# Set the directory where the compiled binaries will be placed.
|
||||||
|
set(MENTOS_BIN_DIR ${CMAKE_SOURCE_DIR}/files/bin)
|
||||||
|
# Create the directory.
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${MENTOS_BIN_DIR})
|
||||||
|
# Add the executables (manually).
|
||||||
set(PROGRAMS
|
set(PROGRAMS
|
||||||
init.c
|
init.c
|
||||||
cpuid.c
|
cpuid.c
|
||||||
@@ -41,77 +68,72 @@ set(PROGRAMS
|
|||||||
uptime.c
|
uptime.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
foreach(FILE_NAME ${PROGRAMS})
|
||||||
# C WARNINGs
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# We need to specify the name of the entry function.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -u_start")
|
|
||||||
|
|
||||||
# Warning flags.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
|
||||||
|
|
||||||
# Disable some specific warnings.
|
|
||||||
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-unknown-pragmas")
|
|
||||||
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(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-protector")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-pic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
|
||||||
endif()
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# BUILD
|
|
||||||
# =============================================================================
|
|
||||||
# Set the directory where the compiled binaries will be placed.
|
|
||||||
set(MENTOS_BIN_DIR ${CMAKE_SOURCE_DIR}/files/bin)
|
|
||||||
|
|
||||||
foreach(PROGRAM ${PROGRAMS})
|
|
||||||
# Prepare the program name.
|
# Prepare the program name.
|
||||||
string(REPLACE ".c" "" PROGRAM_NAME ${PROGRAM})
|
string(REPLACE ".c" "" EXECUTABLE_NAME ${FILE_NAME})
|
||||||
|
|
||||||
# Set the name of the target.
|
# Set the name of the target.
|
||||||
set(TARGET_NAME prog_${PROGRAM_NAME})
|
set(TARGET_NAME prog_${EXECUTABLE_NAME})
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# TEXT ADDRESS
|
||||||
|
# =========================================================================
|
||||||
|
# Randomize .text section address so when debugging symbols don't clash.
|
||||||
|
# The allowed range is from 256MB to 2.75GB
|
||||||
|
# Minimum allowed address: 0x10000000
|
||||||
|
# Max allowed address: 0xB0000000
|
||||||
|
string(MD5 RAND_HASH ${FILE_NAME})
|
||||||
|
string(SUBSTRING ${RAND_HASH} 1 3 TEXADDR_INFIX)
|
||||||
|
string(RANDOM LENGTH 1 ALPHABET 0123456789AB RANDOM_SEED ${RAND_HASH} TEXADDR_FIRST)
|
||||||
|
set(TEXT_ADDR 0x${TEXADDR_FIRST}${TEXADDR_INFIX}0000)
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# EXECUTABLE
|
||||||
|
# =========================================================================
|
||||||
|
set(TARGET_NAME prog_${EXECUTABLE_NAME})
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# TEXT ADDRESS
|
||||||
|
# =========================================================================
|
||||||
|
# Randomize .text section address so when debugging symbols don't clash.
|
||||||
|
# The allowed range is from 256MB to 2.75GB
|
||||||
|
# Minimum allowed address: 0x10000000
|
||||||
|
# Max allowed address: 0xB0000000
|
||||||
|
string(MD5 RAND_HASH ${FILE_NAME})
|
||||||
|
string(SUBSTRING ${RAND_HASH} 1 3 TEXADDR_INFIX)
|
||||||
|
string(RANDOM LENGTH 1 ALPHABET 0123456789AB RANDOM_SEED ${RAND_HASH} TEXADDR_FIRST)
|
||||||
|
set(TEXT_ADDR 0x${TEXADDR_FIRST}${TEXADDR_INFIX}0000)
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# EXECUTABLE
|
||||||
|
# =========================================================================
|
||||||
# Create the target.
|
# Create the target.
|
||||||
add_executable(${TARGET_NAME} ${PROGRAM})
|
add_executable(${TARGET_NAME} ${FILE_NAME})
|
||||||
|
# Add the dependency to libc.
|
||||||
|
add_dependencies(${TARGET_NAME} libc)
|
||||||
# Add the includes.
|
# Add the includes.
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/libc/inc)
|
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/libc/inc)
|
||||||
# Link the libc library.
|
# Link the libc library.
|
||||||
target_link_libraries(${TARGET_NAME} ${CMAKE_BINARY_DIR}/libc/libc.a)
|
target_link_libraries(${TARGET_NAME} libc)
|
||||||
# Add the dependency to libc.
|
# We need to specify the name of the entry function.
|
||||||
add_dependencies(${TARGET_NAME} libc)
|
target_compile_options(${TARGET_NAME} PRIVATE -u_start)
|
||||||
# Copy the progam to the bin folder.
|
# Add the linking properties.
|
||||||
add_custom_command(
|
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-Wl,-Ttext=${TEXT_ADDR},-e_start,-melf_i386")
|
||||||
TARGET ${TARGET_NAME}
|
# Set the output directory.
|
||||||
BYPRODUCTS ${MENTOS_BIN_DIR}/${PROGRAM_NAME}
|
set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${MENTOS_BIN_DIR}")
|
||||||
COMMAND mkdir -p ${MENTOS_BIN_DIR}
|
# Set the output name.
|
||||||
COMMAND cp ${PROJECT_BINARY_DIR}/${TARGET_NAME} ${MENTOS_BIN_DIR}/${PROGRAM_NAME}
|
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}")
|
||||||
DEPENDS ${TARGET_NAME}
|
|
||||||
)
|
target_link_libraries(${TARGET_NAME} libc)
|
||||||
|
# We need to specify the name of the entry function.
|
||||||
|
target_compile_options(${TARGET_NAME} PRIVATE -u_start)
|
||||||
|
# Add the linking properties.
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-Wl,-Ttext=${TEXT_ADDR},-e_start,-melf_i386")
|
||||||
|
# Set the output directory.
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${MENTOS_BIN_DIR}")
|
||||||
|
# Set the output name.
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}")
|
||||||
|
|
||||||
# Append the program name to the list of all the executables.
|
# Append the program name to the list of all the executables.
|
||||||
list(APPEND ALL_EXECUTABLES ${TARGET_NAME})
|
list(APPEND ALL_EXECUTABLES ${TARGET_NAME})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@@ -1,29 +1,26 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Author: Enrico Fraccaroli
|
# BUILD
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Set the minimum required version of cmake.
|
# Set the directory where the compiled binaries will be placed.
|
||||||
cmake_minimum_required(VERSION 3.1...3.22)
|
set(MENTOS_TESTS_DIR ${CMAKE_SOURCE_DIR}/files/bin/tests)
|
||||||
# Initialize the project.
|
# Create the directory.
|
||||||
project(tests C)
|
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${MENTOS_TESTS_DIR})
|
||||||
|
|
||||||
# =============================================================================
|
# Add the executables (manually).
|
||||||
# List of programs.
|
|
||||||
# =============================================================================
|
|
||||||
# Add your file in this list.
|
|
||||||
set(TESTS
|
set(TESTS
|
||||||
t_mem.c
|
t_mem.c
|
||||||
t_fork.c
|
t_fork.c
|
||||||
# Test real-time programs.
|
# Real-time programs
|
||||||
t_periodic1.c
|
t_periodic1.c
|
||||||
t_periodic2.c
|
t_periodic2.c
|
||||||
t_periodic3.c
|
t_periodic3.c
|
||||||
# Testing task execution.
|
# Exec
|
||||||
t_exec.c
|
t_exec.c
|
||||||
t_exec_callee.c
|
t_exec_callee.c
|
||||||
# Test environmental variables.
|
# Test environmental variables.
|
||||||
t_setenv.c
|
t_setenv.c
|
||||||
t_getenv.c
|
t_getenv.c
|
||||||
# Test signals.
|
# Test: signals.
|
||||||
t_stopcont.c
|
t_stopcont.c
|
||||||
t_sigusr.c
|
t_sigusr.c
|
||||||
t_abort.c
|
t_abort.c
|
||||||
@@ -37,91 +34,47 @@ set(TESTS
|
|||||||
t_kill.c
|
t_kill.c
|
||||||
t_itimer.c
|
t_itimer.c
|
||||||
t_gid.c
|
t_gid.c
|
||||||
# Test semaphores.
|
|
||||||
t_semget.c
|
|
||||||
t_semflg.c
|
|
||||||
t_semop.c
|
|
||||||
# Test message queues.
|
|
||||||
t_msgget.c
|
|
||||||
# Test shared memory.
|
|
||||||
t_shmget.c
|
|
||||||
t_shm_read.c
|
|
||||||
t_shm_write.c
|
|
||||||
# Test scheduling feedback tests.
|
|
||||||
t_schedfb.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
foreach(FILE_NAME ${TESTS})
|
||||||
# C WARNINGs
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# We need to specify the name of the entry function.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -u_start")
|
|
||||||
|
|
||||||
# Warning flags.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic-errors")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
|
|
||||||
|
|
||||||
# Disable some specific warnings.
|
|
||||||
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-unknown-pragmas")
|
|
||||||
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(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdlib")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-protector")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-pic")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
|
|
||||||
endif()
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686")
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
|
||||||
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# BUILD
|
|
||||||
# =============================================================================
|
|
||||||
# Set the directory where the compiled binaries will be placed.
|
|
||||||
set(MENTOS_TESTS_DIR ${CMAKE_SOURCE_DIR}/files/bin/tests)
|
|
||||||
|
|
||||||
foreach(TEST ${TESTS})
|
|
||||||
# Prepare the program name.
|
# Prepare the program name.
|
||||||
string(REPLACE ".c" "" TEST_NAME ${TEST})
|
string(REPLACE ".c" "" EXECUTABLE_NAME ${FILE_NAME})
|
||||||
|
|
||||||
# Set the name of the target.
|
# Set the name of the target.
|
||||||
set(TARGET_NAME test_${TEST_NAME})
|
set(TARGET_NAME test_${EXECUTABLE_NAME})
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# TEXT ADDRESS
|
||||||
|
# =========================================================================
|
||||||
|
# Randomize .text section address so when debugging symbols don't clash.
|
||||||
|
# The allowed range is from 256MB to 2.75GB
|
||||||
|
# Minimum allowed address: 0x10000000
|
||||||
|
# Max allowed address: 0xB0000000
|
||||||
|
string(MD5 RAND_HASH ${FILE_NAME})
|
||||||
|
string(SUBSTRING ${RAND_HASH} 1 3 TEXADDR_INFIX)
|
||||||
|
string(RANDOM LENGTH 1 ALPHABET 0123456789AB RANDOM_SEED ${RAND_HASH} TEXADDR_FIRST)
|
||||||
|
set(TEXT_ADDR 0x${TEXADDR_FIRST}${TEXADDR_INFIX}0000)
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# EXECUTABLE
|
||||||
|
# =========================================================================
|
||||||
# Create the target.
|
# Create the target.
|
||||||
add_executable(${TARGET_NAME} ${TEST})
|
add_executable(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/programs/tests/${FILE_NAME})
|
||||||
|
# Add the dependency to libc.
|
||||||
|
add_dependencies(${TARGET_NAME} libc)
|
||||||
# Add the includes.
|
# Add the includes.
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/libc/inc)
|
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/libc/inc)
|
||||||
# Link the libc library.
|
# Link the libc library.
|
||||||
target_link_libraries(${TARGET_NAME} ${CMAKE_BINARY_DIR}/libc/libc.a)
|
target_link_libraries(${TARGET_NAME} libc)
|
||||||
# Add the dependency to libc.
|
# We need to specify the name of the entry function.
|
||||||
add_dependencies(${TARGET_NAME} libc)
|
target_compile_options(${TARGET_NAME} PRIVATE -u_start)
|
||||||
# Copy the progam to the bin folder.
|
# Add the linking properties.
|
||||||
add_custom_command(
|
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-Wl,-Ttext=${TEXT_ADDR},-e_start,-melf_i386")
|
||||||
TARGET ${TARGET_NAME}
|
# Set the output directory.
|
||||||
BYPRODUCTS ${MENTOS_TESTS_DIR}/${TEST_NAME}
|
set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${MENTOS_TESTS_DIR}")
|
||||||
COMMAND mkdir -p ${MENTOS_TESTS_DIR}
|
# Set the output name.
|
||||||
COMMAND cp ${PROJECT_BINARY_DIR}/${TARGET_NAME} ${MENTOS_TESTS_DIR}/${TEST_NAME}
|
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}")
|
||||||
DEPENDS ${TARGET_NAME}
|
|
||||||
)
|
|
||||||
# Append the program name to the list of all the executables.
|
# Append the program name to the list of all the executables.
|
||||||
list(APPEND ALL_TESTS ${TARGET_NAME})
|
list(APPEND ALL_TESTS ${TARGET_NAME})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ void sig_handler(int sig)
|
|||||||
{
|
{
|
||||||
printf("handler(%d) : Starting handler.\n", sig);
|
printf("handler(%d) : Starting handler.\n", sig);
|
||||||
if (sig == SIGABRT) {
|
if (sig == SIGABRT) {
|
||||||
|
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
counter += 1;
|
counter += 1;
|
||||||
|
|
||||||
@@ -38,8 +37,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sigaction(SIGABRT, &action, NULL) == -1) {
|
if (sigaction(SIGABRT, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGABRT, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGABRT, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,12 +39,11 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = alarm_handler;
|
action.sa_handler = alarm_handler;
|
||||||
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
alarm(5);
|
alarm(5);
|
||||||
while(1) { }
|
while (1) {}
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ int main(int argc, char *argv[])
|
|||||||
int status;
|
int status;
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
__print_usage(argc, argv);
|
__print_usage(argc, argv);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
||||||
printf("Failed to set env: `ENV_VAR`\n");
|
printf("Failed to set env: `ENV_VAR`\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *file = "echo";
|
char *file = "echo";
|
||||||
@@ -54,11 +54,11 @@ int main(int argc, char *argv[])
|
|||||||
execvpe(file, exec_argv, exec_envp);
|
execvpe(file, exec_argv, exec_envp);
|
||||||
} else {
|
} else {
|
||||||
__print_usage(argc, argv);
|
__print_usage(argc, argv);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("Exec failed.\n");
|
printf("Exec failed.\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
wait(&status);
|
wait(&status);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ int main(int argc, char *argv[])
|
|||||||
char *ENV_VAR = getenv("ENV_VAR");
|
char *ENV_VAR = getenv("ENV_VAR");
|
||||||
if (ENV_VAR == NULL) {
|
if (ENV_VAR == NULL) {
|
||||||
printf("Failed to get env: `ENV_VAR`\n");
|
printf("Failed to get env: `ENV_VAR`\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("ENV_VAR = %s\n", ENV_VAR);
|
printf("ENV_VAR = %s\n", ENV_VAR);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int N;
|
int N;
|
||||||
@@ -61,5 +61,5 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ int main(int argc, char *argv[])
|
|||||||
char *ENV_VAR = getenv("ENV_VAR");
|
char *ENV_VAR = getenv("ENV_VAR");
|
||||||
if (ENV_VAR == NULL) {
|
if (ENV_VAR == NULL) {
|
||||||
printf("Failed to get env: `ENV_VAR`\n");
|
printf("Failed to get env: `ENV_VAR`\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("ENV_VAR = %s\n", ENV_VAR);
|
printf("ENV_VAR = %s\n", ENV_VAR);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ int main(int argc, char **argv)
|
|||||||
group_t *root_group = getgrgid(0);
|
group_t *root_group = getgrgid(0);
|
||||||
if (strcmp(root_group->gr_name, "root") != 0) {
|
if (strcmp(root_group->gr_name, "root") != 0) {
|
||||||
printf("Error in getgrgid function.");
|
printf("Error in getgrgid function.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
root_group = getgrnam("root");
|
root_group = getgrnam("root");
|
||||||
if (root_group->gr_gid != 0) {
|
if (root_group->gr_gid != 0) {
|
||||||
printf("Error in getgrnam function.");
|
printf("Error in getgrnam function.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,12 @@ int main(int argc, char **argv)
|
|||||||
printf("%d) pid_child: %d, gid_child: %d, ppid_child: %d, sid_child: %d\n",
|
printf("%d) pid_child: %d, gid_child: %d, ppid_child: %d, sid_child: %d\n",
|
||||||
i, pid_child, gid_child, ppid_child, sid_child);
|
i, pid_child, gid_child, ppid_child, sid_child);
|
||||||
sleep(5);
|
sleep(5);
|
||||||
exit(0);
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//int status;
|
//int status;
|
||||||
//while (wait(&status) > 0)
|
//while (wait(&status) > 0)
|
||||||
// ;
|
// ;
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = alarm_handler;
|
action.sa_handler = alarm_handler;
|
||||||
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
itimerval interval = { 0 };
|
itimerval interval = { 0 };
|
||||||
@@ -57,5 +57,5 @@ int main(int argc, char *argv[])
|
|||||||
setitimer(ITIMER_REAL, &interval, NULL);
|
setitimer(ITIMER_REAL, &interval, NULL);
|
||||||
|
|
||||||
while(1) { }
|
while(1) { }
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = child_sigusr1_handler;
|
action.sa_handler = child_sigusr1_handler;
|
||||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
child_process();
|
child_process();
|
||||||
} else {
|
} else {
|
||||||
@@ -61,5 +61,5 @@ int main(int argc, char *argv[])
|
|||||||
int status;
|
int status;
|
||||||
wait(&status);
|
wait(&status);
|
||||||
printf("main : end (%d)\n", status);
|
printf("main : end (%d)\n", status);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
printf("%s: You must provide 2 dimensions.\n", argv[0]);
|
printf("%s: You must provide 2 dimensions.\n", argv[0]);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int rows = strtol(argv[1], &ptr, 10);
|
int rows = strtol(argv[1], &ptr, 10);
|
||||||
@@ -48,5 +48,5 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
sleep(5);
|
sleep(5);
|
||||||
pr_warning("Exiting!\n");
|
pr_warning("Exiting!\n");
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
|
|||||||
key = ftok("/home/user/test7.txt", 5);
|
key = ftok("/home/user/test7.txt", 5);
|
||||||
if (key < 0) {
|
if (key < 0) {
|
||||||
perror("Failed to generate key using ftok");
|
perror("Failed to generate key using ftok");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("Generated key using ftok (key = %d)\n", key);
|
printf("Generated key using ftok (key = %d)\n", key);
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
|
|||||||
msqid = msgget(key, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
msqid = msgget(key, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
if (msqid < 0) {
|
if (msqid < 0) {
|
||||||
perror("Failed to create message queue");
|
perror("Failed to create message queue");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("Created message queue (id : %d)\n", msqid);
|
printf("Created message queue (id : %d)\n", msqid);
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
|
|||||||
sleep(3);
|
sleep(3);
|
||||||
// Send the message.
|
// Send the message.
|
||||||
__send_message(msqid, 1, &message, "General Kenobi...");
|
__send_message(msqid, 1, &message, "General Kenobi...");
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
// Receive the message.
|
// Receive the message.
|
||||||
__receive_message(msqid, 1, &message);
|
__receive_message(msqid, 1, &message);
|
||||||
@@ -106,5 +106,5 @@ int main(int argc, char *argv[])
|
|||||||
perror("Failed to remove message queue.");
|
perror("Failed to remove message queue.");
|
||||||
}
|
}
|
||||||
printf("Correctly removed message queue.\n");
|
printf("Correctly removed message queue.\n");
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <strerror.h>
|
#include <strerror.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -42,5 +43,5 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <strerror.h>
|
#include <strerror.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -30,5 +31,5 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||||
/// See LICENSE.md for details.
|
/// See LICENSE.md for details.
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <strerror.h>
|
#include <strerror.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -30,5 +31,5 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@@ -14,9 +15,9 @@ int main(int argc, char *argv[])
|
|||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
if ((cpid = fork()) == 0) {
|
if ((cpid = fork()) == 0) {
|
||||||
execl("/bin/tests/t_alarm", "t_alarm", NULL);
|
execl("/bin/tests/t_alarm", "t_alarm", NULL);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (wait(NULL) != -1) continue;
|
while (wait(NULL) != -1) continue;
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ int main(int argc, char *argv[])
|
|||||||
semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
if (semid < 0) {
|
if (semid < 0) {
|
||||||
perror("Failed to create semaphore set");
|
perror("Failed to create semaphore set");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Created semaphore set (semid : %d)\n", semid);
|
printf("[father] Created semaphore set (semid : %d)\n", semid);
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, SETVAL, &arg);
|
ret = semctl(semid, 0, SETVAL, &arg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to set value of semaphore");
|
perror("Failed to set value of semaphore");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Set semaphore value (id : %d, value : %d == 1)\n", semid, arg.val);
|
printf("[father] Set semaphore value (id : %d, value : %d == 1)\n", semid, arg.val);
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set");
|
perror("Failed to get the value of semaphore set");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
|
|||||||
// Increment semaphore value.
|
// Increment semaphore value.
|
||||||
if (semop(semid, &op_child, 1) < 0) {
|
if (semop(semid, &op_child, 1) < 0) {
|
||||||
perror("Failed to perform first child operation");
|
perror("Failed to perform first child operation");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set");
|
perror("Failed to get the value of semaphore set");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
printf("[child] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
||||||
printf("[child] Exit, now.\n", semid, ret);
|
printf("[child] Exit, now.\n", semid, ret);
|
||||||
@@ -87,14 +87,14 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
printf("[child] Correctly removed semaphore set.\n");
|
printf("[child] Correctly removed semaphore set.\n");
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// Perform the operations.
|
// Perform the operations.
|
||||||
if (semop(semid, op, 2) < 0) {
|
if (semop(semid, op, 2) < 0) {
|
||||||
perror("Failed to perform operation");
|
perror("Failed to perform operation");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Performed semaphore operations (id : %d)\n", semid);
|
printf("[father] Performed semaphore operations (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set");
|
perror("Failed to get the value of semaphore set");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
||||||
|
|
||||||
@@ -115,5 +115,5 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
printf("[father] Correctly removed semaphore set.\n");
|
printf("[father] Correctly removed semaphore set.\n");
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -26,7 +26,7 @@ int main(int argc, char *argv[])
|
|||||||
key = ftok("/home/user/test7.txt", 5);
|
key = ftok("/home/user/test7.txt", 5);
|
||||||
if (key < 0) {
|
if (key < 0) {
|
||||||
perror("Failed to generate key using ftok.");
|
perror("Failed to generate key using ftok.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("Generated key using ftok (key = %d)\n", key);
|
printf("Generated key using ftok (key = %d)\n", key);
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
|
|||||||
semid = semget(key, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
semid = semget(key, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
if (semid < 0) {
|
if (semid < 0) {
|
||||||
perror("Failed to create semaphore set.");
|
perror("Failed to create semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Created semaphore set (id : %d)\n", semid);
|
printf("[father] Created semaphore set (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, SETVAL, &arg);
|
ret = semctl(semid, 0, SETVAL, &arg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to set value of semaphore.");
|
perror("Failed to set value of semaphore.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Set semaphore value (id : %d, value : %d == 1)\n", semid, arg.val);
|
printf("[father] Set semaphore value (id : %d, value : %d == 1)\n", semid, arg.val);
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set.");
|
perror("Failed to get the value of semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
printf("[father] Get semaphore value (id : %d, value : %d == 1)\n", semid, ret);
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ int main(int argc, char *argv[])
|
|||||||
sleep(3);
|
sleep(3);
|
||||||
if (semop(semid, &op_child, 1) < 0) {
|
if (semop(semid, &op_child, 1) < 0) {
|
||||||
perror("Failed to perform first child operation.");
|
perror("Failed to perform first child operation.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set.");
|
perror("Failed to get the value of semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
printf("[child] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
|
|||||||
sleep(3);
|
sleep(3);
|
||||||
if (semop(semid, &op_child, 1) < 0) {
|
if (semop(semid, &op_child, 1) < 0) {
|
||||||
perror("Failed to perform second child operation.");
|
perror("Failed to perform second child operation.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
printf("[child] Succesfully performed opeation (id : %d)\n", semid);
|
||||||
|
|
||||||
@@ -95,14 +95,14 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set.");
|
perror("Failed to get the value of semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[child] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
printf("[child] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
||||||
|
|
||||||
printf("[child] Exit, now.\n", semid, ret);
|
printf("[child] Exit, now.\n", semid, ret);
|
||||||
|
|
||||||
// Exit with the child process.
|
// Exit with the child process.
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
@@ -121,7 +121,7 @@ int main(int argc, char *argv[])
|
|||||||
// Perform the operations.
|
// Perform the operations.
|
||||||
if (semop(semid, op_father, 3) < 0) {
|
if (semop(semid, op_father, 3) < 0) {
|
||||||
perror("Failed to perform father operation.");
|
perror("Failed to perform father operation.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(2);
|
sleep(2);
|
||||||
@@ -132,7 +132,7 @@ int main(int argc, char *argv[])
|
|||||||
ret = semctl(semid, 0, GETVAL, NULL);
|
ret = semctl(semid, 0, GETVAL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
perror("Failed to get the value of semaphore set.");
|
perror("Failed to get the value of semaphore set.");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
printf("[father] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
printf("[father] Get semaphore value (id : %d, value : %d == 0)\n", semid, ret);
|
||||||
|
|
||||||
@@ -143,5 +143,5 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
printf("[father] Correctly removed semaphore set.\n");
|
printf("[father] Correctly removed semaphore set.\n");
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (semctl(semid, 0, SETALL, &arg) == -1) {
|
if (semctl(semid, 0, SETALL, &arg) == -1) {
|
||||||
perror("Failed to set semaphores");
|
perror("Failed to set semaphores");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fork()) {
|
if (!fork()) {
|
||||||
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (semctl(semid, 0, IPC_RMID, 0) == -1) {
|
if (semctl(semid, 0, IPC_RMID, 0) == -1) {
|
||||||
perror("Failed to remove IPC");
|
perror("Failed to remove IPC");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
||||||
printf("Failed to set env: `PWD`\n");
|
printf("Failed to set env: `PWD`\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fork() == 0) {
|
if (fork() == 0) {
|
||||||
@@ -24,5 +24,5 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
wait(&status);
|
wait(&status);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = sigusr1_handler;
|
action.sa_handler = sigusr1_handler;
|
||||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("main : Calling handler (%d).\n", SIGUSR1);
|
printf("main : Calling handler (%d).\n", SIGUSR1);
|
||||||
@@ -41,8 +41,9 @@ int main(int argc, char *argv[])
|
|||||||
int ret = kill(getpid(), SIGUSR1);
|
int ret = kill(getpid(), SIGUSR1);
|
||||||
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
||||||
printf("main : value : %d\n", values);
|
printf("main : value : %d\n", values);
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i) {
|
||||||
printf("values[%d] : `%d`\n", i, values[i]);
|
printf("values[%d] : `%d`\n", i, values[i]);
|
||||||
|
}
|
||||||
free(values);
|
free(values);
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Diving by zero (unrecoverable)...\n");
|
printf("Diving by zero (unrecoverable)...\n");
|
||||||
@@ -57,4 +57,5 @@ int main(int argc, char *argv[])
|
|||||||
d /= e;
|
d /= e;
|
||||||
e -= 1;
|
e -= 1;
|
||||||
printf("d: %d, e: %d\n", d, e);
|
printf("d: %d, e: %d\n", d, e);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Diving by zero (unrecoverable)...\n");
|
printf("Diving by zero (unrecoverable)...\n");
|
||||||
@@ -48,4 +48,5 @@ int main(int argc, char *argv[])
|
|||||||
e -= 1;
|
e -= 1;
|
||||||
}
|
}
|
||||||
printf("d: %d, e: %d\n", d, e);
|
printf("d: %d, e: %d\n", d, e);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = sigusr1_handler;
|
action.sa_handler = sigusr1_handler;
|
||||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%d, %s).\n", SIGUSR1, strerror(errno));
|
printf("Failed to set signal handler (%d, %s).\n", SIGUSR1, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("main : Blocking signal (%d).\n", SIGUSR1);
|
printf("main : Blocking signal (%d).\n", SIGUSR1);
|
||||||
@@ -45,5 +45,5 @@ int main(int argc, char *argv[])
|
|||||||
ret = kill(getpid(), SIGUSR1);
|
ret = kill(getpid(), SIGUSR1);
|
||||||
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sigaction(SIGUSR2, &action, NULL) == -1) {
|
if (sigaction(SIGUSR2, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler (%s).\n", SIGUSR2, strerror(errno));
|
printf("Failed to set signal handler (%s).\n", SIGUSR2, strerror(errno));
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
kill(getpid(), SIGUSR1);
|
kill(getpid(), SIGUSR1);
|
||||||
@@ -51,5 +51,6 @@ int main(int argc, char *argv[])
|
|||||||
kill(getpid(), SIGUSR2);
|
kill(getpid(), SIGUSR2);
|
||||||
|
|
||||||
while(1) { };
|
while(1) { };
|
||||||
return 0;
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ int main(int argc, char *argv[])
|
|||||||
sleep(4);
|
sleep(4);
|
||||||
printf("COMPLETED.\n");
|
printf("COMPLETED.\n");
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ int main(int argc, char *argv[])
|
|||||||
action.sa_handler = wait_for_child;
|
action.sa_handler = wait_for_child;
|
||||||
if (sigaction(SIGCHLD, &action, NULL) == -1) {
|
if (sigaction(SIGCHLD, &action, NULL) == -1) {
|
||||||
printf("Failed to set signal handler. %d\n", SIGCHLD);
|
printf("Failed to set signal handler. %d\n", SIGCHLD);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
child_pid = fork();
|
child_pid = fork();
|
||||||
@@ -55,5 +55,5 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user