Merge branch 'develop' into feature/remove_nasm
This commit is contained in:
@@ -1,39 +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
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install x86_64-elf-gcc nasm
|
||||
- name: Build
|
||||
run: |
|
||||
cmake \
|
||||
-DCMAKE_C_COMPILER=x86_64-elf-gcc \
|
||||
-DCMAKE_AR=x86_64-elf-gas \
|
||||
-DCMAKE_LINKER=x86_64-elf-ld \
|
||||
-DCMAKE_OBJCOPY=x86_64-elf-objcopy \
|
||||
-DCMAKE_OBJDUMP=x86_64-elf-objdump \
|
||||
-DCMAKE_RANLIB=x86_64-elf-ranlib \
|
||||
-DCMAKE_ASM_COMPILER=/usr/local/bin/nasm \
|
||||
-DCMAKE_SYSTEM_NAME=Linux \
|
||||
-B build
|
||||
cmake --build build --parallel 2 --verbose
|
||||
@@ -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
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"string.h": "c",
|
||||
"debug.h": "c"
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -30,7 +30,7 @@ message(STATUS "System name : ${CMAKE_HOST_SYSTEM_NAME}")
|
||||
message(STATUS "Kernel version : ${CMAKE_SYSTEM_VERSION}")
|
||||
if((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") OR APPLE)
|
||||
# Specify the linker flags.
|
||||
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib")
|
||||
elseif((${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") OR WIN32)
|
||||
# Windows set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
|
||||
else()
|
||||
@@ -58,7 +58,7 @@ else()
|
||||
# set(EMULATOR_FLAGS ${EMULATOR_FLAGS} -sdl)
|
||||
endif()
|
||||
# Speicfy the linker.
|
||||
# set(CMAKE_LINKER ld)
|
||||
set(CMAKE_LINKER ld)
|
||||
endif()
|
||||
|
||||
# Enable the assembly language.
|
||||
@@ -97,6 +97,7 @@ 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()
|
||||
@@ -201,7 +202,8 @@ add_custom_target(
|
||||
COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/get_text_address.sh ${CMAKE_BINARY_DIR}/programs/prog_* >> ${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 "target remote localhost:1234" >> ${CMAKE_BINARY_DIR}/.gdbinit
|
||||
# Create the GDB connection file.
|
||||
COMMAND echo "target remote localhost:1234" > ${CMAKE_BINARY_DIR}/gdb.run
|
||||
DEPENDS ${CMAKE_BINARY_DIR}/mentos/kernel_bootloader.bin
|
||||
DEPENDS ${CMAKE_BINARY_DIR}/mentos/kernel.bin
|
||||
DEPENDS all_programs
|
||||
|
||||
@@ -5,24 +5,29 @@
|
||||
[](https://forthebadge.com)
|
||||
|
||||
[](https://github.com/mentos-team/MentOS/actions/workflows/ubuntu.yml)
|
||||
[](https://github.com/mentos-team/MentOS/actions/workflows/macos.yml)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [What is MentOS](#1-what-is-mentos)
|
||||
2. [Implemented features](#2-implemented-features)
|
||||
3. [Prerequisites](#3-prerequisites)
|
||||
4. [Compiling MentOS](#4-compiling-mentos)
|
||||
5. [Generating the EXT2 filesystem](#5-generating-the-ext2-filesystem)
|
||||
6. [Running MentOS](#6-running-mentos)
|
||||
7. [Running MentOS from GRUB](#7-running-mentos-from-grub)
|
||||
8. [Running and adding new programs to MentOS](#8-running-and-adding-new-programs-to-mentos)
|
||||
9. [Kernel logging](#9-kernel-logging)
|
||||
10. [Change the scheduling algorithm](#10-change-the-scheduling-algorithm)
|
||||
11. [Debugging the kernel](#11-debugging-the-kernel)
|
||||
12. [Contributors](#12-contributors)
|
||||
- [MentOS (Mentoring Operating System)](#mentos-mentoring-operating-system)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [What is MentOS](#what-is-mentos)
|
||||
- [Implemented features](#implemented-features)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Installing the prerequisites](#installing-the-prerequisites)
|
||||
- [Compiling MentOS](#compiling-mentos)
|
||||
- [Generating the EXT2 filesystem](#generating-the-ext2-filesystem)
|
||||
- [Running MentOS](#running-mentos)
|
||||
- [Running MentOS from GRUB](#running-mentos-from-grub)
|
||||
- [Running and adding new programs to MentOS](#running-and-adding-new-programs-to-mentos)
|
||||
- [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
|
||||
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)*
|
||||
|
||||
## 2. Implemented features
|
||||
## Implemented features
|
||||
|
||||
Follows the list of implemented features:
|
||||
|
||||
**Processes and Events**
|
||||
@@ -91,22 +97,18 @@ I will try to keep it updated...
|
||||
|
||||
*[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
|
||||
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
|
||||
|
||||
For compiling the system:
|
||||
|
||||
- nasm
|
||||
- git
|
||||
- gcc
|
||||
- nasm
|
||||
- make
|
||||
- cmake
|
||||
- git
|
||||
- ccmake (suggested)
|
||||
- e2fsprogs (should be already installed)
|
||||
|
||||
@@ -115,43 +117,29 @@ Under **MacOS**, for compiling, you have additional dependencies:
|
||||
- i386-elf-binutils
|
||||
- i386-elf-gcc
|
||||
|
||||
#### 3.1.2. Execute
|
||||
|
||||
To execute the operating system, you need to install:
|
||||
For **executing** the operating system we need:
|
||||
|
||||
- qemu-system-i386 (or qemu-system-x86)
|
||||
|
||||
#### 3.1.3. Debug
|
||||
|
||||
For debugging we suggest using:
|
||||
For **debugging** we suggest using:
|
||||
|
||||
- gdb or cgdb
|
||||
|
||||
### 3.2. installation Prerequisites
|
||||
### Installing the prerequisites
|
||||
|
||||
Under **Ubuntu**, you can type the following commands:
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
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) 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)*
|
||||
|
||||
## 4. Compiling MentOS
|
||||
## Compiling MentOS
|
||||
|
||||
Compile MentOS with:
|
||||
|
||||
@@ -165,7 +153,7 @@ make
|
||||
|
||||
*[Back to the Table of Contents](#table-of-contents)*
|
||||
|
||||
## 5. Generating the EXT2 filesystem
|
||||
## Generating the EXT2 filesystem
|
||||
|
||||
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)*
|
||||
|
||||
## 6. Running MentOS
|
||||
## Running MentOS
|
||||
|
||||
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)*
|
||||
|
||||
## 7. Running MentOS from GRUB
|
||||
## Running MentOS from GRUB
|
||||
|
||||
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)*
|
||||
|
||||
## 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.
|
||||
|
||||
### 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:
|
||||
```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.
|
||||
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.
|
||||
|
||||
### 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:
|
||||
```bash
|
||||
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)*
|
||||
|
||||
## 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`.
|
||||
|
||||
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)*
|
||||
|
||||
## 10. Change the scheduling algorithm
|
||||
## Change the scheduling algorithm
|
||||
|
||||
MentOS supports scheduling algorithms for aperiodic:
|
||||
|
||||
@@ -390,7 +378,7 @@ make qemu
|
||||
|
||||
*[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:
|
||||
|
||||
@@ -450,7 +438,7 @@ to connect to the running process.
|
||||
|
||||
*[Back to the Table of Contents](#table-of-contents)*
|
||||
|
||||
## 12. Contributors
|
||||
## Contributors
|
||||
|
||||
Project Manager:
|
||||
|
||||
@@ -472,5 +460,9 @@ Developers:
|
||||
- Soft IRQs
|
||||
- Timer
|
||||
- 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)*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// @file waitpid.c
|
||||
/// @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.
|
||||
|
||||
#include "sys/unistd.h"
|
||||
@@ -18,19 +18,17 @@ pid_t waitpid(pid_t pid, int *status, int options)
|
||||
int __status = 0;
|
||||
do {
|
||||
__inline_syscall3(__res, waitpid, pid, &__status, options);
|
||||
if (__res < 0) {
|
||||
if (__res != 0) {
|
||||
break;
|
||||
}
|
||||
if (__status == EXIT_ZOMBIE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (options && WNOHANG) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (1);
|
||||
|
||||
if (status) {
|
||||
*status = __status;
|
||||
}
|
||||
}
|
||||
__syscall_return(pid_t, __res);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ option(USE_BUDDY_SYSTEM "Build using the buddysystem written by the user." OFF)
|
||||
option(ENABLE_CACHE_TRACE "Enables cache tracing." OFF)
|
||||
# Enables memory allocation tracing.
|
||||
option(ENABLE_ALLOC_TRACE "Enables memory allocation tracing." OFF)
|
||||
# Enables scheduling feedback on terminal.
|
||||
option(ENABLE_SCHEDULER_FEEDBACK "Enables scheduling feedback on terminal." OFF)
|
||||
|
||||
# =============================================================================
|
||||
# SOURCES
|
||||
|
||||
+5
-13
@@ -9,45 +9,37 @@ MEMORY {
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00100000;
|
||||
_bootloader_start = .;
|
||||
|
||||
_bootloader_start = .;
|
||||
|
||||
.multiboot . : AT(ADDR(.multiboot))
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_multiboot_header_start = .;
|
||||
*(.multiboot_header)
|
||||
_multiboot_header_end = .;
|
||||
} > BOOTLOADER_MEM
|
||||
|
||||
/* Put the .text section. */
|
||||
.text . : AT(ADDR(.text))
|
||||
{
|
||||
_text_start = .;
|
||||
*(.text)
|
||||
_text_end = .;
|
||||
} > BOOTLOADER_MEM
|
||||
|
||||
/* Read-only data. */
|
||||
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
||||
{
|
||||
_rodata_start = .;
|
||||
*(.rodata)
|
||||
_rodata_end = .;
|
||||
} > BOOTLOADER_MEM
|
||||
|
||||
/* Read-write data (initialized) */
|
||||
.data ALIGN(4K) : AT(ADDR(.data))
|
||||
.data ALIGN(4K) : AT(ADDR(.data))
|
||||
{
|
||||
_data_start = .;
|
||||
*(.data)
|
||||
_data_end = .;
|
||||
} > BOOTLOADER_MEM
|
||||
|
||||
/* Read-write data (uninitialized) and stack */
|
||||
.bss ALIGN(4K) : AT(ADDR(.bss))
|
||||
.bss ALIGN(4K) : AT(ADDR(.bss))
|
||||
{
|
||||
_bss_start = .;
|
||||
*(.bss*)
|
||||
_bss_end = .;
|
||||
} > BOOTLOADER_MEM
|
||||
|
||||
/* 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
|
||||
/// @return 1 if the group is orphan, 0 otherwise.
|
||||
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. */
|
||||
.text . : AT(ADDR(.text))
|
||||
{
|
||||
_text_start = .;
|
||||
EXCLUDE_FILE(*boot.*.o) *(.text)
|
||||
_text_end = .;
|
||||
} > KERNEL_LOWMEM
|
||||
|
||||
/* Read-only data. */
|
||||
.rodata ALIGN(4K) : AT(ADDR(.rodata))
|
||||
{
|
||||
_rodata_start = .;
|
||||
EXCLUDE_FILE(*boot.*.o) *(.rodata)
|
||||
_rodata_end = .;
|
||||
} > KERNEL_LOWMEM
|
||||
|
||||
/* Read-write data (initialized) */
|
||||
.data ALIGN(4K) : AT(ADDR(.data))
|
||||
{
|
||||
_data_start = .;
|
||||
EXCLUDE_FILE(*boot.*.o) *(.data)
|
||||
_data_end = .;
|
||||
} > KERNEL_LOWMEM
|
||||
|
||||
/* Read-write data (uninitialized) and stack */
|
||||
.bss ALIGN(4K) : AT(ADDR(.bss))
|
||||
{
|
||||
_bss_start = .;
|
||||
*(.bss*)
|
||||
_bss_end = .;
|
||||
} > KERNEL_LOWMEM
|
||||
|
||||
/* 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
|
||||
+16
-3
@@ -32,6 +32,19 @@
|
||||
# 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)
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -40,11 +53,11 @@
|
||||
# This is the GRUB Multiboot header.
|
||||
multiboot_header:
|
||||
# magic
|
||||
.quad MULTIBOOT_HEADER_MAGIC
|
||||
.long MULTIBOOT_HEADER_MAGIC
|
||||
# flags
|
||||
.quad MULTIBOOT_HEADER_FLAGS
|
||||
.long MULTIBOOT_HEADER_FLAGS
|
||||
# checksum
|
||||
.quad MULTIBOOT_CHECKSUM
|
||||
.long MULTIBOOT_CHECKSUM
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# SECTION (data)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,28 +1,26 @@
|
||||
; 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.
|
||||
# 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
|
||||
.extern irq_handler
|
||||
|
||||
%macro IRQ 2
|
||||
global IRQ_%1
|
||||
IRQ_%1:
|
||||
cli ; disable interrupt line
|
||||
; A normal ISR stub that pops a dummy error code to keep a
|
||||
; uniform stack frame
|
||||
push 0
|
||||
push %2 ; irq number
|
||||
.macro IRQ ARG1, ARG2
|
||||
.globl IRQ_&ARG1
|
||||
IRQ_&ARG1:
|
||||
cli # disable interrupt line
|
||||
push $0
|
||||
push &ARG2
|
||||
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 1, 33
|
||||
IRQ 2, 34
|
||||
@@ -40,52 +38,52 @@ 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
|
||||
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
|
||||
# Save registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||
pusha
|
||||
|
||||
; Save segment registers
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
;---------------------------------------------------------------------------
|
||||
# Save segment registers
|
||||
push %ds
|
||||
push %es
|
||||
push %fs
|
||||
push %gs
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
;==== ensure we are using kernel data segment ==============================
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
# ==== 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 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 esp, $4 ; remove esp from stack
|
||||
;---------------------------------------------------------------------------
|
||||
add $0x04, %esp # remove esp from stack
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
;==== Restore registers ====================================================
|
||||
; restore segment registers
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
# ==== Restore registers ====================================================
|
||||
# restore segment registers
|
||||
pop %gs
|
||||
pop %fs
|
||||
pop %es
|
||||
pop %ds
|
||||
|
||||
; restore registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||
# restore registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
|
||||
popa
|
||||
;---------------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
; Cleanup error code and IRQ #
|
||||
add esp, $8
|
||||
# Cleanup error code and IRQ #
|
||||
add $0x08, %esp
|
||||
|
||||
; return to process
|
||||
iret ; pops 5 things at once:
|
||||
; CS, EIP, EFLAGS, SS, and 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
|
||||
@@ -6,7 +6,7 @@
|
||||
// Setup the logging for this file (do this before any other include).
|
||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||
#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 "assert.h"
|
||||
|
||||
+23
-45
@@ -43,28 +43,6 @@ char *module_start[MAX_MODULES];
|
||||
/// Describe end address of grub multiboot 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.
|
||||
extern uint32_t stack_top;
|
||||
/// Points at the bottom of the kernel stack.
|
||||
@@ -107,8 +85,8 @@ int kmain(boot_info_t *boot_informations)
|
||||
boot_info = *boot_informations;
|
||||
// Am I booted by a Multiboot-compliant boot loader?
|
||||
if (boot_info.magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||
printf("Invalid magic number: 0x%x\n", boot_info.magic);
|
||||
return 1;
|
||||
pr_emerg("Invalid magic number: 0x%x\n", boot_info.magic);
|
||||
while (1) {}
|
||||
}
|
||||
// Set the initial esp.
|
||||
initial_esp = boot_info.stack_base;
|
||||
@@ -131,7 +109,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Initialize modules...");
|
||||
if (!init_modules(boot_info.multiboot_header)) {
|
||||
print_fail();
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -140,7 +118,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Initialize physical memory manager...");
|
||||
if (!pmmngr_init(&boot_info)) {
|
||||
print_fail();
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -216,7 +194,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Initialize ATA devices...");
|
||||
if (ata_initialize()) {
|
||||
pr_emerg("Failed to initialize ATA devices!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -225,7 +203,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Initialize EXT2 filesystem...");
|
||||
if (ext2_initialize()) {
|
||||
pr_emerg("Failed to initialize EXT2 filesystem!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -234,7 +212,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Mount EXT2 filesystem...");
|
||||
if (do_mount("ext2", "/", "/dev/hda")) {
|
||||
pr_emerg("Failed to mount EXT2 filesystem...\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -244,7 +222,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
if (procfs_module_init()) {
|
||||
print_fail();
|
||||
pr_emerg("Failed to register `procfs`!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -253,7 +231,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf(" Mounting 'procfs'...");
|
||||
if (do_mount("procfs", "/proc", NULL)) {
|
||||
pr_emerg("Failed to mount procfs at `/proc`!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -263,7 +241,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
if (procv_module_init()) {
|
||||
print_fail();
|
||||
pr_emerg("Failed to initialize `/proc/video`!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -273,7 +251,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
if (procs_module_init()) {
|
||||
print_fail();
|
||||
pr_emerg("Failed to initialize proc system entries!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -283,7 +261,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
if (procipc_module_init()) {
|
||||
print_fail();
|
||||
pr_emerg("Failed to initialize the IPC information system!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -293,7 +271,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
if (sem_init()) {
|
||||
print_fail();
|
||||
pr_emerg("Failed to initialize the IPC/SEM system!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -303,7 +281,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
if (msq_init()) {
|
||||
print_fail();
|
||||
pr_emerg("Failed to initialize the IPC/MSQ system!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -313,7 +291,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
if (shm_init()) {
|
||||
print_fail();
|
||||
pr_emerg("Failed to initialize the IPC/SHM system!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -328,7 +306,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
if (ps2_initialize()) {
|
||||
print_fail();
|
||||
pr_emerg("Failed to initialize proc system entries!\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -365,7 +343,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Init process management...");
|
||||
if (!init_tasking()) {
|
||||
print_fail();
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -375,7 +353,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Initialize scheduler feedback system...");
|
||||
if (!scheduler_feedback_init()) {
|
||||
print_fail();
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
#endif
|
||||
@@ -385,7 +363,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Initialize scheduler feedback system (2)...");
|
||||
if (procfb_module_init()) {
|
||||
print_fail();
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -395,7 +373,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
task_struct *init_p = process_create_init("/bin/init");
|
||||
if (!init_p) {
|
||||
print_fail();
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -404,7 +382,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Initialize floating point unit...");
|
||||
if (!fpu_install()) {
|
||||
print_fail();
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -413,7 +391,7 @@ int kmain(boot_info_t *boot_informations)
|
||||
printf("Initialize signals...");
|
||||
if (!signals_init()) {
|
||||
print_fail();
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
print_ok();
|
||||
|
||||
@@ -432,5 +410,5 @@ int kmain(boot_info_t *boot_informations)
|
||||
for (;;) {}
|
||||
// We should not be here.
|
||||
pr_emerg("Dear developer, we have to talk...\n");
|
||||
return 1;
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
/// See LICENSE.md for details.
|
||||
|
||||
// Setup the logging for this file (do this before any other include).
|
||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||
#define __DEBUG_HEADER__ "[PROC ]" ///< Change header.
|
||||
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE ///< Set log level.
|
||||
#include "io/debug.h" // Include debugging functions.
|
||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||
#define __DEBUG_HEADER__ "[PROC ]" ///< Change header.
|
||||
#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG ///< Set log level.
|
||||
#include "io/debug.h" // Include debugging functions.
|
||||
|
||||
#include "assert.h"
|
||||
#include "elf/elf.h"
|
||||
@@ -91,11 +91,15 @@ static int __reset_process(task_struct *task)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_debug("Switching to task page directory.\n");
|
||||
|
||||
// Save the current page 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.
|
||||
paging_switch_directory_va(task->mm->pgd);
|
||||
|
||||
pr_debug("Clean stack (%p).\n", task->mm->start_stack);
|
||||
|
||||
// Clean stack space.
|
||||
memset((char *)task->mm->start_stack, 0, DEFAULT_STACK_SIZE);
|
||||
// Set the base address of the stack.
|
||||
@@ -105,6 +109,8 @@ static int __reset_process(task_struct *task)
|
||||
// Enable the interrupts.
|
||||
task->thread.regs.eflags = task->thread.regs.eflags | EFLAG_IF;
|
||||
|
||||
pr_debug("Switching to previous page directory.\n");
|
||||
|
||||
// Restore previous pgdir
|
||||
paging_switch_directory(crtdir);
|
||||
|
||||
|
||||
@@ -517,7 +517,7 @@ pid_t sys_waitpid(pid_t pid, int *status, int options)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_exit(int exit_code)
|
||||
void do_exit(int exit_code)
|
||||
{
|
||||
// Get the current task.
|
||||
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);
|
||||
}
|
||||
|
||||
void sys_exit(int exit_code)
|
||||
{
|
||||
do_exit(exit_code << 8);
|
||||
}
|
||||
|
||||
int sys_sched_setparam(pid_t pid, const sched_param_t *param)
|
||||
{
|
||||
list_head *it;
|
||||
|
||||
@@ -1,78 +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 |
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; 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, [ebp + 0x0C] ; 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, [ebp + 0x08] ; 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;
|
||||
case SIGQUIT:
|
||||
sys_exit(GET_EXIT_STATUS(1));
|
||||
do_exit(GET_EXIT_STATUS(1));
|
||||
continue;
|
||||
case SIGILL:
|
||||
sys_exit(GET_EXIT_STATUS(132));
|
||||
do_exit(GET_EXIT_STATUS(132));
|
||||
continue;
|
||||
case SIGTRAP:
|
||||
sys_exit(GET_EXIT_STATUS(133));
|
||||
do_exit(GET_EXIT_STATUS(133));
|
||||
continue;
|
||||
case SIGABRT:
|
||||
sys_exit(GET_EXIT_STATUS(134));
|
||||
do_exit(GET_EXIT_STATUS(134));
|
||||
continue;
|
||||
case SIGFPE:
|
||||
sys_exit(GET_EXIT_STATUS(136) | signr);
|
||||
do_exit(GET_EXIT_STATUS(136) | signr);
|
||||
__unlock_task_sighand(current_process);
|
||||
return 1;
|
||||
case SIGBUS:
|
||||
sys_exit(GET_EXIT_STATUS(138) | signr);
|
||||
do_exit(GET_EXIT_STATUS(138) | signr);
|
||||
__unlock_task_sighand(current_process);
|
||||
return 1;
|
||||
case SIGSEGV:
|
||||
sys_exit(GET_EXIT_STATUS(139) | signr);
|
||||
do_exit(GET_EXIT_STATUS(139) | signr);
|
||||
__unlock_task_sighand(current_process);
|
||||
return 1;
|
||||
case SIGXCPU:
|
||||
sys_exit(GET_EXIT_STATUS(158) | signr);
|
||||
do_exit(GET_EXIT_STATUS(158) | signr);
|
||||
__unlock_task_sighand(current_process);
|
||||
case SIGXFSZ:
|
||||
sys_exit(GET_EXIT_STATUS(159) | signr);
|
||||
do_exit(GET_EXIT_STATUS(159) | signr);
|
||||
__unlock_task_sighand(current_process);
|
||||
case SIGSYS:
|
||||
default:
|
||||
sys_exit(GET_EXIT_STATUS(exit_code) | signr);
|
||||
do_exit(GET_EXIT_STATUS(exit_code) | signr);
|
||||
__unlock_task_sighand(current_process);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,37 @@
|
||||
# =============================================================================
|
||||
# BUILD
|
||||
# =============================================================================
|
||||
# Add the executables (manually).
|
||||
set(PROGRAMS
|
||||
nice.c
|
||||
ls.c
|
||||
mkdir.c
|
||||
ipcrm.c
|
||||
login.c
|
||||
man.c
|
||||
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.
|
||||
@@ -56,6 +87,23 @@ foreach(FILE_NAME ${PROGRAMS})
|
||||
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
|
||||
# =========================================================================
|
||||
@@ -76,6 +124,16 @@ foreach(FILE_NAME ${PROGRAMS})
|
||||
# Set the output name.
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_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.
|
||||
list(APPEND ALL_EXECUTABLES ${TARGET_NAME})
|
||||
endforeach()
|
||||
|
||||
@@ -59,7 +59,7 @@ foreach(FILE_NAME ${TESTS})
|
||||
# EXECUTABLE
|
||||
# =========================================================================
|
||||
# Create the target.
|
||||
add_executable(${TARGET_NAME} ${FILE_NAME})
|
||||
add_executable(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/programs/tests/${FILE_NAME})
|
||||
# Add the dependency to libc.
|
||||
add_dependencies(${TARGET_NAME} libc)
|
||||
# Add the includes.
|
||||
|
||||
@@ -16,7 +16,6 @@ void sig_handler(int sig)
|
||||
{
|
||||
printf("handler(%d) : Starting handler.\n", sig);
|
||||
if (sig == SIGABRT) {
|
||||
|
||||
static int counter = 0;
|
||||
counter += 1;
|
||||
|
||||
@@ -38,8 +37,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (sigaction(SIGABRT, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGABRT, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
abort();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -39,12 +39,11 @@ int main(int argc, char *argv[])
|
||||
action.sa_handler = alarm_handler;
|
||||
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
alarm(5);
|
||||
while(1) { }
|
||||
while (1) {}
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ int main(int argc, char *argv[])
|
||||
int status;
|
||||
if (argc != 2) {
|
||||
__print_usage(argc, argv);
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (setenv("ENV_VAR", "pwd0", 0) == -1) {
|
||||
printf("Failed to set env: `ENV_VAR`\n");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char *file = "echo";
|
||||
@@ -54,11 +54,11 @@ int main(int argc, char *argv[])
|
||||
execvpe(file, exec_argv, exec_envp);
|
||||
} else {
|
||||
__print_usage(argc, argv);
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("Exec failed.\n");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
wait(&status);
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ int main(int argc, char *argv[])
|
||||
char *ENV_VAR = getenv("ENV_VAR");
|
||||
if (ENV_VAR == NULL) {
|
||||
printf("Failed to get env: `ENV_VAR`\n");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("ENV_VAR = %s\n", ENV_VAR);
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
char *ptr;
|
||||
int N;
|
||||
@@ -61,5 +61,5 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ int main(int argc, char *argv[])
|
||||
char *ENV_VAR = getenv("ENV_VAR");
|
||||
if (ENV_VAR == NULL) {
|
||||
printf("Failed to get env: `ENV_VAR`\n");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (strcmp(root_group->gr_name, "root") != 0) {
|
||||
printf("Error in getgrgid function.");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
root_group = getgrnam("root");
|
||||
if (root_group->gr_gid != 0) {
|
||||
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",
|
||||
i, pid_child, gid_child, ppid_child, sid_child);
|
||||
sleep(5);
|
||||
exit(0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
//int status;
|
||||
//while (wait(&status) > 0)
|
||||
// ;
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
|
||||
action.sa_handler = alarm_handler;
|
||||
if (sigaction(SIGALRM, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGALRM, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
itimerval interval = { 0 };
|
||||
@@ -57,5 +57,5 @@ int main(int argc, char *argv[])
|
||||
setitimer(ITIMER_REAL, &interval, NULL);
|
||||
|
||||
while(1) { }
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ int main(int argc, char *argv[])
|
||||
action.sa_handler = child_sigusr1_handler;
|
||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
child_process();
|
||||
} else {
|
||||
@@ -61,5 +61,5 @@ int main(int argc, char *argv[])
|
||||
int status;
|
||||
wait(&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) {
|
||||
printf("%s: You must provide 2 dimensions.\n", argv[0]);
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
char *ptr;
|
||||
int rows = strtol(argv[1], &ptr, 10);
|
||||
@@ -48,5 +48,5 @@ int main(int argc, char *argv[])
|
||||
|
||||
sleep(5);
|
||||
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);
|
||||
if (key < 0) {
|
||||
perror("Failed to generate key using ftok");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (msqid < 0) {
|
||||
perror("Failed to create message queue");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("Created message queue (id : %d)\n", msqid);
|
||||
|
||||
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
|
||||
sleep(3);
|
||||
// Send the message.
|
||||
__send_message(msqid, 1, &message, "General Kenobi...");
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
// Receive the message.
|
||||
__receive_message(msqid, 1, &message);
|
||||
@@ -106,5 +106,5 @@ int main(int argc, char *argv[])
|
||||
perror("Failed to remove message queue.");
|
||||
}
|
||||
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.
|
||||
/// See LICENSE.md for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <strerror.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -42,5 +43,5 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||
/// See LICENSE.md for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <strerror.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -30,5 +31,5 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||
/// See LICENSE.md for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <strerror.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -30,5 +31,5 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -14,9 +15,9 @@ int main(int argc, char *argv[])
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if ((cpid = fork()) == 0) {
|
||||
execl("/bin/tests/t_alarm", "t_alarm", NULL);
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (semid < 0) {
|
||||
perror("Failed to create semaphore set");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
|
||||
ret = semctl(semid, 0, GETVAL, NULL);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
|
||||
// Increment semaphore value.
|
||||
if (semop(semid, &op_child, 1) < 0) {
|
||||
perror("Failed to perform first child operation");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (ret < 0) {
|
||||
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] Exit, now.\n", semid, ret);
|
||||
@@ -87,14 +87,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
printf("[child] Correctly removed semaphore set.\n");
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Perform the operations.
|
||||
if (semop(semid, op, 2) < 0) {
|
||||
perror("Failed to perform operation");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
@@ -115,5 +115,5 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
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);
|
||||
if (key < 0) {
|
||||
perror("Failed to generate key using ftok.");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (semid < 0) {
|
||||
perror("Failed to create semaphore set.");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
@@ -55,7 +55,7 @@ int main(int argc, char *argv[])
|
||||
ret = semctl(semid, 0, GETVAL, NULL);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
@@ -71,7 +71,7 @@ int main(int argc, char *argv[])
|
||||
sleep(3);
|
||||
if (semop(semid, &op_child, 1) < 0) {
|
||||
perror("Failed to perform first child operation.");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
|
||||
sleep(3);
|
||||
if (semop(semid, &op_child, 1) < 0) {
|
||||
perror("Failed to perform second child operation.");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
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);
|
||||
if (ret < 0) {
|
||||
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] Exit, now.\n", semid, ret);
|
||||
|
||||
// Exit with the child process.
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
@@ -121,7 +121,7 @@ int main(int argc, char *argv[])
|
||||
// Perform the operations.
|
||||
if (semop(semid, op_father, 3) < 0) {
|
||||
perror("Failed to perform father operation.");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
sleep(2);
|
||||
@@ -132,7 +132,7 @@ int main(int argc, char *argv[])
|
||||
ret = semctl(semid, 0, GETVAL, NULL);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
@@ -143,5 +143,5 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
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) {
|
||||
perror("Failed to set semaphores");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!fork()) {
|
||||
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
if (semctl(semid, 0, IPC_RMID, 0) == -1) {
|
||||
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) {
|
||||
printf("Failed to set env: `PWD`\n");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (fork() == 0) {
|
||||
@@ -24,5 +24,5 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
wait(&status);
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ int main(int argc, char *argv[])
|
||||
action.sa_handler = sigusr1_handler;
|
||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("main : Calling handler (%d).\n", SIGUSR1);
|
||||
@@ -41,8 +41,9 @@ int main(int argc, char *argv[])
|
||||
int ret = kill(getpid(), SIGUSR1);
|
||||
printf("main : Returning from handler (%d): %d.\n", SIGUSR1, ret);
|
||||
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]);
|
||||
}
|
||||
free(values);
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (sigaction(SIGFPE, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Diving by zero (unrecoverable)...\n");
|
||||
@@ -57,4 +57,5 @@ int main(int argc, char *argv[])
|
||||
d /= e;
|
||||
e -= 1;
|
||||
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) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGFPE, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Diving by zero (unrecoverable)...\n");
|
||||
@@ -48,4 +48,5 @@ int main(int argc, char *argv[])
|
||||
e -= 1;
|
||||
}
|
||||
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;
|
||||
if (sigaction(SIGUSR1, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler (%d, %s).\n", SIGUSR1, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("main : Blocking signal (%d).\n", SIGUSR1);
|
||||
@@ -45,5 +45,5 @@ int main(int argc, char *argv[])
|
||||
ret = kill(getpid(), SIGUSR1);
|
||||
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) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGUSR1, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (sigaction(SIGUSR2, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler (%s).\n", SIGUSR2, strerror(errno));
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
kill(getpid(), SIGUSR1);
|
||||
@@ -51,5 +51,6 @@ int main(int argc, char *argv[])
|
||||
kill(getpid(), SIGUSR2);
|
||||
|
||||
while(1) { };
|
||||
return 0;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -17,5 +17,5 @@ int main(int argc, char *argv[])
|
||||
sleep(4);
|
||||
printf("COMPLETED.\n");
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ int main(int argc, char *argv[])
|
||||
action.sa_handler = wait_for_child;
|
||||
if (sigaction(SIGCHLD, &action, NULL) == -1) {
|
||||
printf("Failed to set signal handler. %d\n", SIGCHLD);
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
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