master eb30f8802fac cached
430 files
729.8 KB
231.9k tokens
936 symbols
1 requests
Download .txt
Showing preview only (822K chars total). Download the full file or copy to clipboard to get everything.
Repository: SamyPesse/How-to-Make-a-Computer-Operating-System
Branch: master
Commit: eb30f8802fac
Files: 430
Total size: 729.8 KB

Directory structure:
gitextract_39nrcw17/

├── .gitignore
├── Chapter-1/
│   └── README.md
├── Chapter-2/
│   └── README.md
├── Chapter-3/
│   └── README.md
├── Chapter-4/
│   └── README.md
├── Chapter-5/
│   └── README.md
├── Chapter-6/
│   └── README.md
├── Chapter-7/
│   └── README.md
├── Chapter-8/
│   └── README.md
├── LICENSE
├── README.md
├── SUMMARY.md
├── chapter9/
│   └── README.md
└── src/
    ├── Makefile
    ├── Vagrantfile
    ├── kernel/
    │   ├── Makefile
    │   ├── arch/
    │   │   └── x86/
    │   │       ├── Makefile
    │   │       ├── alloc.cc
    │   │       ├── architecture.cc
    │   │       ├── architecture.h
    │   │       ├── archprocess.h
    │   │       ├── config.make
    │   │       ├── io.cc
    │   │       ├── io.h
    │   │       ├── linker.ld
    │   │       ├── start.asm
    │   │       ├── switch.asm
    │   │       ├── vmm.cc
    │   │       ├── vmm.h
    │   │       ├── x86.cc
    │   │       ├── x86.h
    │   │       └── x86int.asm
    │   ├── config.h
    │   ├── core/
    │   │   ├── Makefile
    │   │   ├── api/
    │   │   │   ├── dev/
    │   │   │   │   ├── clock.h
    │   │   │   │   ├── fb.h
    │   │   │   │   ├── ioctl.h
    │   │   │   │   ├── ipc.h
    │   │   │   │   ├── keyboard.h
    │   │   │   │   ├── proc.h
    │   │   │   │   └── tty.h
    │   │   │   └── kernel/
    │   │   │       ├── syscall.h
    │   │   │       └── syscall_table.h
    │   │   ├── api.h
    │   │   ├── api_posix.cc
    │   │   ├── boot.h
    │   │   ├── class.cc
    │   │   ├── device.cc
    │   │   ├── device.h
    │   │   ├── elf_loader.cc
    │   │   ├── elf_loader.h
    │   │   ├── env.cc
    │   │   ├── env.h
    │   │   ├── file.cc
    │   │   ├── file.h
    │   │   ├── filesystem.cc
    │   │   ├── filesystem.h
    │   │   ├── kernel.cc
    │   │   ├── kernel.h
    │   │   ├── keyboard.h
    │   │   ├── modulelink.cc
    │   │   ├── modulelink.h
    │   │   ├── os.h
    │   │   ├── process.cc
    │   │   ├── process.h
    │   │   ├── signal.h
    │   │   ├── socket.cc
    │   │   ├── socket.h
    │   │   ├── syscalls.cc
    │   │   ├── syscalls.h
    │   │   ├── system.cc
    │   │   ├── system.h
    │   │   ├── user.cc
    │   │   └── user.h
    │   ├── modules/
    │   │   ├── Makefile
    │   │   ├── bochsvbe.cc
    │   │   ├── bochsvbe.h
    │   │   ├── clock_x86.cc
    │   │   ├── clock_x86.h
    │   │   ├── dospartition.cc
    │   │   ├── dospartition.h
    │   │   ├── ext2.cc
    │   │   ├── ext2.h
    │   │   ├── ide.cc
    │   │   ├── ide.h
    │   │   ├── keys.cc
    │   │   ├── keys.h
    │   │   ├── module.cc
    │   │   ├── module.h
    │   │   ├── modules.conf
    │   │   ├── null.cc
    │   │   ├── null.h
    │   │   ├── stdtty.cc
    │   │   ├── stdtty.h
    │   │   ├── x86serial.cc
    │   │   └── x86serial.h
    │   └── runtime/
    │       ├── Makefile
    │       ├── alloc.h
    │       ├── buffer.cc
    │       ├── buffer.h
    │       ├── cxx.cc
    │       ├── itoa.cc
    │       ├── libc.h
    │       ├── list.h
    │       ├── memory.cc
    │       ├── string.cc
    │       ├── string.h
    │       └── types.h
    ├── sdk/
    │   ├── Makefile
    │   ├── bootdisk/
    │   │   ├── bin/
    │   │   │   └── .gitkeep
    │   │   └── boot/
    │   │       └── grub/
    │   │           ├── grub.conf
    │   │           ├── menu.lst
    │   │           ├── stage1
    │   │           ├── stage2
    │   │           └── stage2_eltorito
    │   ├── build.mak
    │   ├── diskimage.sh
    │   ├── include/
    │   │   ├── _ansi.h
    │   │   ├── alloca.h
    │   │   ├── arpa/
    │   │   │   └── inet.h
    │   │   ├── assert.h
    │   │   ├── ctype.h
    │   │   ├── dirent.h
    │   │   ├── endian.h
    │   │   ├── errno.h
    │   │   ├── fcntl.h
    │   │   ├── float.h
    │   │   ├── getopt.h
    │   │   ├── inttypes.h
    │   │   ├── limits.h
    │   │   ├── linker.ld
    │   │   ├── locale.h
    │   │   ├── math.h
    │   │   ├── netinet/
    │   │   │   └── in.h
    │   │   ├── os.h
    │   │   ├── pwd.h
    │   │   ├── setjmp.h
    │   │   ├── signal.h
    │   │   ├── stdarg.h
    │   │   ├── stddef.h
    │   │   ├── stdint.h
    │   │   ├── stdio.h
    │   │   ├── stdlib.h
    │   │   ├── string.h
    │   │   ├── strings.h
    │   │   ├── sys/
    │   │   │   ├── cdefs.h
    │   │   │   ├── ioctl.h
    │   │   │   ├── mman.h
    │   │   │   ├── mount.h
    │   │   │   ├── param.h
    │   │   │   ├── resource.h
    │   │   │   ├── select.h
    │   │   │   ├── socket.h
    │   │   │   ├── stat.h
    │   │   │   ├── time.h
    │   │   │   ├── types.h
    │   │   │   └── wait.h
    │   │   ├── termios.h
    │   │   ├── time.h
    │   │   ├── unistd.h
    │   │   └── utime.h
    │   ├── lib/
    │   │   └── .gitkeep
    │   ├── qemu.sh
    │   └── src/
    │       └── libc/
    │           ├── Makefile
    │           ├── arch/
    │           │   └── i386/
    │           │       ├── getpagesize.c
    │           │       ├── longjmp.S
    │           │       ├── math/
    │           │       │   ├── e_atan2.S
    │           │       │   ├── e_exp.S
    │           │       │   ├── e_fmod.S
    │           │       │   ├── e_hypot.S
    │           │       │   ├── e_log.S
    │           │       │   ├── e_log10.S
    │           │       │   ├── e_pow.S
    │           │       │   ├── s_ceil.S
    │           │       │   ├── s_cos.S
    │           │       │   ├── s_fabs.S
    │           │       │   ├── s_finite.S
    │           │       │   ├── s_floor.S
    │           │       │   ├── s_frexp.S
    │           │       │   ├── s_scalbn.S
    │           │       │   └── s_sin.S
    │           │       └── setjmp.S
    │           └── src/
    │               ├── closedir.c
    │               ├── ctype/
    │               │   ├── isalnum.c
    │               │   ├── isalpha.c
    │               │   ├── isascii.c
    │               │   ├── isblank.c
    │               │   ├── iscntrl.c
    │               │   ├── isdigit.c
    │               │   ├── isgraph.c
    │               │   ├── islower.c
    │               │   ├── isprint.c
    │               │   ├── ispunct.c
    │               │   ├── isspace.c
    │               │   ├── isupper.c
    │               │   ├── isxdigit.c
    │               │   ├── toascii.c
    │               │   ├── tolower.c
    │               │   └── toupper.c
    │               ├── fcntl/
    │               │   ├── creat.c
    │               │   ├── fcntl.c
    │               │   └── open.c
    │               ├── getopt/
    │               │   ├── getopt.c
    │               │   ├── getopt_int.h
    │               │   ├── getopt_long.c
    │               │   └── getopt_long_only.c
    │               ├── locale/
    │               │   ├── localeconv.c
    │               │   └── setlocale.c
    │               ├── math/
    │               │   ├── s_ldexp.c
    │               │   └── s_modf.c
    │               ├── network/
    │               │   ├── inet_aton.c
    │               │   └── inet_ntoa.c
    │               ├── opendir.c
    │               ├── os/
    │               │   ├── debug.c
    │               │   ├── ipc.c
    │               │   ├── module.c
    │               │   ├── os.c
    │               │   ├── region.c
    │               │   ├── semaphore.c
    │               │   ├── syscall.c
    │               │   ├── sysinfo.c
    │               │   └── thread.c
    │               ├── pwd/
    │               │   ├── endpwent.c
    │               │   ├── getpwent.c
    │               │   ├── getpwnam.c
    │               │   ├── getpwuid.c
    │               │   └── setpwent.c
    │               ├── readdir.c
    │               ├── rewinddir.c
    │               ├── signal/
    │               │   ├── kill.c
    │               │   ├── killpg.c
    │               │   ├── raise.c
    │               │   ├── sigaction.c
    │               │   ├── sigaddset.c
    │               │   ├── sigdelset.c
    │               │   ├── sigemptyset.c
    │               │   ├── sigfillset.c
    │               │   ├── sigismember.c
    │               │   ├── signal.c
    │               │   └── sigprocmask.c
    │               ├── sscanf.c
    │               ├── start.c
    │               ├── stdio/
    │               │   ├── clearerr.c
    │               │   ├── fclose.c
    │               │   ├── fdopen.c
    │               │   ├── feof.c
    │               │   ├── ferror.c
    │               │   ├── fflush.c
    │               │   ├── fgetc.c
    │               │   ├── fgets.c
    │               │   ├── fileno.c
    │               │   ├── fopen.c
    │               │   ├── fpurge.c
    │               │   ├── fputc.c
    │               │   ├── fputs.c
    │               │   ├── fread.c
    │               │   ├── freopen.c
    │               │   ├── fseek.c
    │               │   ├── ftell.c
    │               │   ├── fwrite.c
    │               │   ├── getc.c
    │               │   ├── perror.c
    │               │   ├── putc.c
    │               │   ├── putchar.c
    │               │   ├── puts.c
    │               │   ├── remove.c
    │               │   ├── rename.c
    │               │   ├── rewind.c
    │               │   ├── setvbuf.c
    │               │   ├── stdio_internal.c
    │               │   ├── stdio_internal.h
    │               │   ├── streams.c
    │               │   ├── support_bufio.c
    │               │   ├── support_pf.c
    │               │   ├── support_supcon.c
    │               │   └── ungetc.c
    │               ├── stdlib/
    │               │   ├── abort.c
    │               │   ├── abs.c
    │               │   ├── atof.c
    │               │   ├── atoi.c
    │               │   ├── atol.c
    │               │   ├── atoll.c
    │               │   ├── bsearch.c
    │               │   ├── getenv.c
    │               │   ├── labs.c
    │               │   ├── llabs.c
    │               │   ├── malloc.c
    │               │   ├── mkstemp.c
    │               │   ├── mktemp.c
    │               │   ├── qsort.c
    │               │   ├── rand.c
    │               │   ├── random.c
    │               │   ├── srand.c
    │               │   ├── srandom.c
    │               │   ├── strtod.c
    │               │   ├── strtol.c
    │               │   ├── strtoll.c
    │               │   ├── strtoul.c
    │               │   └── strtoull.c
    │               ├── string/
    │               │   ├── memchr.c
    │               │   ├── memcmp.c
    │               │   ├── memcpy.c
    │               │   ├── memmove.c
    │               │   ├── memset.c
    │               │   ├── strcasecmp.c
    │               │   ├── strcat.c
    │               │   ├── strchr.c
    │               │   ├── strcmp.c
    │               │   ├── strcpy.c
    │               │   ├── strcspn.c
    │               │   ├── strdup.c
    │               │   ├── strerror.c
    │               │   ├── strlen.c
    │               │   ├── strncasecmp.c
    │               │   ├── strncat.c
    │               │   ├── strncmp.c
    │               │   ├── strncpy.c
    │               │   ├── strndup.c
    │               │   ├── strnlen.c
    │               │   ├── strpbrk.c
    │               │   ├── strrchr.c
    │               │   ├── strsignal.c
    │               │   ├── strspn.c
    │               │   ├── strstr.c
    │               │   ├── strtok.c
    │               │   └── strtok_r.c
    │               ├── sys/
    │               │   ├── chmod.c
    │               │   ├── connect.c
    │               │   ├── fstat.c
    │               │   ├── ioctl.c
    │               │   ├── lstat.c
    │               │   ├── mkdir.c
    │               │   ├── mount.c
    │               │   ├── select.c
    │               │   ├── socket.c
    │               │   ├── stat.c
    │               │   ├── stime.c
    │               │   ├── umask.c
    │               │   ├── umount.c
    │               │   ├── utime.c
    │               │   ├── utimes.c
    │               │   ├── wait.c
    │               │   ├── wait3.c
    │               │   ├── wait4.c
    │               │   └── waitpid.c
    │               ├── termios/
    │               │   ├── tcflow.c
    │               │   ├── tcflush.c
    │               │   ├── tcgetattr.c
    │               │   ├── tcgetpgrp.c
    │               │   ├── tcsetattr.c
    │               │   └── tcsetpgrp.c
    │               ├── time/
    │               │   ├── asctime.c
    │               │   ├── asctime_r.c
    │               │   ├── ctime.c
    │               │   ├── ctime_r.c
    │               │   ├── gettimeofday.c
    │               │   ├── gmtime.c
    │               │   ├── gmtime_r.c
    │               │   ├── localtime.c
    │               │   ├── localtime_r.c
    │               │   ├── mktime.c
    │               │   ├── nanosleep.c
    │               │   ├── strftime.c
    │               │   ├── time.c
    │               │   ├── time_int.c
    │               │   ├── time_int.h
    │               │   └── tzset.c
    │               ├── trio/
    │               │   ├── trio.c
    │               │   ├── trio.h
    │               │   ├── triodef.h
    │               │   ├── trionan.c
    │               │   ├── trionan.h
    │               │   ├── triop.h
    │               │   ├── triostr.c
    │               │   └── triostr.h
    │               ├── udivmoddi4.c
    │               └── unistd/
    │                   ├── access.c
    │                   ├── alarm.c
    │                   ├── chdir.c
    │                   ├── chown.c
    │                   ├── close.c
    │                   ├── dup.c
    │                   ├── dup2.c
    │                   ├── execlp.c
    │                   ├── execv.c
    │                   ├── execve.c
    │                   ├── execvp.c
    │                   ├── exit.c
    │                   ├── fchdir.c
    │                   ├── fork.c
    │                   ├── fpathconf.c
    │                   ├── ftruncate.c
    │                   ├── getcwd.c
    │                   ├── getdents.c
    │                   ├── getdtablesize.c
    │                   ├── getegid.c
    │                   ├── geteuid.c
    │                   ├── getgid.c
    │                   ├── gethostname.c
    │                   ├── getpgid.c
    │                   ├── getpgrp.c
    │                   ├── getpid.c
    │                   ├── getppid.c
    │                   ├── gettid.c
    │                   ├── getuid.c
    │                   ├── isatty.c
    │                   ├── link.c
    │                   ├── lseek.c
    │                   ├── mmap.c
    │                   ├── pipe.c
    │                   ├── pread.c
    │                   ├── pwrite.c
    │                   ├── read.c
    │                   ├── readlink.c
    │                   ├── rmdir.c
    │                   ├── sbrk.c
    │                   ├── setgid.c
    │                   ├── setpgid.c
    │                   ├── setpgrp.c
    │                   ├── setregid.c
    │                   ├── setreuid.c
    │                   ├── setuid.c
    │                   ├── sleep.c
    │                   ├── symlink.c
    │                   ├── ttyname.c
    │                   ├── unlink.c
    │                   └── write.c
    └── userland/
        ├── Makefile
        └── helloworld/
            ├── Makefile
            └── main.c

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Compiled Object files
*.slo
*.lo
*.o

# Compiled Dynamic libraries
*.so
*.dylib

# Compiled Static libraries
*.lai
*.la
*.a

# Elf binaries
*.elf

# Vagrant
/src/.vagrant/

# Other
/src/userland/helloworld/hello

# SDK binaries
/src/sdk/bootdisk/bin/hello
/src/sdk/c.img

node_modules
.grunt
_book


================================================
FILE: Chapter-1/README.md
================================================
## Chapter 1: Introduction to the x86 architecture and about our OS

### What is the x86 architecture?

> The term x86 denotes a family of backward compatible instruction set architectures based on the Intel 8086 CPU.

The x86 architecture is the most common instruction set architecture since its introduction in 1981 for the IBM PC. A large amount of software, including operating systems (OS's) such as DOS, Windows, Linux, BSD, Solaris and Mac OS X, function with x86-based hardware.

In this course we are not going to design an operating system for the x86-64 architecture but for x86-32, thanks to backward compatibility, our OS will be compatible with our newer PCs (but take caution if you want to test it on your real machine).

### Our Operating System

The goal is to build a very simple UNIX-based operating system in C++, but the goal is not to just build a "proof-of-concept". The OS should be able to boot, start a userland shell and be extensible.

The OS will be built for the x86 architecture, running on 32 bits, and compatible with IBM PCs.

**Specifications:**

* Code in C++
* x86, 32 bit architecture
* Boot with Grub
* Kind of modular system for drivers
* Kind of UNIX style
* Multitasking
* ELF executable in userland
* Modules (accessible in userland using /dev/...) :
    * IDE disks
    * DOS partitions
    * Clock
    * EXT2 (read only)
    * Boch VBE
* Userland :
    * API Posix
    * LibC
    * "Can" run a shell or some executables (e.g., lua)


================================================
FILE: Chapter-2/README.md
================================================
## Chapter 2: Setup the development environment

The first step is to setup a good and viable development environment. Using Vagrant and Virtualbox, you'll be able to compile and test your OS from all the OSs (Linux, Windows or Mac).

### Install Vagrant

> Vagrant is free and open-source software for creating and configuring virtual development environments. It can be considered a wrapper around VirtualBox.

Vagrant will help us create a clean virtual development environment on whatever system you are using.
The first step is to download and install Vagrant for your system at http://www.vagrantup.com/.

### Install Virtualbox

> Oracle VM VirtualBox is a virtualization software package for x86 and AMD64/Intel64-based computers.

Vagrant needs Virtualbox to work, Download and install for your system at https://www.virtualbox.org/wiki/Downloads.

### Start and test your development environment

Once Vagrant and Virtualbox are installed, you need to download the ubuntu lucid32 image for Vagrant:

```
vagrant box add lucid32 http://files.vagrantup.com/lucid32.box
```

Once the lucid32 image is ready, we need to define our development environment using a *Vagrantfile*, [create a file named *Vagrantfile*](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/Vagrantfile). This file defines what prerequisites our environment needs: nasm, make, build-essential, grub and qemu.

Start your box using:

```
vagrant up
```

You can now access your box by using ssh to connect to the virtual box using:

```
vagrant ssh
```

The directory containing the *Vagrantfile* will be mounted by default in the */vagrant* directory of the guest VM (in this case, Ubuntu Lucid32):

```
cd /vagrant
```

#### Build and test our operating system

The file [**Makefile**](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/Makefile) defines some basics rules for building the kernel, the user libc and some userland programs.

Build:

```
make all
```

Test our operating system with qemu:

```
make run
```

The documentation for qemu is available at [QEMU Emulator Documentation](http://wiki.qemu.org/download/qemu-doc.html).

You can exit the emulator using: Ctrl-a.


================================================
FILE: Chapter-3/README.md
================================================
## Chapter 3: First boot with GRUB

#### How the boot works?

When an x86-based computer is turned on, it begins a complex path to get to the stage where control is transferred to our kernel's "main" routine (`kmain()`). For this course, we are only going to consider the BIOS boot method and not it's successor (UEFI).

The BIOS boot sequence is: RAM detection -> Hardware detection/Initialization -> Boot sequence.

The most important step for us is the "Boot sequence", where the BIOS is done with its initialization and tries to transfer control to the next stage of the bootloader process.

During the "Boot sequence", the BIOS will try to determine a "boot device" (e.g. floppy disk, hard-disk, CD, USB flash memory device or network). Our Operating System will initially boot from the hard-disk (but it will be possible to boot it from a CD or a USB flash memory device in future). A device is considered bootable if the bootsector contains the valid signature bytes `0x55` and `0xAA` at offsets 511 and 512 respectively (called the magic bytes of the Master Boot Record, also known as the MBR). This signature is represented (in binary) as 0b1010101001010101. The alternating bit pattern was thought to be a protection against certain failures (drive or controller). If this pattern is garbled or 0x00, the device is not considered bootable.

BIOS physically searches for a boot device by loading the first 512 bytes from the bootsector of each device into physical memory, starting at the address `0x7C00` (1 KiB below the 32 KiB mark). When the valid signature bytes are detected, BIOS transfers control to the `0x7C00` memory address (via a jump instruction) in order to execute the bootsector code.

Throughout this process the CPU has been running in 16-bit Real Mode, which is the default state for x86 CPUs in order to maintain backwards compatibility. To execute the 32-bit instructions within our kernel, a bootloader is required to switch the CPU into Protected Mode.

#### What is GRUB?

> GNU GRUB (short for GNU GRand Unified Bootloader) is a boot loader package from the GNU Project. GRUB is the reference implementation of the Free Software Foundation's Multiboot Specification, which provides a user the choice to boot one of multiple operating systems installed on a computer or select a specific kernel configuration available on a particular operating system's partitions.

To make it simple, GRUB is the first thing booted by the machine (a boot-loader) and will simplify the loading of our kernel stored on the hard-disk.

#### Why are we using GRUB?

* GRUB is very simple to use
* Make it very simple to load 32bits kernels without needs of 16bits code
* Multiboot with Linux, Windows and others
* Make it easy to load external modules in memory

#### How to use GRUB?

GRUB uses the Multiboot specification, the executable binary should be 32bits and must contain a special header (multiboot header) in its 8192 first bytes. Our kernel will be a ELF executable file ("Executable and Linkable Format", a common standard file format for executables in most UNIX system).

The first boot sequence of our kernel is written in Assembly: [start.asm](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/start.asm) and we use a linker file to define our executable structure: [linker.ld](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/linker.ld).

This boot process also initializes some of our C++ runtime, it will be described in the next chapter.

Multiboot header structure:

```cpp
struct multiboot_info {
	u32 flags;
	u32 low_mem;
	u32 high_mem;
	u32 boot_device;
	u32 cmdline;
	u32 mods_count;
	u32 mods_addr;
	struct {
		u32 num;
		u32 size;
		u32 addr;
		u32 shndx;
	} elf_sec;
	unsigned long mmap_length;
	unsigned long mmap_addr;
	unsigned long drives_length;
	unsigned long drives_addr;
	unsigned long config_table;
	unsigned long boot_loader_name;
	unsigned long apm_table;
	unsigned long vbe_control_info;
	unsigned long vbe_mode_info;
	unsigned long vbe_mode;
	unsigned long vbe_interface_seg;
	unsigned long vbe_interface_off;
	unsigned long vbe_interface_len;
};
```

You can use the command ```mbchk kernel.elf``` to validate your kernel.elf file against the multiboot standard. You can also use the command ```nm -n kernel.elf``` to validate the offset of the different objects in the ELF binary.

#### Create a disk image for our kernel and grub

The script [diskimage.sh](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/sdk/diskimage.sh) will generate a hard disk image that can be used by QEMU.

The first step is to create a hard-disk image (c.img) using qemu-img:

```
qemu-img create c.img 2M
```

We need now to partition the disk using fdisk:

```bash
fdisk ./c.img

# Switch to Expert commands
> x

# Change number of cylinders (1-1048576)
> c
> 4

# Change number of heads (1-256, default 16):
> h
> 16

# Change number of sectors/track (1-63, default 63)
> s
> 63

# Return to main menu
> r

# Add a new partition
> n

# Choose primary partition
> p

# Choose partition number
> 1

# Choose first sector (1-4, default 1)
> 1

# Choose last sector, +cylinders or +size{K,M,G} (1-4, default 4)
> 4

# Toggle bootable flag
> a

# Choose first partition for bootable flag
> 1

# Write table to disk and exit
> w
```

We need now to attach the created partition to the loop-device using losetup. This allows a file to be access like a block device. The offset of the partition is passed as an argument and calculated using: **offset= start_sector * bytes_by_sector**.

Using ```fdisk -l -u c.img```, you get: 63 * 512 = 32256.

```bash
losetup -o 32256 /dev/loop1 ./c.img
```

We create a EXT2 filesystem on this new device using:

```bash
mke2fs /dev/loop1
```

We copy our files on a mounted disk:

```bash
mount  /dev/loop1 /mnt/
cp -R bootdisk/* /mnt/
umount /mnt/
```

Install GRUB on the disk:

```bash
grub --device-map=/dev/null << EOF
device (hd0) ./c.img
geometry (hd0) 4 16 63
root (hd0,0)
setup (hd0)
quit
EOF
```

And finally we detach the loop device:

```bash
losetup -d /dev/loop1
```

#### See Also

* [GNU GRUB on Wikipedia](http://en.wikipedia.org/wiki/GNU_GRUB)
* [Multiboot specification](https://www.gnu.org/software/grub/manual/multiboot/multiboot.html)


================================================
FILE: Chapter-4/README.md
================================================
## Chapter 4: Backbone of the OS and C++ runtime

#### C++ kernel run-time

A kernel can be written in C++ just as it can be in C, with the exception of a few pitfalls that come with using C++ (runtime support, constructors, etc). 

The compiler will assume that all the necessary C++ runtime support is available by default, but as we are not linking libsupc++ into your C++ kernel, we need to add some basic functions that can be found in the [cxx.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/runtime/cxx.cc) file.

**Caution:** The operators `new` and `delete` cannot be used before virtual memory and pagination have been initialized.

#### Basic C/C++ functions

The kernel code can't use functions from the standard libraries so we need to add some basic functions for managing memory and strings:

```cpp
void 	itoa(char *buf, unsigned long int n, int base);

void *	memset(char *dst,char src, int n);
void *	memcpy(char *dst, char *src, int n);

int 	strlen(char *s);
int 	strcmp(const char *dst, char *src);
int 	strcpy(char *dst,const char *src);
void 	strcat(void *dest,const void *src);
char *	strncpy(char *destString, const char *sourceString,int maxLength);
int 	strncmp( const char* s1, const char* s2, int c );
```

These functions are defined in [string.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/runtime/string.cc), [memory.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/runtime/memory.cc), [itoa.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/runtime/itoa.cc)

#### C types

In the next step, we're going to define different types we're going to use in our code. Most of our variable types are going to be unsigned. This means that all the bits are used to store the integer. Signed variables use their first bit to indicate their sign. 

```cpp
typedef unsigned char 	u8;
typedef unsigned short 	u16;
typedef unsigned int 	u32;
typedef unsigned long long 	u64;

typedef signed char 	s8;
typedef signed short 	s16;
typedef signed int 		s32;
typedef signed long long	s64;
```

#### Compile our kernel

Compiling a kernel is not the same thing as compiling a linux executable, we can't use a standard library and should have no dependencies to the system.

Our [Makefile](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/Makefile) will define the process to compile and link our kernel.

For x86 architecture, the followings arguments will be used for gcc/g++/ld:

```
# Linker
LD=ld
LDFLAG= -melf_i386 -static  -L ./  -T ./arch/$(ARCH)/linker.ld

# C++ compiler
SC=g++
FLAG= $(INCDIR) -g -O2 -w -trigraphs -fno-builtin  -fno-exceptions -fno-stack-protector -O0 -m32  -fno-rtti -nostdlib -nodefaultlibs 

# Assembly compiler
ASM=nasm
ASMFLAG=-f elf -o
```


================================================
FILE: Chapter-5/README.md
================================================
## Chapter 5: Base classes for managing x86 architecture

Now that we know how to compile our C++ kernel and boot the binary using GRUB, we can start to do some cool things in C/C++.

#### Printing to the screen console

We are going to use VGA default mode (03h) to display some text to the user. The screen can be directly accessed using the video memory at 0xB8000. The screen resolution is 80x25 and each character on the screen is defined by 2 bytes: one for the character code, and one for the style flag. This means that the total size of the video memory is 4000B (80B*25B*2B).

In the IO class ([io.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/io.cc)),:
* **x,y**: define the cursor position on the screen
* **real_screen**: define the  video memory pointer
* **putc(char c)**: print a unique character on the screen and manage cursor position
* **printf(char* s, ...)**: print a string

We add a method **putc** to the [IO Class](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/io.cc) to put a character on the screen and update the (x,y) position.

```cpp
/* put a byte on screen */
void Io::putc(char c){
	kattr = 0x07;
	unsigned char *video;
	video = (unsigned char *) (real_screen+ 2 * x + 160 * y);
	// newline
	if (c == '\n') {
		x = 0;
		y++;
	// back space
	} else if (c == '\b') {
		if (x) {
			*(video + 1) = 0x0;
			x--;
		}
	// horizontal tab
	} else if (c == '\t') {
		x = x + 8 - (x % 8);
	// carriage return
	} else if (c == '\r') {
		x = 0;
	} else {
		*video = c;
		*(video + 1) = kattr;

		x++;
		if (x > 79) {
			x = 0;
			y++;
		}
	}
	if (y > 24)
		scrollup(y - 24);
}
```

We also add a useful and very known method: [printf](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/io.cc#L155)

```cpp
/* put a string in screen */
void Io::print(const char *s, ...){
	va_list ap;

	char buf[16];
	int i, j, size, buflen, neg;

	unsigned char c;
	int ival;
	unsigned int uival;

	va_start(ap, s);

	while ((c = *s++)) {
		size = 0;
		neg = 0;

		if (c == 0)
			break;
		else if (c == '%') {
			c = *s++;
			if (c >= '0' && c <= '9') {
				size = c - '0';
				c = *s++;
			}

			if (c == 'd') {
				ival = va_arg(ap, int);
				if (ival < 0) {
					uival = 0 - ival;
					neg++;
				} else
					uival = ival;
				itoa(buf, uival, 10);

				buflen = strlen(buf);
				if (buflen < size)
					for (i = size, j = buflen; i >= 0;
					     i--, j--)
						buf[i] =
						    (j >=
						     0) ? buf[j] : '0';

				if (neg)
					print("-%s", buf);
				else
					print(buf);
			}
			 else if (c == 'u') {
				uival = va_arg(ap, int);
				itoa(buf, uival, 10);

				buflen = strlen(buf);
				if (buflen < size)
					for (i = size, j = buflen; i >= 0;
					     i--, j--)
						buf[i] =
						    (j >=
						     0) ? buf[j] : '0';

				print(buf);
			} else if (c == 'x' || c == 'X') {
				uival = va_arg(ap, int);
				itoa(buf, uival, 16);

				buflen = strlen(buf);
				if (buflen < size)
					for (i = size, j = buflen; i >= 0;
					     i--, j--)
						buf[i] =
						    (j >=
						     0) ? buf[j] : '0';

				print("0x%s", buf);
			} else if (c == 'p') {
				uival = va_arg(ap, int);
				itoa(buf, uival, 16);
				size = 8;

				buflen = strlen(buf);
				if (buflen < size)
					for (i = size, j = buflen; i >= 0;
					     i--, j--)
						buf[i] =
						    (j >=
						     0) ? buf[j] : '0';

				print("0x%s", buf);
			} else if (c == 's') {
				print((char *) va_arg(ap, int));
			}
		} else
			putc(c);
	}

	return;
}
```

#### Assembly interface

A large number of instructions are available in Assembly but there is not equivalent in C (like cli, sti, in and out), so we need an interface to these instructions.

In C, we can include Assembly using the directive "asm()", gcc use gas to compile the assembly.

**Caution:** gas uses the AT&T syntax.

```cpp
/* output byte */
void Io::outb(u32 ad, u8 v){
	asmv("outb %%al, %%dx" :: "d" (ad), "a" (v));;
}
/* output word */
void Io::outw(u32 ad, u16 v){
	asmv("outw %%ax, %%dx" :: "d" (ad), "a" (v));
}
/* output word */
void Io::outl(u32 ad, u32 v){
	asmv("outl %%eax, %%dx" : : "d" (ad), "a" (v));
}
/* input byte */
u8 Io::inb(u32 ad){
	u8 _v;       \
	asmv("inb %%dx, %%al" : "=a" (_v) : "d" (ad)); \
	return _v;
}
/* input word */
u16	Io::inw(u32 ad){
	u16 _v;			\
	asmv("inw %%dx, %%ax" : "=a" (_v) : "d" (ad));	\
	return _v;
}
/* input word */
u32	Io::inl(u32 ad){
	u32 _v;			\
	asmv("inl %%dx, %%eax" : "=a" (_v) : "d" (ad));	\
	return _v;
}
```


================================================
FILE: Chapter-6/README.md
================================================
## Chapter 6: GDT

Thanks to GRUB, your kernel is no longer in real-mode, but already in [protected mode](http://en.wikipedia.org/wiki/Protected_mode), this mode allows us to use all the possibilities of the microprocessor such as virtual memory management, paging and safe multi-tasking.

#### What is the GDT?

The [GDT](http://en.wikipedia.org/wiki/Global_Descriptor_Table) ("Global Descriptor Table") is a data structure used to define the different memory areas: the base address, the size and access privileges like execute and write. These memory areas are called "segments".

We are going to use the GDT to define different memory segments:

* *"code"*: kernel code, used to stored the executable binary code
* *"data"*: kernel data
* *"stack"*: kernel stack, used to stored the call stack during kernel execution
* *"ucode"*: user code, used to stored the executable binary code for user program
* *"udata"*: user program data
* *"ustack"*: user stack, used to stored the call stack during execution in userland

#### How to load our GDT?

GRUB initializes a GDT but this GDT is does not correspond to our kernel.
The GDT is loaded using the LGDT assembly instruction. It expects the location of a GDT description structure:

![GDTR](./gdtr.png)

And the C structure:

```cpp
struct gdtr {
	u16 limite;
	u32 base;
} __attribute__ ((packed));
```

**Caution:** the directive ```__attribute__ ((packed))``` signal to gcc that the structure should use as little memory as possible. Without this directive, gcc include some bytes to optimize the memory alignment and the access during execution.

Now we need to define our GDT table and then load it using LGDT. The GDT table can be stored wherever we want in memory, its address should just be signaled to the process using the GDTR registry.

The GDT table is composed of segments with the following structure:

![GDTR](./gdtentry.png)

And the C structure:

```cpp
struct gdtdesc {
	u16 lim0_15;
	u16 base0_15;
	u8 base16_23;
	u8 acces;
	u8 lim16_19:4;
	u8 other:4;
	u8 base24_31;
} __attribute__ ((packed));
```

#### How to define our GDT table?

We need now to define our GDT in memory and finally load it using the GDTR registry.

We are going to store our GDT at the address:

```cpp
#define GDTBASE	0x00000800
```

The function **init_gdt_desc** in [x86.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/x86.cc) initialize a gdt segment descriptor.

```cpp
void init_gdt_desc(u32 base, u32 limite, u8 acces, u8 other, struct gdtdesc *desc)
{
	desc->lim0_15 = (limite & 0xffff);
	desc->base0_15 = (base & 0xffff);
	desc->base16_23 = (base & 0xff0000) >> 16;
	desc->acces = acces;
	desc->lim16_19 = (limite & 0xf0000) >> 16;
	desc->other = (other & 0xf);
	desc->base24_31 = (base & 0xff000000) >> 24;
	return;
}
```

And the function **init_gdt** initialize the GDT, some parts of the below function will be explained later and are used for multitasking.

```cpp
void init_gdt(void)
{
	default_tss.debug_flag = 0x00;
	default_tss.io_map = 0x00;
	default_tss.esp0 = 0x1FFF0;
	default_tss.ss0 = 0x18;

	/* initialize gdt segments */
	init_gdt_desc(0x0, 0x0, 0x0, 0x0, &kgdt[0]);
	init_gdt_desc(0x0, 0xFFFFF, 0x9B, 0x0D, &kgdt[1]);	/* code */
	init_gdt_desc(0x0, 0xFFFFF, 0x93, 0x0D, &kgdt[2]);	/* data */
	init_gdt_desc(0x0, 0x0, 0x97, 0x0D, &kgdt[3]);		/* stack */

	init_gdt_desc(0x0, 0xFFFFF, 0xFF, 0x0D, &kgdt[4]);	/* ucode */
	init_gdt_desc(0x0, 0xFFFFF, 0xF3, 0x0D, &kgdt[5]);	/* udata */
	init_gdt_desc(0x0, 0x0, 0xF7, 0x0D, &kgdt[6]);		/* ustack */

	init_gdt_desc((u32) & default_tss, 0x67, 0xE9, 0x00, &kgdt[7]);	/* descripteur de tss */

	/* initialize the gdtr structure */
	kgdtr.limite = GDTSIZE * 8;
	kgdtr.base = GDTBASE;

	/* copy the gdtr to its memory area */
	memcpy((char *) kgdtr.base, (char *) kgdt, kgdtr.limite);

	/* load the gdtr registry */
	asm("lgdtl (kgdtr)");

	/* initiliaz the segments */
	asm("   movw $0x10, %ax	\n \
            movw %ax, %ds	\n \
            movw %ax, %es	\n \
            movw %ax, %fs	\n \
            movw %ax, %gs	\n \
            ljmp $0x08, $next	\n \
            next:		\n");
}
```


================================================
FILE: Chapter-7/README.md
================================================
## Chapter 7: IDT and interrupts

An interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention.

There are 3 types of interrupts:

- **Hardware interrupts:** are sent to the processor from an external device (keyboard, mouse, hard disk, ...). Hardware interrupts were introduced as a way to reduce wasting the processor's valuable time in polling loops, waiting for external events.
- **Software interrupts:** are initiated voluntarily by the software. It's used to manage system calls.
- **Exceptions:**  are used for errors or events occurring during program execution that are exceptional enough that they cannot be handled within the program itself (division by zero, page fault, ...)

#### The keyboard example:

When the user pressed a key on the keyboard, the keyboard controller will signal an interrupt to the Interrupt Controller. If the interrupt is not masked, the controller will signal the interrupt to the processor, the processor will execute a routine to manage the interrupt (key pressed or key released), this routine could, for example, get the pressed key from the keyboard controller and print the key to the screen. Once the character processing routine is completed, the interrupted job can be resumed.

#### What is the PIC?

The [PIC](http://en.wikipedia.org/wiki/Programmable_Interrupt_Controller) (Programmable interrupt controller)is a device that is used to combine several sources of interrupt onto one or more CPU lines, while allowing priority levels to be assigned to its interrupt outputs. When the device has multiple interrupt outputs to assert, it asserts them in the order of their relative priority.

The best known PIC is the 8259A, each 8259A can handle 8 devices but most computers have two controllers: one master and one slave, this allows the computer to manage interrupts from 14 devices.

In this chapter, we will need to program this controller to initialize and mask interrupts.

#### What is the IDT?

> The Interrupt Descriptor Table (IDT) is a data structure used by the x86 architecture to implement an interrupt vector table. The IDT is used by the processor to determine the correct response to interrupts and exceptions.

Our kernel is going to use the IDT to define the different functions to be executed when an interrupt occurred.

Like the GDT, the IDT is loaded using the LIDTL assembly instruction. It expects the location of a IDT description structure:

```cpp
struct idtr {
	u16 limite;
	u32 base;
} __attribute__ ((packed));
```

The IDT table is composed of IDT segments with the following structure:

```cpp
struct idtdesc {
	u16 offset0_15;
	u16 select;
	u16 type;
	u16 offset16_31;
} __attribute__ ((packed));
```

**Caution:** the directive ```__attribute__ ((packed))``` signal to gcc that the structure should use as little memory as possible. Without this directive, gcc includes some bytes to optimize the memory alignment and the access during execution.

Now we need to define our IDT table and then load it using LIDTL. The IDT table can be stored wherever we want in memory, its address should just be signaled to the process using the IDTR registry.

Here is a table of common interrupts (Maskable hardware interrupt are called IRQ):


| IRQ   |         Description        |
|:-----:| -------------------------- |
| 0 | Programmable Interrupt Timer Interrupt |
| 1 | Keyboard Interrupt |
| 2 | Cascade (used internally by the two PICs. never raised) |
| 3 | COM2 (if enabled) |
| 4 | COM1 (if enabled) |
| 5 | LPT2 (if enabled) |
| 6 | Floppy Disk |
| 7 | LPT1 |
| 8 | CMOS real-time clock (if enabled) |
| 9 | Free for peripherals / legacy SCSI / NIC |
| 10 | Free for peripherals / SCSI / NIC |
| 11 | Free for peripherals / SCSI / NIC |
| 12 | PS2 Mouse |
| 13 | FPU / Coprocessor / Inter-processor |
| 14 | Primary ATA Hard Disk |
| 15 | Secondary ATA Hard Disk |

#### How to initialize the interrupts?

This is a simple method to define an IDT segment

```cpp
void init_idt_desc(u16 select, u32 offset, u16 type, struct idtdesc *desc)
{
	desc->offset0_15 = (offset & 0xffff);
	desc->select = select;
	desc->type = type;
	desc->offset16_31 = (offset & 0xffff0000) >> 16;
	return;
}
```

And we can now initialize the interupts:

```cpp
#define IDTBASE	0x00000000
#define IDTSIZE 0xFF
idtr kidtr;
```


```cpp
void init_idt(void)
{
	/* Init irq */
	int i;
	for (i = 0; i < IDTSIZE; i++)
		init_idt_desc(0x08, (u32)_asm_schedule, INTGATE, &kidt[i]); //

	/* Vectors  0 -> 31 are for exceptions */
	init_idt_desc(0x08, (u32) _asm_exc_GP, INTGATE, &kidt[13]);		/* #GP */
	init_idt_desc(0x08, (u32) _asm_exc_PF, INTGATE, &kidt[14]);     /* #PF */

	init_idt_desc(0x08, (u32) _asm_schedule, INTGATE, &kidt[32]);
	init_idt_desc(0x08, (u32) _asm_int_1, INTGATE, &kidt[33]);

	init_idt_desc(0x08, (u32) _asm_syscalls, TRAPGATE, &kidt[48]);
	init_idt_desc(0x08, (u32) _asm_syscalls, TRAPGATE, &kidt[128]); //48

	kidtr.limite = IDTSIZE * 8;
	kidtr.base = IDTBASE;


	/* Copy the IDT to the memory */
	memcpy((char *) kidtr.base, (char *) kidt, kidtr.limite);

	/* Load the IDTR registry */
	asm("lidtl (kidtr)");
}
```

After intialization of our IDT, we need to activate interrupts by configuring the PIC. The following function will configure the two PICs by writting in their internal registries using the output ports of the processor ```io.outb```. We configure the PICs using the ports:

* Master PIC: 0x20 and 0x21
* Slave PIC: 0xA0 and 0xA1

For a PIC, there are 2 types of registries:

* ICW (Initialization Command Word): reinit the controller
* OCW (Operation Control Word): configure the controller once initialized (used to mask/unmask the interrupts)

```cpp
void init_pic(void)
{
	/* Initialization of ICW1 */
	io.outb(0x20, 0x11);
	io.outb(0xA0, 0x11);

	/* Initialization of ICW2 */
	io.outb(0x21, 0x20);	/* start vector = 32 */
	io.outb(0xA1, 0x70);	/* start vector = 96 */

	/* Initialization of ICW3 */
	io.outb(0x21, 0x04);
	io.outb(0xA1, 0x02);

	/* Initialization of ICW4 */
	io.outb(0x21, 0x01);
	io.outb(0xA1, 0x01);

	/* mask interrupts */
	io.outb(0x21, 0x0);
	io.outb(0xA1, 0x0);
}
```

#### PIC ICW configurations details

The registries have to be configured in order.

**ICW1 (port 0x20 / port 0xA0)**
```
|0|0|0|1|x|0|x|x|
         |   | +--- with ICW4 (1) or without (0)
         |   +----- one controller (1), or cascade (0)
         +--------- triggering by level (level) (1) or by edge (edge) (0)
```

**ICW2 (port 0x21 / port 0xA1)**
```
|x|x|x|x|x|0|0|0|
 | | | | |
 +----------------- base address for interrupts vectors
```

**ICW2 (port 0x21 / port 0xA1)**

For the master:
```
|x|x|x|x|x|x|x|x|
 | | | | | | | |
 +------------------ slave controller connected to the port yes (1), or no (0)
```

For the slave:
```
|0|0|0|0|0|x|x|x|  pour l'esclave
           | | |
           +-------- Slave ID which is equal to the master port
```

**ICW4 (port 0x21 / port 0xA1)**

It is used to define in which mode the controller should work.

```
|0|0|0|x|x|x|x|1|
       | | | +------ mode "automatic end of interrupt" AEOI (1)
       | | +-------- mode buffered slave (0) or master (1)
       | +---------- mode buffered (1)
       +------------ mode "fully nested" (1)
```

#### Why do idt segments offset our ASM functions?

You should have noticed that when I'm initializing our IDT segments, I'm using offsets to segment the code in Assembly. The different functions are defined in [x86int.asm](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/x86int.asm) and are of the following scheme:

```asm
%macro	SAVE_REGS 0
	pushad
	push ds
	push es
	push fs
	push gs
	push ebx
	mov bx,0x10
	mov ds,bx
	pop ebx
%endmacro

%macro	RESTORE_REGS 0
	pop gs
	pop fs
	pop es
	pop ds
	popad
%endmacro

%macro	INTERRUPT 1
global _asm_int_%1
_asm_int_%1:
	SAVE_REGS
	push %1
	call isr_default_int
	pop eax	;;a enlever sinon
	mov al,0x20
	out 0x20,al
	RESTORE_REGS
	iret
%endmacro
```

These macros will be used to define the interrupt segment that will prevent corruption of the different registries, it will be very useful for multitasking.


================================================
FILE: Chapter-8/README.md
================================================
## Chapter 8: Theory: physical and virtual memory

In the chapter related to the GDT, we saw that using segmentation a physical memory address is calculated using a segment selector and an offset.

In this chapter, we are going to implement paging, paging will translate a linear address from segmentation into a physical address.

#### Why do we need paging?

Paging will allow our kernel to:

* use the hard-drive as a memory and not be limited by the machine ram memory limit
* to have a unique memory space for each process
* to allow and unallow memory space in a dynamic way

In a paged system, each process may execute in its own 4gb area of memory, without any chance of effecting any other process's memory, or the kernel's. It simplifies multitasking.

![Processes memories](./processes.png)

#### How does it work?

The translation of a linear address to a physical address is done in multiple steps:

1. The processor use the registry `CR3` to know the physical address of the pages directory.
2. The first 10 bits of the linear address represent an offset (between 0 and 1023), pointing to an entry in the pages directory. This entry contains the physical address of a pages table.
3. the next 10 bits of the linear address represent an offset, pointing to an entry in the pages table. This entry is pointing to a 4ko page.
4. The last 12 bits of the linear address represent an offset (between 0 and 4095), which indicates the position in the 4ko page.

![Address translation](./paging_memory.png)

#### Format for pages table and directory

The two types of entries (table and directory) look like the same. Only the field in gray will be used in our OS.

![Page directory entry](./page_directory_entry.png)

![Page table entry](./page_table_entry.png)

* `P`: indicate if the page or table is in physical memory
* `R/W`: indicate if the page or table is accessible in writting (equals 1)
* `U/S`: equals 1 to allow access to non-preferred tasks
* `A`: indicate if the page or table was accessed
* `D`: (only for pages table) indicate if the page was written
* `PS` (only for pages directory) indicate the size of pages:
    * 0 = 4kb
    * 1 = 4mb

**Note:** Physical addresses in the pages diretcory or pages table are written using 20 bits because these addresses are aligned on 4kb, so the last 12bits should be equal to 0.

* A pages directory or pages table used 1024*4 = 4096 bytes = 4k
* A pages table can address 1024 * 4k = 4 Mb
* A pages directory can address 1024 * (1024 * 4k) = 4 Gb

#### How to enable pagination?

To enable pagination, we just need to set bit 31 of the `CR0`registry to 1:

```asm
asm("  mov %%cr0, %%eax; \
       or %1, %%eax;     \
       mov %%eax, %%cr0" \
       :: "i"(0x80000000));
```

But before, we need to initialize our pages directory with at least one pages table.

#### Identity Mapping

With the identity mapping model, the page will apply only to the kernel as the first 4 MB of virtual memory coincide with the first 4 MB of physical memory:

![Identity Mapping](identitymapping.png)

This model is simple: the first virtual memory page coincide to the first page in physical memory, the second page coincide to the second page on physical memory and so on ...








================================================
FILE: LICENSE
================================================
Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2014 Samy Pessé

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
How to Make a Computer Operating System
=======================================

Online book about how to write a computer operating system in C/C++ from scratch.

**Caution**: This repository is a remake of my old course. It was written several years ago [as one of my first projects when I was in High School](https://github.com/SamyPesse/devos), I'm still refactoring some parts. The original course was in French and I'm not an English native. I'm going to continue and improve this course in my free-time.

**Book**: An online version is available at [http://samypesse.gitbooks.io/how-to-create-an-operating-system/](http://samypesse.gitbooks.io/how-to-create-an-operating-system/) (PDF, Mobi and ePub). It was generated using [GitBook](https://www.gitbook.com/).

**Source Code**: All the system source code will be stored in the [src](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/tree/master/src) directory. Each step will contain links to the different related files.

**Contributions**: This course is open to contributions, feel free to signal errors with issues or directly correct the errors with pull-requests.

**Questions**: Feel free to ask any questions by adding issues or commenting sections.

You can follow me on Twitter [@SamyPesse](https://twitter.com/SamyPesse) or [GitHub](https://github.com/SamyPesse).

### What kind of OS are we building?

The goal is to build a very simple UNIX-based operating system in C++, not just a "proof-of-concept". The OS should be able to boot, start a userland shell, and be extensible.

![Screen](./preview.png)


================================================
FILE: SUMMARY.md
================================================
# Summary

* [Introduction](README.md)
* [Introduction about the x86 architecture and about our OS](Chapter-1/README.md)
* [Setup the development environment](Chapter-2/README.md)
* [First boot with GRUB](Chapter-3/README.md)
* [Backbone of the OS and C++ runtime](Chapter-4/README.md)
* [Base classes for managing x86 architecture](Chapter-5/README.md)
* [GDT](Chapter-6/README.md)
* [IDT and interrupts](Chapter-7/README.md)
* [Theory: physical and virtual memory](Chapter-8/README.md)
* [Memory management: physical and virtual](chapter9/README.md)
* Process management and multitasking
* External program execution: ELF files
* Userland and syscalls
* Modular drivers
* Some basics modules: console, keyboard
* IDE Hard disks
* DOS Partitions
* EXT2 read-only filesystems
* Standard C library (libC)
* UNIX basic tools: sh, cat
* Lua interpreter



================================================
FILE: chapter9/README.md
================================================
# Memory management: physical and virtual

The kernel knows the size of the physical memory available thanks to [GRUB](../Chapter-3/README.md).

In our implementation, the first 8 megabytes of physical memory will be reserved for use by the kernel and will contain:

- The kernel
- GDT, IDT et TSS
- Kernel Stack
- Some space reserved to hardware (video memory, ...)
- Page directory and pages table for the kernel

The rest of the physical memory is freely available to the kernel and applications.

![Physical Memory](physicalmemory.png)


### Virtual Memory Mapping

The address space between the beginning of memory and `0x40000000` address is the kernel space, while the space between the address `0x40000000` and the end of the memory corresponds to user space:

![Virtual Memory](virtualmemory.png)

The kernel space in virtual memory, which is using 1Gb of virtual memory, is common to all tasks (kernel and user).

This is implemented by pointing the first 256 entries of the task page directory to the kernel page directory (In [vmm.cc](https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System/blob/master/src/kernel/arch/x86/vmm.cc#L204)):

```cpp
/* 
 * Kernel Space. v_addr < USER_OFFSET are addressed by the kernel pages table
 */
for (i=0; i<256; i++) 
    pdir[i] = pd0[i];
```

================================================
FILE: src/Makefile
================================================
SDKDIR=./sdk

help:
	@echo "Makefile for Building Dev Operating System."
	@echo "Usage: make [ all | clean | help | build | run] " 
	@echo ""
	@echo

all: 
	@echo "Building Kernel"
	make -C ./kernel
	@echo "Building SDK"
	make -C ./sdk
	@echo "Building Userland"
	make -C ./userland
	

build:
	zip -r devos-$(VERSION).zip ./


run:
	@echo "Running Dev Operating System."
	cd ./sdk && sudo bash ./diskimage.sh
	cd ./sdk && ./qemu.sh

clean:
	make -C ./kernel clean
	make -C ./userland clean


================================================
FILE: src/Vagrantfile
================================================
# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # All Vagrant configuration is done here. The most common configuration
  # options are documented and commented below. For a complete reference,
  # please see the online documentation at vagrantup.com.

  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "lucid32"

  # The url from where the 'config.vm.box' box will be fetched if it
  # doesn't already exist on the user's system.
  config.vm.box_url = "http://files.vagrantup.com/lucid32.box"

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # config.vm.network :forwarded_port, guest: 80, host: 8080

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  # config.vm.network :private_network, ip: "192.168.33.10"

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  # config.vm.network :public_network

  # If true, then any SSH connections made will enable agent forwarding.
  # Default value: false
  # config.ssh.forward_agent = true

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  # config.vm.provider :virtualbox do |vb|
  #   # Don't boot with headless mode
  #   vb.gui = true
  #
  #   # Use VBoxManage to customize the VM. For example to change memory:
  #   vb.customize ["modifyvm", :id, "--memory", "1024"]
  # end
  #
  # View the documentation for the provider you're using for more
  # information on available options.

  # Enable provisioning with Puppet stand alone.  Puppet manifests
  # are contained in a directory path relative to this Vagrantfile.
  # You will need to create the manifests directory and a manifest in
  # the file base.pp in the manifests_path directory.
  #
  # An example Puppet manifest to provision the message of the day:
  #
  # # group { "puppet":
  # #   ensure => "present",
  # # }
  # #
  # # File { owner => 0, group => 0, mode => 0644 }
  # #
  # # file { '/etc/motd':
  # #   content => "Welcome to your Vagrant-built virtual machine!
  # #               Managed by Puppet.\n"
  # # }
  #
  # config.vm.provision :puppet do |puppet|
  #   puppet.manifests_path = "manifests"
  #   puppet.manifest_file  = "init.pp"
  # end

  # Enable provisioning with chef solo, specifying a cookbooks path, roles
  # path, and data_bags path (all relative to this Vagrantfile), and adding
  # some recipes and/or roles.
  #
  # config.vm.provision :chef_solo do |chef|
  #   chef.cookbooks_path = "../my-recipes/cookbooks"
  #   chef.roles_path = "../my-recipes/roles"
  #   chef.data_bags_path = "../my-recipes/data_bags"
  #   chef.add_recipe "mysql"
  #   chef.add_role "web"
  #
  #   # You may also specify custom JSON attributes:
  #   chef.json = { :mysql_password => "foo" }
  # end

  $script = %Q{
    sudo apt-get update
    sudo apt-get install nasm make build-essential grub qemu zip -y
  }

  
  config.vm.provision :shell, :inline => $script
  

  # Enable provisioning with chef server, specifying the chef server URL,
  # and the path to the validation key (relative to this Vagrantfile).
  #
  # The Opscode Platform uses HTTPS. Substitute your organization for
  # ORGNAME in the URL and validation key.
  #
  # If you have your own Chef Server, use the appropriate URL, which may be
  # HTTP instead of HTTPS depending on your configuration. Also change the
  # validation key to validation.pem.
  #
  # config.vm.provision :chef_client do |chef|
  #   chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
  #   chef.validation_key_path = "ORGNAME-validator.pem"
  # end
  #
  # If you're using the Opscode platform, your validator client is
  # ORGNAME-validator, replacing ORGNAME with your organization name.
  #
  # If you have your own Chef Server, the default validation client name is
  # chef-validator, unless you changed the configuration.
  #
  #   chef.validation_client_name = "ORGNAME-validator"
end


================================================
FILE: src/kernel/Makefile
================================================
ARCH=x86
KERNEL=kernel.elf
SDKDIR=../sdk
INCDIR= -I ./ -I ./modules -I ./core -I ./arch/$(ARCH)


include ./arch/$(ARCH)/config.make

include ./runtime/Makefile
include ./core/Makefile
include ./modules/Makefile
include ./arch/$(ARCH)/Makefile

FLAG :=$(FLAG) -D__$(ARCH)__
PLATFORMS= `find ./arch/ -type d | sed "s/.*\///" | sort`


all: $(KERNEL)

$(KERNEL): $(OBJS)
	$(LD) $(LDFLAG) -o $@ $^ 
	cp $(KERNEL) $(SDKDIR)/bootdisk/
	
help:
	@echo "Makefile for Kernel."
	@echo "Please see COPYING for licensing information."
	@echo "Output should be: "$(KERNEL)
	@echo "Usage: make [ all | clean] " 
	@echo "Currently supported platforms:"
	@echo $(PLATFORMS)
	@echo

tosdk:
	cp $(KERNEL) $(SDKDIR)/disk/

install:
	sudo cp $(KERNEL) /boot/
	
debug:
	$(NM) -n $(KERNEL)

	
hinfo:
	$(OBJDUMP) -f $(KERNEL)
	
dasm:
	$(OBJDUMP) -d $(KERNEL) > dasm.txt
	
				
run:
	cd $(SDKDIR) &&	sh ./diskimage.sh
	cd $(SDKDIR) &&	sh ./qemu.sh
	
geniso:
	cd $(SDKDIR) &&	sh ./cdrom.sh

%.o: %.cc
	$(SC) $(FLAG) -c $< -o  $@
	
%.o: %.S
	$(SC) $(FLAG) -c $< -o  $@
	
%.o: %.asm
	$(ASM) $(ASMFLAG)  -c $< -o  $@


clean:
	rm -f $(OBJS)  $(KERNEL) dasm.txt
	
	



================================================
FILE: src/kernel/arch/x86/Makefile
================================================
OBJS:= arch/$(ARCH)/start.o  $(OBJS) arch/$(ARCH)/alloc.o arch/$(ARCH)/architecture.o \
	arch/$(ARCH)/io.o arch/$(ARCH)/vmm.o arch/$(ARCH)/x86.o arch/$(ARCH)/switch.o arch/$(ARCH)/x86int.o


================================================
FILE: src/kernel/arch/x86/alloc.cc
================================================
#include <os.h>

extern "C" {
		
	/* change memory segment size */
	void *ksbrk(int n)
	{
		struct kmalloc_header *chunk;
		char *p_addr;
		int i;

		if ((kern_heap + (n * PAGESIZE)) > (char *) KERN_HEAP_LIM) {
			io.print
			    ("PANIC: ksbrk(): no virtual memory left for kernel heap !\n");
			return (char *) -1;
		}

		chunk = (struct kmalloc_header *) kern_heap;

		/* Allocation d'une page libre */
		for (i = 0; i < n; i++) {
			p_addr = get_page_frame();
			if ((int)(p_addr) < 0) {
				io.print
				    ("PANIC: ksbrk(): no free page frame available !\n");
				return (char *) -1;
			}

			/* Ajout dans le repertoire de pages */
			pd0_add_page(kern_heap, p_addr, 0);

			kern_heap += PAGESIZE;
		}

		/* Marquage pour kmalloc */
		chunk->size = PAGESIZE * n;
		chunk->used = 0;

		return chunk;
	}

	/* allocate memory block */
	void *kmalloc(unsigned long size)
	{
		if (size==0)
			return 0;
			
		unsigned long realsize;	/* taille totale de l'enregistrement */
		struct kmalloc_header *chunk, *other;

		if ((realsize =
		     sizeof(struct kmalloc_header) + size) < KMALLOC_MINSIZE)
			realsize = KMALLOC_MINSIZE;

		/* 
		 * On recherche un bloc libre de 'size' octets en parcourant le HEAP
		 * kernel a partir du debut
		 */
		chunk = (struct kmalloc_header *) KERN_HEAP;
		while (chunk->used || chunk->size < realsize) {
			if (chunk->size == 0) {
				io.print
				    ("\nPANIC: kmalloc(): corrupted chunk on %x with null size (heap %x) !\nSystem halted\n",
				     chunk, kern_heap);
					 //error
					 asm("hlt");
					 return 0;
			}

			chunk =
			    (struct kmalloc_header *) ((char *) chunk +
						       chunk->size);

			if (chunk == (struct kmalloc_header *) kern_heap) {
				if ((int)(ksbrk((realsize / PAGESIZE) + 1)) < 0) {
					io.print
					    ("\nPANIC: kmalloc(): no memory left for kernel !\nSystem halted\n");
					 asm("hlt");
					return 0;
				}
			} else if (chunk > (struct kmalloc_header *) kern_heap) {
				io.print
				    ("\nPANIC: kmalloc(): chunk on %x while heap limit is on %x !\nSystem halted\n",
				     chunk, kern_heap);
				 asm("hlt");
				return 0;
			}
		}

		/* 
		 * Found free block with size >= 'size'
		 * We limit size block
		 */
		if (chunk->size - realsize < KMALLOC_MINSIZE)
			chunk->used = 1;
		else {
			other =
			    (struct kmalloc_header *) ((char *) chunk + realsize);
			other->size = chunk->size - realsize;
			other->used = 0;

			chunk->size = realsize;
			chunk->used = 1;
		}

		kmalloc_used += realsize;

		/* Return a pointer to the memory area */
		return (char *) chunk + sizeof(struct kmalloc_header);
	}

	/* free memory block */
	void kfree(void *v_addr)
	{
		if (v_addr==(void*)0)
			return;
			
		struct kmalloc_header *chunk, *other;

		/* On libere le bloc alloue */
		chunk =
		    (struct kmalloc_header *) ((u32)v_addr -
					       sizeof(struct kmalloc_header));
		chunk->used = 0;

		kmalloc_used -= chunk->size;

		/* 
		 * Merge free block with next free block
		 */
		while ((other =
			(struct kmalloc_header *) ((char *) chunk + chunk->size))
		       && other < (struct kmalloc_header *) kern_heap
		       && other->used == 0)
			chunk->size += other->size;
	}
}


================================================
FILE: src/kernel/arch/x86/architecture.cc
================================================
#include <os.h>
#include <x86.h>

/* Stack pointer */
extern u32 *		stack_ptr;

/* Current cpu name */
static char cpu_name[512] = "x86-noname";


/* Detect the type of processor */
char* Architecture::detect(){
	cpu_vendor_name(cpu_name);
	return cpu_name;
}

/* Start and initialize the architecture */
void Architecture::init(){
	 io.print("Architecture x86, cpu=%s \n", detect());
	
	 io.print("Loading GDT \n");
		 init_gdt();
		 asm("	movw $0x18, %%ax \n \
			movw %%ax, %%ss \n \
			movl %0, %%esp"::"i" (KERN_STACK));
		
	 io.print("Loading IDT \n");
		 init_idt();
		
		
	 io.print("Configure PIC \n");
		 init_pic();
	 
	 io.print("Loading Task Register \n");
		 asm("	movw $0x38, %ax; ltr %ax");	 
}

/* Initialise the list of processus */
void Architecture::initProc(){
	firstProc= new Process("kernel");
	firstProc->setState(ZOMBIE);
	firstProc->addFile(fsm.path("/dev/tty"),0);
	firstProc->addFile(fsm.path("/dev/tty"),0);
	firstProc->addFile(fsm.path("/dev/tty"),0);
	
	
	plist=firstProc;
	pcurrent=firstProc; 
	pcurrent->setPNext(NULL);
	process_st* current=pcurrent->getPInfo();
	current->regs.cr3 = (u32) pd0;
}

/* Reboot the computer */
void Architecture::reboot(){
    u8 good = 0x02;
    while ((good & 0x02) != 0)
        good = io.inb(0x64);
    io.outb(0x64, 0xFE);
}

/* Shutdown the computer */
void Architecture::shutdown(){
	// todo
}

/* Install a interruption handler */
void Architecture::install_irq(int_handler h){
	// todo
}

/* Add a process to the scheduler */
void Architecture::addProcess(Process* p){
	p->setPNext(plist);
	plist=p;
}

/* Fork a process */
int Architecture::fork(process_st* info,process_st* father){
	memcpy((char*)info,(char*)father,sizeof(process_st));
	info->pd = pd_copy(father->pd);
}

/* Initialise a new process */
int Architecture::createProc(process_st* info, char* file, int argc, char** argv){
	page *kstack;
	process_st *previous;
	process_st *current;

	char **param, **uparam;
	u32 stackp;
	u32 e_entry; 

	
	int pid;
	int i;

	pid = 1;

	info->pid = pid;
	
	if (argc) {
		param = (char**) kmalloc(sizeof(char*) * (argc+1));
		for (i=0 ; i<argc ; i++) {
			param[i] = (char*) kmalloc(strlen(argv[i]) + 1);
			strcpy(param[i], argv[i]);
		}
		param[i] = 0;
	}
	
	info->pd = pd_create();


	INIT_LIST_HEAD(&(info->pglist));


	previous = arch.pcurrent->getPInfo();
	current=info;
	
	asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"((info->pd)->base->p_addr));
	
	e_entry = (u32) load_elf(file,info);

	if (e_entry == 0) {	
		for (i=0 ; i<argc ; i++) 
			kfree(param[i]);
		kfree(param);
		arch.pcurrent = (Process*) previous->vinfo;
		current=arch.pcurrent->getPInfo();
		asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (current->regs.cr3));
		pd_destroy(info->pd);
		return -1;
	}


	stackp = USER_STACK - 16;


	if (argc) {
		uparam = (char**) kmalloc(sizeof(char*) * argc);

		for (i=0 ; i<argc ; i++) {
			stackp -= (strlen(param[i]) + 1);
			strcpy((char*) stackp, param[i]);
			uparam[i] = (char*) stackp;
		}

		stackp &= 0xFFFFFFF0;	

		// Creation des arguments de main() : argc, argv[]... 
		stackp -= sizeof(char*);
		*((char**) stackp) = 0;

		for (i=argc-1 ; i>=0 ; i--) {		
			stackp -= sizeof(char*);
			*((char**) stackp) = uparam[i]; 
		}

		stackp -= sizeof(char*);	
		*((char**) stackp) = (char*) (stackp + 4); 

		stackp -= sizeof(char*);	
		*((int*) stackp) = argc; 

		stackp -= sizeof(char*);

		for (i=0 ; i<argc ; i++) 
			kfree(param[i]);

		kfree(param);
		kfree(uparam);
	}

	
	kstack = get_page_from_heap();


	// Initialise le reste des registres et des attributs 
	info->regs.ss = 0x33;
	info->regs.esp = stackp;
	info->regs.eflags = 0x0;
	info->regs.cs = 0x23;
	info->regs.eip = e_entry;
	info->regs.ds = 0x2B;
	info->regs.es = 0x2B;
	info->regs.fs = 0x2B;
	info->regs.gs = 0x2B;
	info->regs.cr3 = (u32) info->pd->base->p_addr;

	info->kstack.ss0 = 0x18;
	info->kstack.esp0 = (u32) kstack->v_addr + PAGESIZE - 16;

	info->regs.eax = 0;
	info->regs.ecx = 0;
	info->regs.edx = 0;
	info->regs.ebx = 0;

	info->regs.ebp = 0;
	info->regs.esi = 0;
	info->regs.edi = 0;

	info->b_heap = (char*) ((u32) info->e_bss & 0xFFFFF000) + PAGESIZE;
	info->e_heap = info->b_heap;

	info->signal = 0;
	for(i=0 ; i<32 ; i++)
		info->sigfn[i] = (char*) SIG_DFL;

	arch.pcurrent = (Process*) previous->vinfo;
	current=arch.pcurrent->getPInfo();
	asm("mov %0, %%eax ;mov %%eax, %%cr3":: "m"(current->regs.cr3));
	
	return 1;
}


// Destroy a process
void Architecture::destroy_process(Process* pp){
	disable_interrupt();
	
	u16 kss;
	u32 kesp;
	u32 accr3;
	list_head *p, *n;
	page *pg;
	process_st *proccurrent=(arch.pcurrent)->getPInfo();
	process_st *pidproc=pp->getPInfo();
	
	
	// Switch page to the process to destroy
	asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (pidproc->regs.cr3));

	
	// Free process memory:
	//  - pages used by the executable code
	//  - user stack
	//  - kernel stack
	//  - pages directory

	// Free process memory
	list_for_each_safe(p, n, &pidproc->pglist) {
		pg = list_entry(p, struct page, list);
		release_page_frame(pg->p_addr);
		list_del(p);
		kfree(pg);
	}
	
	release_page_from_heap((char *) ((u32)pidproc->kstack.esp0 & 0xFFFFF000));

	// Free pages directory
	asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"(pd0));

	pd_destroy(pidproc->pd);

	asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (proccurrent->regs.cr3));
	
	// Remove from the list
	if (plist==pp){
		plist=pp->getPNext();
	}
	else{
		Process* l=plist;
		Process*ol=plist;
		while (l!=NULL){
			
			if (l==pp){
				ol->setPNext(pp->getPNext());
			}
			
			ol=l;
			l=l->getPNext();
		}
	}
	
	enable_interrupt();
}


void Architecture::change_process_father(Process* pe, Process* pere){
	Process* p=plist;
	Process* pn=NULL;
	while (p!=NULL){
		pn=p->getPNext();
		if (p->getPParent()==pe){
			p->setPParent(pere);
		}
		
		p=pn;
	}
}


void Architecture::destroy_all_zombie(){
	Process* p=plist;
	Process* pn=NULL;
	while (p!=NULL){
		pn=p->getPNext();
		if (p->getState()==ZOMBIE && p->getPid()!=1){
			destroy_process(p);
			delete p;
		}
		
		p=pn;
	}
}

/* Set the syscall arguments */
void Architecture::setParam(u32 ret, u32 ret1, u32 ret2, u32 ret3,u32 ret4){
	ret_reg[0]=ret;
	ret_reg[1]=ret1;
	ret_reg[2]=ret2;
	ret_reg[3]=ret3;
	ret_reg[4]=ret4;
}

/* Enable the interruption */
void Architecture::enable_interrupt(){
	asm ("sti");
}

/* Disable the interruption */
void Architecture::disable_interrupt(){
	asm ("cli");
}

/* Get a syscall argument */
u32	Architecture::getArg(u32 n){
	if (n<5)
		return ret_reg[n];
	else
		return 0;
}

/* Set the return value of syscall */
void Architecture::setRet(u32 ret){
	stack_ptr[14] = ret;
}


================================================
FILE: src/kernel/arch/x86/architecture.h
================================================
#ifndef ARCH_H
#define ARCH_H

#include <runtime/types.h>

#include <process.h>


/** Processor architecture class **/
class Architecture
{
	public:
		/** architecture class functions **/
		void	init();			/* start the processor interface */
		void	reboot();		/* reboot the computer */
		void	shutdown();		/* shutdown the computer */
		char*	detect();		/* detect the type of processor */
		void	install_irq(int_handler h);	/* install a interruption handler */
		void	addProcess(Process* p);		/* add a process to the scheduler */
		void	enable_interrupt();		/* enable the interruption */
		void	disable_interrupt();	/* disable the interruption */
		int 	createProc(process_st* info,char* file,int argc,char** argv);	/* initialise a process */
		void	setParam(u32 ret,u32 ret1,u32 ret2, u32 ret3,u32 ret4);		/* set the syscall arguments */
		u32		getArg(u32 n);		/* get a syscall argument */
		void	setRet(u32 ret);	/* set the return value of syscall */
		void 	initProc();			/* initialise the list of processes */
		void	destroy_process(Process* pp);	/* destroy a processes */
		void	destroy_all_zombie();
		void	change_process_father(Process* p,Process* pere);
		int		fork(process_st* info,process_st* father);	/* fork a process */
		
		
		/** architecture public class attributes */
		Process*	pcurrent;		/* the current processes */
		Process*	plist;			/* the chain list of processes */
		
		
	private:
		/** architecture private attributes **/
		u32			ret_reg[5];
		Process* 	firstProc;
		
};

/** standart starting architecture interface **/
extern Architecture arch;

#endif


================================================
FILE: src/kernel/arch/x86/archprocess.h
================================================
#ifndef APROC_H
#define APROC_H

#include <runtime/types.h>

extern "C" {

#define KERNELMODE	0
#define USERMODE	1

	/** info processor structure for a process */
	struct process_st {
		int pid;

		struct {
			u32 eax, ecx, edx, ebx;
			u32 esp, ebp, esi, edi;
			u32 eip, eflags;
			u32 cs:16, ss:16, ds:16, es:16, fs:16, gs:16;
			u32 cr3;
		} regs __attribute__ ((packed));

		struct {
			u32 esp0;
			u16 ss0;
		} kstack __attribute__ ((packed));

		// Caution: with task switch
		struct page_directory *pd;	

		list_head pglist;

		char *b_exec;
		char *e_exec;
		char *b_bss;
		char *e_bss;
		char *b_heap;
		char *e_heap;

		u32 signal;
		void* sigfn[32];

		void*	vinfo;
		
	} __attribute__ ((packed));
}

#endif


================================================
FILE: src/kernel/arch/x86/config.make
================================================
LDFLAG= -melf_i386 -static  -L ./  -T ./arch/$(ARCH)/linker.ld
SC=g++
FLAG= $(INCDIR) -g -O2 -w -trigraphs -fno-builtin  -fno-exceptions -fno-stack-protector -O0 -m32  -fno-rtti -nostdlib -nodefaultlibs 
ASM=nasm  
ASMFLAG=-f elf -o
LD=ld
NM=nm
OBJDUMP=objdump


================================================
FILE: src/kernel/arch/x86/io.cc
================================================
#include <os.h>

Io* Io::last_io=&io;		/* definis la derniere io avant switch */
Io* Io::current_io=&io;		/* interface actuel (clavier redirig vers celle ci) */

/* Video memory */
char* Io::vidmem = (char*)RAMSCREEN;

/* Constructor */
Io::Io(){
	real_screen = (char*)RAMSCREEN;
}

/* Destructor */
Io::Io(u32 flag){
	real_screen=(char*)screen;
}

/* output byte */
void Io::outb(u32 ad,u8 v){
	asmv("outb %%al, %%dx" :: "d" (ad), "a" (v));;
}
/* output word */
void Io::outw(u32 ad,u16 v){
	asmv("outw %%ax, %%dx" :: "d" (ad), "a" (v));
}
/* output word */
void Io::outl(u32 ad,u32 v){
	asmv("outl %%eax, %%dx" : : "d" (ad), "a" (v));
}
/* input byte */
u8 Io::inb(u32 ad){
	u8 _v;       \
	asmv("inb %%dx, %%al" : "=a" (_v) : "d" (ad)); \
	return _v;
}
/* input word */
u16	Io::inw(u32 ad){
	u16 _v;			\
	asmv("inw %%dx, %%ax" : "=a" (_v) : "d" (ad));	\
	return _v;
}
/* input word */
u32	Io::inl(u32 ad){
	u32 _v;			\
	asmv("inl %%dx, %%eax" : "=a" (_v) : "d" (ad));	\
	return _v;
}

/* renvoie la position x du curseur */
u32	Io::getX(){
	return (u32)x;
}

/* renvoie la position y du curseur */
u32	Io::getY(){
	return (u32)y;
}

/* x86 scroll up screen */
void Io::scrollup(unsigned int n)
{
		unsigned char *video, *tmp;

		for (video = (unsigned char *) real_screen;
		     video < (unsigned char *) SCREENLIM; video += 2) {
			tmp = (unsigned char *) (video + n * 160);

			if (tmp < (unsigned char *) SCREENLIM) {
				*video = *tmp;
				*(video + 1) = *(tmp + 1);
			} else {
				*video = 0;
				*(video + 1) = 0x07;
			}
		}

		y -= n;
		if (y < 0)
			y = 0;
}

/* sauvegarde la memoire video */
void Io::save_screen(){
	memcpy(screen,(char*)RAMSCREEN,SIZESCREEN);
	real_screen=(char*)screen;
}

/* charge la memoire video */
void Io::load_screen(){
	memcpy((char*)RAMSCREEN,screen,SIZESCREEN);
	real_screen=(char*)RAMSCREEN;
}

/* switch tty io */
void Io::switchtty(){
	current_io->save_screen();
	load_screen();
	last_io=current_io;
	current_io=this;
}

/* put a byte on screen */
void Io::putc(char c){
	kattr = 0x07;
	unsigned char *video;
	video = (unsigned char *) (real_screen+ 2 * x + 160 * y);
	if (c == 10) {			
		x = 0;
		y++;
	} else if (c == 8) {	
		if (x) {
				*(video + 1) = 0x0;
			x--;
		}
	} else if (c == 9) {	
		x = x + 8 - (x % 8);
	} else if (c == 13) {	
		x = 0;
	} else {		
			*video = c;
			*(video + 1) = kattr;

		x++;
		if (x > 79) {
			x = 0;
			y++;
		}
	}
			if (y > 24)
				scrollup(y - 24);
}

/* change colors */
void Io::setColor(char fcol,char bcol){
	fcolor=fcol;
	bcolor=bcol;
}

/* change cursor position */
void Io::setXY(char xc,char yc){
	x=xc;
	y=yc;
}

/* clear screen */
void Io::clear(){
	x=0;
	y=0;
	memset((char*)RAMSCREEN,0,SIZESCREEN);
}

/* put a string in screen */
void Io::print(const char *s, ...){
	va_list ap;

	char buf[16];
	int i, j, size, buflen, neg;

	unsigned char c;
	int ival;
	unsigned int uival;

	va_start(ap, s);

	while ((c = *s++)) {
		size = 0;
		neg = 0;

		if (c == 0)
			break;
		else if (c == '%') {
			c = *s++;
			if (c >= '0' && c <= '9') {
				size = c - '0';
				c = *s++;
			}

			if (c == 'd') {
				ival = va_arg(ap, int);
				if (ival < 0) {
					uival = 0 - ival;
					neg++;
				} else
					uival = ival;
				itoa(buf, uival, 10);

				buflen = strlen(buf);
				if (buflen < size)
					for (i = size, j = buflen; i >= 0;
					     i--, j--)
						buf[i] =
						    (j >=
						     0) ? buf[j] : '0';

				if (neg)
					print("-%s", buf);
				else
					print(buf);
			}
			 else if (c == 'u') {
				uival = va_arg(ap, int);
				itoa(buf, uival, 10);

				buflen = strlen(buf);
				if (buflen < size)
					for (i = size, j = buflen; i >= 0;
					     i--, j--)
						buf[i] =
						    (j >=
						     0) ? buf[j] : '0';

				print(buf);
			} else if (c == 'x' || c == 'X') {
				uival = va_arg(ap, int);
				itoa(buf, uival, 16);

				buflen = strlen(buf);
				if (buflen < size)
					for (i = size, j = buflen; i >= 0;
					     i--, j--)
						buf[i] =
						    (j >=
						     0) ? buf[j] : '0';

				print("0x%s", buf);
			} else if (c == 'p') {
				uival = va_arg(ap, int);
				itoa(buf, uival, 16);
				size = 8;

				buflen = strlen(buf);
				if (buflen < size)
					for (i = size, j = buflen; i >= 0;
					     i--, j--)
						buf[i] =
						    (j >=
						     0) ? buf[j] : '0';

				print("0x%s", buf);
			} else if (c == 's') {
				print((char *) va_arg(ap, int));
			} 
		} else
			putc(c);
	}

	return;
}

/* put a byte on the console */
void Io::putctty(char c){
	if (keystate==BUFFERED){
		if (c == 8) {		/* backspace */
			if (keypos>0) {
				inbuf[keypos--] = 0;
			}
		}
		else if (c == 10) {	/* newline */
			inbuf[keypos++] = c;
			inbuf[keypos] = 0; 
			inlock = 0;
			keypos = 0;
		}
		else {
			inbuf[keypos++] = c; 
		}
	}
	else if (keystate==GETCHAR){
		inbuf[0]=c;
		inbuf[1]=0;
		inlock = 0;
		keypos = 0;
	}
}

/* read a string in the console */
u32 Io::read(char* buf,u32 count){
	if (count>1){
		keystate=BUFFERED;
	}
	else{	//getchar
		keystate=GETCHAR;
	}
	asm("sti");
	inlock=1;
	while (inlock == 1);
	asm("cli");
	strncpy(buf,inbuf,count);
	return strlen(buf);
}

================================================
FILE: src/kernel/arch/x86/io.h
================================================

#ifndef IO_H
#define IO_H

#include <runtime/types.h>



#define RAMSCREEN 0xB8000	/* debut de la memoire video */
#define SIZESCREEN 0xFA0	/* 4000, nombres d'octets d'une page texte */
#define SCREENLIM 0xB8FA0

/** Input/output class **/
class Io
{
	public:
	
		Io();
		Io(u32 flag);
		
		/** standart io color **/
		enum Colour
		  {
			Black       =0,
			Blue        =1,
			Green       =2,
			Cyan        =3,
			Red         =4,
			Magenta     =5,
			Orange      =6,
			LightGrey   =7,
			DarkGrey    =8,
			LightBlue   =9,
			LightGreen  =10,
			LightCyan   =11,
			LightRed    =12,
			LightMagenta=13,
			Yellow      =14,
			White       =15
		  };

		/** io class functions **/
		void	outb(u32 ad,u8 v);		/* output byte */
		void	outw(u32 ad,u16 v);		/* output word */
		void	outl(u32 ad,u32 v);		/* output word */
		
		u8		inb(u32 ad);			/* input byte */
		u16		inw(u32 ad);			/* input word */
		u32		inl(u32 ad);			/* input word */
		
		void	putctty(char c);		/* put a byte on the console */
		
		u32 	read(char* buf,u32 count);	/* read a string in the console */
		void	putc(char c);				/* put a byte on screen */
		void	setColor(char fcol,char bcol);	/* change colors */
		void	setXY(char xc,char yc);			/* change cursor position */
		void	clear();				/* clear screen */
		void	print(const char *s, ...);	/* put a string in screen */
		
		u32		getX();
		u32		getY();
		
		
		void	switchtty();		/* change the io interface */	
		
		/** x86 functions **/
		void	scrollup(unsigned int n);
		void	save_screen();
		void	load_screen();
		
		enum ConsoleType {
			BUFFERED,
			GETCHAR
		};
		
		static Io*	current_io;
		static Io*	last_io;
		
	private:

	
	
		/** x86 private attributes **/
		char*	real_screen;
		char	screen[SIZESCREEN];
		
		char	inbuf[512];		/* console buffer */
		int		keypos;			/* console read position */
		int		inlock;			/* console state */
		int		keystate;		/* console type keyboard */
		
		
		char 	fcolor;			/* console foreground color */
		char	bcolor;			/* console background color */
		char	x;				/* console x position */
		char	y;				/* console y position */
		char kattr;				/* console attribut */
		static char*	vidmem;	/* screen video memory */
		
};

/** standart starting io interface **/
extern Io io;

#endif


================================================
FILE: src/kernel/arch/x86/linker.ld
================================================
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386)
ENTRY (_start)

SECTIONS{
    . = 0x00100000;

    .text :{
        *(.text)
    }

	.data ALIGN (0x1000) : {
	   start_ctors = .;
	   *(.ctor*)
	   end_ctors = .;
	   start_dtors = .;
	   *(.dtor*)
	   end_dtors = .;
	   *(.data)
	}


    .rodata ALIGN (0x1000) : {
        *(.rodata)
    }

    .data ALIGN (0x1000) : {
        *(.data)
    }

    .bss : {
        sbss = .;
        *(COMMON)
        *(.bss)
        ebss = .;
    }
}


================================================
FILE: src/kernel/arch/x86/start.asm
================================================
global _start, _kmain
extern kmain, start_ctors, end_ctors, start_dtors, end_dtors

    
%define MULTIBOOT_HEADER_MAGIC  0x1BADB002
%define MULTIBOOT_HEADER_FLAGS	0x00000003
%define CHECKSUM -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

;-- Entry point
_start:
	jmp start

;-- Multiboot header --
align 4

multiboot_header:
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd CHECKSUM     
;--/Multiboot header --

start:
	push ebx
	 
static_ctors_loop:
   mov ebx, start_ctors
   jmp .test
.body:
   call [ebx]
   add ebx,4
.test:
   cmp ebx, end_ctors
   jb .body
 
   call kmain                      ; call kernel proper
 
static_dtors_loop:
   mov ebx, start_dtors
   jmp .test
.body:
   call [ebx]
   add ebx,4
.test:
   cmp ebx, end_dtors
   jb .body
	
	cli ; stop interrupts
	hlt ; halt the CPU


================================================
FILE: src/kernel/arch/x86/switch.asm
================================================

global do_switch

do_switch:
	; recuper l'adresse de *current 
	mov esi, [esp]
	pop eax			; depile @current

	; prepare les registres
	push dword [esi+4]	; eax
	push dword [esi+8]	; ecx
	push dword [esi+12]	; edx
	push dword [esi+16]	; ebx
	push dword [esi+24]	; ebp
	push dword [esi+28]	; esi
	push dword [esi+32]	; edi
	push dword [esi+48]	; ds
	push dword [esi+50]	; es
	push dword [esi+52]	; fs
	push dword [esi+54]	; gs

	; enleve le mask du PIC
	mov al, 0x20
	out 0x20, al

	; charge table des pages
	mov eax, [esi+56]
	mov cr3, eax

	; charge les registres
	pop gs
	pop fs
	pop es
	pop ds
	pop edi
	pop esi
	pop ebp
	pop ebx
	pop edx
	pop ecx
	pop eax

	; retourne 
	iret



================================================
FILE: src/kernel/arch/x86/vmm.cc
================================================
#include <os.h>

extern "C" {
	char *kern_heap;
	list_head kern_free_vm;
	u32 *pd0 = (u32 *) KERN_PDIR;			/* kernel page directory */
	char *pg0 = (char *) 0;					/* kernel page 0 (4MB) */
	char *pg1 = (char *) KERN_PG_1;			/* kernel page 1 (4MB) 0x400000*/
	char *pg1_end = (char *) KERN_PG_1_LIM;	/* limite de la page 1 0x800000*/
	u8 mem_bitmap[RAM_MAXPAGE / 8];			/* bitmap allocation de pages (1 Go) */

	u32 kmalloc_used = 0;
	
	
	/*
	 * Parcours le bitmap a la recherche d'une page libre et la marque
	 * comme utilisee avant de retourner son adresse physique.
	 */
	char* get_page_frame(void)
	{
		int byte, bit;
		int page = -1;

		for (byte = 0; byte < RAM_MAXPAGE / 8; byte++)
			if (mem_bitmap[byte] != 0xFF)
				for (bit = 0; bit < 8; bit++)
					if (!(mem_bitmap[byte] & (1 << bit))) {
						page = 8 * byte + bit;
						set_page_frame_used(page);
						return (char *) (page * PAGESIZE);
					}
		return (char *) -1;
	}


	/* 
	 * Recherche une page virtuelle libre dans l'espace d'adresses virtuelles du
	 * noyau. La fonction demande ensuite une page physique libre a associer.
	 * NOTE: ces pages sont dans l'espace d'adressage du noyau. Celui-ci est mis a
	 * jour.
	 */
	page* get_page_from_heap(void)
	{
		page *pg;
		vm_area *area;
		char *v_addr, *p_addr;

		/* Prend une page physique libre */
		p_addr = get_page_frame();
		if ((int)(p_addr) < 0) {
			io.print ("PANIC: get_page_from_heap(): no page frame available. System halted !\n");
		}

		/* Verifie si il y a une page virtuelle libre */
		if (list_empty(&kern_free_vm)) {
			io.print ("PANIC: get_page_from_heap(): not memory left in page heap. System halted !\n");
		}

		/* Prend la premiere page virtuelle libre de disponible */
		area = list_first_entry(&kern_free_vm, vm_area, list);
		v_addr = area->vm_start;

		/* Met a jour la liste de pages libres dans l'espace virtuel du noyau */
		area->vm_start += PAGESIZE;
		if (area->vm_start == area->vm_end) {
			list_del(&area->list);
			kfree(area);
		}

		/* Met a jour l'espace d'adressage du noyau */
		pd0_add_page(v_addr, p_addr, 0);

		/* Renvoie la page */
		pg = (page*) kmalloc(sizeof(page));
		pg->v_addr = v_addr;
		pg->p_addr = p_addr;
		pg->list.next = 0;
		pg->list.prev = 0;

		return pg;
	}

	int release_page_from_heap(char *v_addr)
	{
		struct vm_area *next_area, *prev_area, *new_area;
		char *p_addr;

		/* Retrouve la page frame associee a v_addr et la libere */
		p_addr = get_p_addr(v_addr);
		if (p_addr) {
			release_page_frame(p_addr);
		}
		else {
			io.print("WARNING: release_page_from_heap(): no page frame associated with v_addr %x\n", v_addr);
			return 1;
		}

		/* Met a jour le repertoire de pages */
		pd_remove_page(v_addr);

		/* Met a jour la liste d'adresses virtuelles libres */
		list_for_each_entry(next_area, &kern_free_vm, list) {
			if (next_area->vm_start > v_addr)
				break;
		}

		prev_area = list_entry(next_area->list.prev, struct vm_area, list);
		
		if (prev_area->vm_end == v_addr) {
			prev_area->vm_end += PAGESIZE;
			if (prev_area->vm_end == next_area->vm_start) {
				prev_area->vm_end = next_area->vm_end;
				list_del(&next_area->list);
				kfree(next_area);
			}
		}
		else if (next_area->vm_start == v_addr + PAGESIZE) {
			next_area->vm_start = v_addr;
		}
		else if (next_area->vm_start > v_addr + PAGESIZE) {
			new_area = (struct vm_area*) kmalloc(sizeof(struct vm_area));
			new_area->vm_start = v_addr;
			new_area->vm_end = v_addr + PAGESIZE;
			list_add(&new_area->list, &prev_area->list);
		}
		else {
			io.print ("\nPANIC: release_page_from_heap(): corrupted linked list. System halted !\n");
			asm("hlt");
		}

		return 0;
	}




	/* 
	 * Initialise le bitmap memoire et cree le repertoire de pages du kernel.
	 * Utilise un identity mapping tel que vaddr = paddr sur 4Mo 
	 */
	void Memory_init(u32 high_mem)
	{
		int pg, pg_limit;
		unsigned long i;
		struct vm_area *p;
		struct vm_area *pm;

		/* Numero de la derniere page */
		pg_limit = (high_mem * 1024) / PAGESIZE;

		/* Initialisation du bitmap de pages physiques */
		for (pg = 0; pg < pg_limit / 8; pg++)
			mem_bitmap[pg] = 0;

		for (pg = pg_limit / 8; pg < RAM_MAXPAGE / 8; pg++)
			mem_bitmap[pg] = 0xFF;

		/* Pages reservees pour le noyau */
		for (pg = PAGE(0x0); pg < (int)(PAGE((u32) pg1_end)); pg++) {
			set_page_frame_used(pg);
		}

		/* Initialisation du repertoire de pages */
		pd0[0] = ((u32) pg0 | (PG_PRESENT | PG_WRITE | PG_4MB));
		pd0[1] = ((u32) pg1 | (PG_PRESENT | PG_WRITE | PG_4MB));
		for (i = 2; i < 1023; i++)
			pd0[i] =
			    ((u32) pg1 + PAGESIZE * i) | (PG_PRESENT | PG_WRITE);

		// Page table mirroring magic trick ! 
		pd0[1023] = ((u32) pd0 | (PG_PRESENT | PG_WRITE));


		/* Passe en mode pagination */
		asm("	mov %0, %%eax \n \
			mov %%eax, %%cr3 \n \
			mov %%cr4, %%eax \n \
			or %2, %%eax \n \
			mov %%eax, %%cr4 \n \
			mov %%cr0, %%eax \n \
			or %1, %%eax \n \
			mov %%eax, %%cr0"::"m"(pd0), "i"(PAGING_FLAG), "i"(PSE_FLAG));

		
		/* Initialisation du heap du noyau utilise par kmalloc */
		kern_heap = (char *) KERN_HEAP;
		ksbrk(1);

		/* Initialisation de la liste d'adresses virtuelles libres */
		p = (struct vm_area*) kmalloc(sizeof(struct vm_area));
		p->vm_start = (char*) KERN_PG_HEAP;
		p->vm_end = (char*) KERN_PG_HEAP_LIM;
		INIT_LIST_HEAD(&kern_free_vm);
		list_add(&p->list, &kern_free_vm);

		arch.initProc();

		return;
	}

	/*
	 * Cree et initialise un rep. de pages pour une tache
	 */
	struct page_directory *pd_create(void)
	{
		struct page_directory *pd;
		u32 *pdir;
		int i;

		/* Prend et initialise une page pour le Page Directory */
		pd = (struct page_directory *) kmalloc(sizeof(struct page_directory));
		pd->base = get_page_from_heap();

		/* 
		 * Espace kernel. Les v_addr < USER_OFFSET sont adressees par la table
		 * de pages du noyau (pd0[]).
		 */
		pdir = (u32 *) pd->base->v_addr;
		for (i = 0; i < 256; i++)
			pdir[i] = pd0[i];

		/* Espace utilisateur */
		for (i = 256; i < 1023; i++)
			pdir[i] = 0;

		/* Page table mirroring magic trick !... */
		pdir[1023] = ((u32) pd->base->p_addr | (PG_PRESENT | PG_WRITE));


		/* Mise a jour de la liste des tables de pages de l'espace utilisateur */
		INIT_LIST_HEAD(&pd->pt);

		return pd;
	}

	void page_copy_in_pd(process_st* current,u32 virtadr){
			struct page *pg;
			pg = (struct page *) kmalloc(sizeof(struct page));
			pg->p_addr = get_page_frame();
			/* todo copier le contenus de l'autre page */
			pg->v_addr = (char *) (virtadr & 0xFFFFF000);
			list_add(&pg->list, &current->pglist);
			pd_add_page(pg->v_addr, pg->p_addr, PG_USER, current->pd);
	}


	/*
	 * Cree et initialise un rep. de pages pour une tache en copie d'une autre  (ne marche pas encore )
	 */
	struct page_directory *pd_copy(struct page_directory * pdfather)
	{
		struct page_directory *pd;
		u32 *pdir;
		int i;

		/* Prend et initialise une page pour le Page Directory */
		pd = (struct page_directory *) kmalloc(sizeof(struct page_directory));
		pd->base = get_page_from_heap();

		/* 
		 * Espace kernel. Les v_addr < USER_OFFSET sont adressees par la table
		 * de pages du noyau (pd0[]).
		 */
		pdir = (u32 *) pd->base->v_addr;
		for (i = 0; i < 256; i++)
			pdir[i] = pd0[i];

		/* Espace utilisateur */
		for (i = 256; i < 1023; i++)
			pdir[i] = 0;

		/* Page table mirroring magic trick !... */
		pdir[1023] = ((u32) pd->base->p_addr | (PG_PRESENT | PG_WRITE));


		/* Mise a jour de la liste des tables de pages de l'espace utilisateur */
		INIT_LIST_HEAD(&pd->pt);

		return pd;
	}

	int pd_destroy(struct page_directory *pd)
	{
		struct page *pg;
		struct list_head *p, *n;

		/* Libere les pages correspondant aux tables */
		list_for_each_safe(p, n, &pd->pt) {
			pg = list_entry(p, struct page, list);
			release_page_from_heap(pg->v_addr);
			list_del(p);
			kfree(pg);
		}

		/* Libere la page correspondant au repertoire */
		release_page_from_heap(pd->base->v_addr);
		kfree(pd);

		return 0;
	}

	/* 
	 * Met a jour l'espace d'adressage du noyau.
	 * NOTE : cet espace est commun a tous les repertoires de pages.
	 */
	int pd0_add_page(char *v_addr, char *p_addr, int flags)
	{
		u32 *pde;
		u32 *pte;

		if (v_addr > (char *) USER_OFFSET) {
			io.print("ERROR: pd0_add_page(): %p is not in kernel space !\n", v_addr);
			return 0;
		}

		/* On verifie que la table de page est bien presente */
		pde = (u32 *) (0xFFFFF000 | (((u32) v_addr & 0xFFC00000) >> 20));
		if ((*pde & PG_PRESENT) == 0) {
			//error
		}

		/* Modification de l'entree dans la table de page */
		pte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10));
		*pte = ((u32) p_addr) | (PG_PRESENT | PG_WRITE | flags);
		set_page_frame_used(p_addr);
		return 0;
	}

	/* 
	 * Met a jour le repertoire de pages courant
	 * input:
	 * 	v_addr : adresse lineaire de la page 
	 * 	p_addr : adresse physique de la page allouee 
	 * 	pd     : structure qui doit etre mise a jour avec les pages allouees
	 */
	int pd_add_page(char *v_addr, char *p_addr, int flags, struct page_directory *pd)
	{
		u32 *pde;		/* adresse virtuelle de l'entree du repertoire de pages */
		u32 *pte;		/* adresse virtuelle de l'entree de la table de pages */
		u32 *pt;		/* adresse virtuelle de la table de pages */
		struct page *pg;
		int i;

		//// io.print("DEBUG: pd_add_page(%p, %p, %d)\n", v_addr, p_addr, flags); /* DEBUG */

		/*
		 * La derniere entree du PageDir pointe sur lui-meme.
		 * Les adresses commencant par 0xFFC00000 utilisent cette entree et il
		 * s'ensuite que :
		 * - les 10 bits en 0x003FF000 sont un index dans le PageDir et designent une
		 *   PageTable. Les 12 derniers bits permettent de modifier une entree du PageTable
		 * - l'adresse 0xFFFFF000 designe le PageDir lui-meme
		 */
		pde = (u32 *) (0xFFFFF000 | (((u32) v_addr & 0xFFC00000) >> 20));

		/* 
		 * On cree la table de pages correspondante si elle n'est pas presente
		 */
		if ((*pde & PG_PRESENT) == 0) {

			/* 
			 * Allocation d'une page pour y mettre la table. 
			 */
			pg = get_page_from_heap();

			/* On initialise la nouvelle table de pages */
			pt = (u32 *) pg->v_addr;
			for (i = 1; i < 1024; i++)
				pt[i] = 0;

			/* On ajoute l'entree correspondante dans le repertoire */
			*pde = (u32) pg->p_addr | (PG_PRESENT | PG_WRITE | flags);

			/* On rajoute la nouvelle page dans la structure  passee en parametre */
			if (pd) 
				list_add(&pg->list, &pd->pt);
		}

		pte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10));
		*pte = ((u32) p_addr) | (PG_PRESENT | PG_WRITE | flags);

		return 0;
	}

	int pd_remove_page(char *v_addr)
	{
		u32 *pte;

		if (get_p_addr(v_addr)) {
			pte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10));
			*pte = (*pte & (~PG_PRESENT));
			
			asm("invlpg %0"::"m"(v_addr));
		}

		return 0;
	}

	/*
	 * Retourne l'adresse physique de la page associee a l'adresse virtuelle passee
	 * en argument
	 */
	char *get_p_addr(char *v_addr)
	{
		u32 *pde;		/* adresse virtuelle de l'entree du repertoire de pages */
		u32 *pte;		/* adresse virtuelle de l'entree de la table de pages */

		pde = (u32 *) (0xFFFFF000 | (((u32) v_addr & 0xFFC00000) >> 20));
		if ((*pde & PG_PRESENT)) {
			pte = (u32 *) (0xFFC00000 | (((u32) v_addr & 0xFFFFF000) >> 10));
			if ((*pte & PG_PRESENT))
				return (char *) ((*pte & 0xFFFFF000) + (VADDR_PG_OFFSET((u32) v_addr)));
		}

		return 0;
	}
}

void Vmm::kmap(u32 phy,u32 virt){
	pd0_add_page((char*)phy,(char*)virt,PG_USER);
}

void Vmm::init(u32 high){
	Memory_init(high);
}


================================================
FILE: src/kernel/arch/x86/vmm.h
================================================
#ifndef VMM_H
#define VMM_H

#include <runtime/types.h>
#include <runtime/list.h>
#include <runtime/alloc.h>
#include <x86.h>


extern "C" {

struct page {
		char *v_addr;
		char *p_addr;
		list_head list;
};

struct page_directory {
		page *base;
		list_head pt;
};

struct vm_area {
		char *vm_start;	
		char *vm_end;	/* exclude */
		list_head list;
};

typedef page_directory proc_memory;

	/* Pointe sur le sommet du heap noyau */
	extern char *kern_heap;

	/* Pointe sur le debut de la liste des pages libres du noyau */
	extern list_head kern_free_vm;


	extern u32 *pd0;
	extern u8 mem_bitmap[];

	extern u32 kmalloc_used;



	/* Marque une page comme utilisee / libre dans le bitmap */
	#define set_page_frame_used(page)	mem_bitmap[((u32) page)/8] |= (1 << (((u32) page)%8))
	#define release_page_frame(p_addr)	mem_bitmap[((u32) p_addr/PAGESIZE)/8] &= ~(1 << (((u32) p_addr/PAGESIZE)%8))

	/* Selectionne une page libre dans le bitmap */
	char *get_page_frame(void);

	/* Selectionne / libere une page libre dans le bitmap et l'associe a une page
	 * virtuelle libre du heap */
	struct page *get_page_from_heap(void);
	int release_page_from_heap(char *);

	/* Initialise les structures de donnees de gestion de la memoire */
	void Memory_init(u32 high_mem);

	/* Cree un repertoire de page pour un processus */
	struct page_directory *pd_create(void);
	int pd_destroy(struct page_directory *);
	struct page_directory *pd_copy(struct page_directory * pdfather);
	
	
	/* Ajoute une entree dans l'espace du noyau */
	int pd0_add_page(char *, char *, int);

	/* Ajoute / enleve une entree dans le repertoire de pages courant */
	int pd_add_page(char *, char *, int, struct page_directory *);
	int pd_remove_page(char *);

	/* Retourne l'adresse physique associee a une adresse virtuelle */
	char *get_p_addr(char *);

	
	#define KMALLOC_MINSIZE		16

	struct kmalloc_header {
		unsigned long size:31;	/* taille totale de l'enregistrement */
		unsigned long used:1;
	} __attribute__ ((packed));

}

class Vmm
{
	public:
		void			init(u32 high);
		proc_memory*	createPM();					/* Create page directory for a process */
		void			switchPM(proc_memory* ad);	/* Switch page directory for a process */
		void			map(proc_memory* ad,u32 phy,u32 adr);	/* map a physical page memory in virtual space */
		
		void			kmap(u32 phy,u32 virt);
		
};

extern Vmm vmm;

#endif


================================================
FILE: src/kernel/arch/x86/x86.cc
================================================
#include <os.h>
#include <x86.h>
#include <keyboard.h>


extern "C" {

regs_t cpu_cpuid(int code)
{
	regs_t r;
	asm volatile("cpuid":"=a"(r.eax),"=b"(r.ebx),
                 "=c"(r.ecx),"=d"(r.edx):"0"(code));
	return r;
}


u32 cpu_vendor_name(char *name)
{
		regs_t r = cpu_cpuid(0x00);
		
		char line1[5];
		line1[0] = ((char *) &r.ebx)[0];
		line1[1] = ((char *) &r.ebx)[1];
		line1[2] = ((char *) &r.ebx)[2];
		line1[3] = ((char *) &r.ebx)[3];
		line1[4] = '\0';

		char line2[5];
		line2[0] = ((char *) &r.ecx)[0];
		line2[1] = ((char *) &r.ecx)[1];
		line2[2] = ((char *) &r.ecx)[2];
		line2[3] = ((char *) &r.ecx)[3];
		line2[4] = '\0';
		
		char line3[5];
		line3[0] = ((char *) &r.edx)[0];
		line3[1] = ((char *) &r.edx)[1];
		line3[2] = ((char *) &r.edx)[2];
		line3[3] = ((char *) &r.edx)[3];
		line3[4] = '\0';
							
		strcpy(name, line1);
		strcat(name, line3);
		strcat(name, line2);
		return 15;
}


void schedule();

idtdesc 	kidt[IDTSIZE]; 		/* IDT table */
int_desc 	intt[IDTSIZE]; 		/* Interruptions functions tables */
gdtdesc 	kgdt[GDTSIZE];		/* GDT */
tss 		default_tss;
gdtr 		kgdtr;				/* GDTR */
idtr 		kidtr; 				/* IDTR registry */
u32 *		stack_ptr=0;

/*
 * 'init_desc' initialize a segment descriptor in gdt or ldt.
 * 'desc' is a pointer to the address
 */
void init_gdt_desc(u32 base, u32 limite, u8 acces, u8 other,struct gdtdesc *desc)
{
	desc->lim0_15 = (limite & 0xffff);
	desc->base0_15 = (base & 0xffff);
	desc->base16_23 = (base & 0xff0000) >> 16;
	desc->acces = acces;
	desc->lim16_19 = (limite & 0xf0000) >> 16;
	desc->other = (other & 0xf);
	desc->base24_31 = (base & 0xff000000) >> 24;
	return;
}


/*
 * This function initialize the GDT after the kernel is loaded.
 */
void init_gdt(void)
{

	default_tss.debug_flag = 0x00;
	default_tss.io_map = 0x00;
	default_tss.esp0 = 0x1FFF0;
	default_tss.ss0 = 0x18;

	/* initialize gdt segments */
	init_gdt_desc(0x0, 0x0, 0x0, 0x0, &kgdt[0]);
	init_gdt_desc(0x0, 0xFFFFF, 0x9B, 0x0D, &kgdt[1]);	/* code */
	init_gdt_desc(0x0, 0xFFFFF, 0x93, 0x0D, &kgdt[2]);	/* data */
	init_gdt_desc(0x0, 0x0, 0x97, 0x0D, &kgdt[3]);		/* stack */

	init_gdt_desc(0x0, 0xFFFFF, 0xFF, 0x0D, &kgdt[4]);	/* ucode */
	init_gdt_desc(0x0, 0xFFFFF, 0xF3, 0x0D, &kgdt[5]);	/* udata */
	init_gdt_desc(0x0, 0x0, 0xF7, 0x0D, &kgdt[6]);		/* ustack */

	init_gdt_desc((u32) & default_tss, 0x67, 0xE9, 0x00, &kgdt[7]);	/* descripteur de tss */

	/* initialize the gdtr structure */
	kgdtr.limite = GDTSIZE * 8;
	kgdtr.base = GDTBASE;

	/* copy the gdtr to its memory area */
	memcpy((char *) kgdtr.base, (char *) kgdt, kgdtr.limite);

	/* load the gdtr registry */
	asm("lgdtl (kgdtr)");

	/* initiliaz the segments */
	asm("   movw $0x10, %ax	\n \
            movw %ax, %ds	\n \
            movw %ax, %es	\n \
            movw %ax, %fs	\n \
            movw %ax, %gs	\n \
            ljmp $0x08, $next	\n \
            next:		\n");
			
}


void init_idt_desc(u16 select, u32 offset, u16 type, struct idtdesc *desc)
{
	desc->offset0_15 = (offset & 0xffff);
	desc->select = select;
	desc->type = type;
	desc->offset16_31 = (offset & 0xffff0000) >> 16;
	return;
}

extern void _asm_int_0();
extern void _asm_int_1();
extern void _asm_syscalls();
extern void _asm_exc_GP(void);
extern void _asm_exc_PF(void);
extern void _asm_schedule();

void do_syscalls(int num){
	 u32 ret,ret1,ret2,ret3,ret4;
	 asm("mov %%ebx, %0": "=m"(ret):);
	 asm("mov %%ecx, %0": "=m"(ret1):);
	 asm("mov %%edx, %0": "=m"(ret2):);
	 asm("mov %%edi, %0": "=m"(ret3):);
	 asm("mov %%esi, %0": "=m"(ret4):);
	 //io.print("syscall %d \n",num);
	 /*io.print(" ebx : %x  ",ret);
	 io.print(" ecx : %x \n",ret1);
	 io.print(" edx : %x  ",ret2);
	 io.print(" edi : %x \n",ret3);*/
	   
	 arch.setParam(ret,ret1,ret2,ret3,ret4);
	 asm("cli");
	 asm("mov %%ebp, %0": "=m"(stack_ptr):);

	 
	 syscall.call(num);
	 asm("sti");
}



void isr_kbd_int(void)
{
	u8 i;
	static int lshift_enable;
	static int rshift_enable;
	static int alt_enable;
	static int ctrl_enable;
	do {
		i = io.inb(0x64);
	} while ((i & 0x01) == 0);
	

	i = io.inb(0x60);
	i--;

	if (i < 0x80) {		/* touche enfoncee */
		switch (i) {
		case 0x29:
			lshift_enable = 1;
			break;
		case 0x35:
			rshift_enable = 1;
			break;
		case 0x1C:
			ctrl_enable = 1;
			break;
		case 0x37:
			alt_enable = 1;
			break;
		default:
		
				if(alt_enable==1)
				{
					io.putctty(kbdmap[i * 4 + 2]);
					if (&io != io.current_io)
					io.current_io->putctty(kbdmap[i * 4 + 2]);
		 
				}
				else if(lshift_enable == 1 || rshift_enable == 1)
				{
		 
					 io.putctty(kbdmap[i * 4 + 1]);
					 if (&io != io.current_io)
						io.current_io->putctty(kbdmap[i * 4 + 1]);
		 
				}
				else
				{
						  io.putctty(kbdmap[i * 4]);
					 if (&io != io.current_io)
					 io.current_io->putctty(kbdmap[i * 4]);
		 
				}
               break;

			//io.print("sancode: %x \n",i * 4 + (lshift_enable || rshift_enable));
			/*io.putctty(kbdmap[i * 4 + (lshift_enable || rshift_enable)]);	//replac depuis la 10.4.6
			if (&io != io.current_io)
				io.current_io->putctty(kbdmap[i * 4 + (lshift_enable || rshift_enable)]);*/
			break;
		}
	} else {		/* touche relachee */
		i -= 0x80;
		switch (i) {
		case 0x29:
			lshift_enable = 0;
			break;
		case 0x35:
			rshift_enable = 0;
			break;
		case 0x1C:
			ctrl_enable = 0;
			break;
		case 0x37:
			alt_enable = 0;
			break;
		}
	}
	
		io.outb(0x20,0x20);
		io.outb(0xA0,0x20); 
}


void isr_default_int(int id)
{
	static int tic = 0;
	static int sec = 0;
	switch (id){
		case 1:
			isr_kbd_int();
			break;
			
			
		default:
			return;
		
	}
	
	io.outb(0x20,0x20);
	io.outb(0xA0,0x20);
}


void isr_schedule_int()
{
	static int tic = 0;
	static int sec = 0;
		tic++;
		if (tic % 100 == 0) {
		sec++;
		tic = 0;
	}
	schedule();
	io.outb(0x20,0x20);
	io.outb(0xA0,0x20);
}

void isr_GP_exc(void)
{
	io.print("\n General protection fault !\n");
	if (arch.pcurrent!=NULL){
		io.print("The processus %s have to be killed !\n\n",(arch.pcurrent)->getName());
		(arch.pcurrent)->exit();
		schedule();
	}
	else{
		io.print("The kernel have to be killed !\n\n");
		asm("hlt");
	}
}

void isr_PF_exc(void)
{
	u32 faulting_addr, code;
	u32 eip;
	struct page *pg;
	u32 stack;
 	asm(" 	movl 60(%%ebp), %%eax	\n \
    		mov %%eax, %0		\n \
		mov %%cr2, %%eax	\n \
		mov %%eax, %1		\n \
 		movl 56(%%ebp), %%eax	\n \
    		mov %%eax, %2"
		: "=m"(eip), "=m"(faulting_addr), "=m"(code));
	 asm("mov %%ebp, %0": "=m"(stack):);
	
	//io.print("#PF : %x \n",faulting_addr);
	
	//for (;;);
		if (arch.pcurrent==NULL)
			return;
			
		process_st* current=arch.pcurrent->getPInfo();

	if (faulting_addr >= USER_OFFSET && faulting_addr <= USER_STACK) {
		pg = (struct page *) kmalloc(sizeof(struct page));
		pg->p_addr = get_page_frame();
		pg->v_addr = (char *) (faulting_addr & 0xFFFFF000);
		list_add(&pg->list, &current->pglist);
		pd_add_page(pg->v_addr, pg->p_addr, PG_USER, current->pd);
	}
	else {
		io.print("\n");
		io.print("No autorized memory acces on : %p (eip:%p,code:%p)\n", faulting_addr,eip,  code);
		io.print("heap=%x, heap_limit=%x, stack=%x\n",kern_heap,KERN_HEAP_LIM,stack);
		
		if (arch.pcurrent!=NULL){
			io.print("The processus %s have to be killed !\n\n",(arch.pcurrent)->getName());
			(arch.pcurrent)->exit();
			schedule();
		}
		else{
			io.print("The kernel have to be killed !\n\n");
			asm("hlt");
		}
	}
		
}



/*
 * Init IDT after kernel is loaded
 */
void init_idt(void)
{
	/* Init irq */
	int i;
	for (i = 0; i < IDTSIZE; i++) 
		init_idt_desc(0x08, (u32)_asm_schedule, INTGATE, &kidt[i]); // 
	
	/* Vectors  0 -> 31 are for exceptions */
	init_idt_desc(0x08, (u32) _asm_exc_GP, INTGATE, &kidt[13]);		/* #GP */
	init_idt_desc(0x08, (u32) _asm_exc_PF, INTGATE, &kidt[14]);     /* #PF */
	
	init_idt_desc(0x08, (u32) _asm_schedule, INTGATE, &kidt[32]);
	init_idt_desc(0x08, (u32) _asm_int_1, INTGATE, &kidt[33]);
	
	init_idt_desc(0x08, (u32) _asm_syscalls, TRAPGATE, &kidt[48]);
	init_idt_desc(0x08, (u32) _asm_syscalls, TRAPGATE, &kidt[128]); //48
	
	kidtr.limite = IDTSIZE * 8;
	kidtr.base = IDTBASE;
	
	
	/* Copy the IDT to the memory */
	memcpy((char *) kidtr.base, (char *) kidt, kidtr.limite);

	/* Load the IDTR registry */
	asm("lidtl (kidtr)");
}


void init_pic(void)
{
	/* Initialization of ICW1 */
	io.outb(0x20, 0x11);
	io.outb(0xA0, 0x11);

	/* Initialization of ICW2 */
	io.outb(0x21, 0x20);	/* start vector = 32 */
	io.outb(0xA1, 0x70);	/* start vector = 96 */

	/* Initialization of ICW3 */
	io.outb(0x21, 0x04);
	io.outb(0xA1, 0x02);

	/* Initialization of ICW4 */
	io.outb(0x21, 0x01);
	io.outb(0xA1, 0x01);

	/* mask interrupts */
	io.outb(0x21, 0x0);
	io.outb(0xA1, 0x0);
}

#define DEBUG_REG(a) io.print("  %s : %x",#a,p->regs.a)

void schedule(){
	Process* pcurrent=arch.pcurrent;
	Process*plist=arch.plist;
	if (pcurrent==0)
		return;

	if (pcurrent->getPNext() == 0 && plist==pcurrent)	//si le proc est seul
		return;

	process_st* current=pcurrent->getPInfo();
	process_st *p;
	int i, newpid;

	/* Stocke dans stack_ptr le pointeur vers les registres sauvegardes */
	asm("mov (%%ebp), %%eax; mov %%eax, %0": "=m"(stack_ptr):);
	//asm("mov (%%eip), %%eax; mov %%eax, %0": "=m"(current->regs.eip):);
	
	//io.print("stack_ptr : %x \n",stack_ptr);
		/* Sauver les registres du processus courant */
		current->regs.eflags = stack_ptr[16];
		current->regs.cs = stack_ptr[15];
		current->regs.eip = stack_ptr[14];
		current->regs.eax = stack_ptr[13];
		current->regs.ecx = stack_ptr[12];
		current->regs.edx = stack_ptr[11];
		current->regs.ebx = stack_ptr[10];
		current->regs.ebp = stack_ptr[8];
		current->regs.esi = stack_ptr[7];
		current->regs.edi = stack_ptr[6];
		current->regs.ds = stack_ptr[5];
		current->regs.es = stack_ptr[4];
		current->regs.fs = stack_ptr[3];
		current->regs.gs = stack_ptr[2];

	
		/* 
		 * Sauvegarde le contenu des registres de pile (ss, esp)
		 * au moment de l'interruption. Necessaire car le processeur
		 * empile ou non ces valeurs selon le contexte de l'interruption.
		 */
		if (current->regs.cs != 0x08) {	/* mode utilisateur */
			current->regs.esp = stack_ptr[17];
			current->regs.ss = stack_ptr[18];
		} else {	/* pendant un appel systeme */
			current->regs.esp = stack_ptr[9] + 12;	/* vaut : &stack_ptr[17] */
			current->regs.ss = default_tss.ss0;
		}

		/* Sauver le TSS de l'ancien processus */
		current->kstack.ss0 = default_tss.ss0;
		current->kstack.esp0 = default_tss.esp0;
	
	//io.print("schedule %s ",pcurrent->getName());
	pcurrent=pcurrent->schedule();
	p = pcurrent->getPInfo();

	//io.print("to %s \n",pcurrent->getName());
	/*DEBUG_REG(eax);
	DEBUG_REG(ebx);
	DEBUG_REG(ecx);
	DEBUG_REG(edx);*/
	/*DEBUG_REG(esp); io.print("\t");
	DEBUG_REG(ebp);	io.print("\n");*/
	//DEBUG_REG(esi);
	//DEBUG_REG(edi);
	//DEBUG_REG(eip);	io.print("\t");
	/*DEBUG_REG(eflags);
	DEBUG_REG(cs);
	DEBUG_REG(ss);
	DEBUG_REG(ds);
	DEBUG_REG(es);
	DEBUG_REG(fs);
	DEBUG_REG(gs);
	DEBUG_REG(cr3);
	io.print("\n");*/
	
	/* Commutation */
	if (p->regs.cs != 0x08)
		switch_to_task(p, USERMODE);
	else
		switch_to_task(p, KERNELMODE);
}

/* 
 * switch_to_task(): Prepare la commutation de tache effectuee par do_switch().
 * Le premier parametre indique le pid du processus a charger.
 * Le mode indique si ce processus etait en mode utilisateur ou en mode kernel
 * quand il a ete precedement interrompu par le scheduler.
 * L'empilement des registres sur la pile change selon le cas.
 */
void switch_to_task(process_st* current, int mode)
{

	u32 kesp, eflags;
	u16 kss, ss, cs;
	int sig;
	
	/* Traite les signaux */

		if ((sig = dequeue_signal(current->signal))) 
			handle_signal(sig);
	
	/* Charge le TSS du nouveau processus */
	default_tss.ss0 = current->kstack.ss0;
	default_tss.esp0 = current->kstack.esp0;

	/* 
	 * Empile les registres ss, esp, eflags, cs et eip necessaires a la
	 * commutation. Ensuite, la fonction do_switch() restaure les
	 * registres, la table de page du nouveau processus courant et commute
	 * avec l'instruction iret.
	 */
	ss = current->regs.ss;
	cs = current->regs.cs;
	eflags = (current->regs.eflags | 0x200) & 0xFFFFBFFF;
	

	
	/* Prepare le changement de pile noyau */
	if (mode == USERMODE) {
		kss = current->kstack.ss0;
		kesp = current->kstack.esp0;
	} else {			/* KERNELMODE */
		kss = current->regs.ss;
		kesp = current->regs.esp;
	}
	
	
	//io.print("switch to %x \n",current->regs.eip);

	
	asm("	mov %0, %%ss; \
		mov %1, %%esp; \
		cmp %[KMODE], %[mode]; \
		je nextt; \
		push %2; \
		push %3; \
		nextt: \
		push %4; \
		push %5; \
		push %6; \
		push %7; \
		ljmp $0x08, $do_switch" 
		:: \
		"m"(kss), \
		"m"(kesp), \
		"m"(ss), \
		"m"(current->regs.esp), \
		"m"(eflags), \
		"m"(cs), \
		"m"(current->regs.eip), \
		"m"(current), \
		[KMODE] "i"(KERNELMODE), \
		[mode] "g"(mode)
	    );
	
}


int dequeue_signal(int mask) 
{
	int sig;

	if (mask) {
		sig = 1;
		while (!(mask & 1)) {
			mask = mask >> 1;
			sig++;
		}
	}
	else
		sig = 0;

	return sig;
}

int handle_signal(int sig)
{
	Process* pcurrent=arch.pcurrent;
	if (pcurrent==0)
		return 0;

	process_st* current=pcurrent->getPInfo();
	
	u32 *esp;

	//io.print("signal> handle signal : signal %d for process %d\n", sig, pcurrent->getPid());

	if (current->sigfn[sig] == (void*) SIG_IGN) {
		clear_signal(&(current->signal), sig);
	}
	else if (current->sigfn[sig] == (void*) SIG_DFL) {
		switch(sig) {
			case SIGHUP : case SIGINT : case SIGQUIT : 
				asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"(current->regs.cr3));
				pcurrent->exit();
				break;
			case SIGCHLD : 
				break;
			default :
				clear_signal(&(current->signal), sig);
		}
	}
	else {

		esp = (u32*) current->regs.esp - 20;

		asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"(current->regs.cr3));
		
		// Code assembleur qui appelle sys_sigreturn() 
		esp[19] = 0x0030CD00;
		esp[18] = 0x00000EB8;

		// Sauvegarde des registres 
		esp[17] = current->kstack.esp0;
		esp[16] = current->regs.ss;
		esp[15] = current->regs.esp;
		esp[14] = current->regs.eflags;
		esp[13] = current->regs.cs;
		esp[12] = current->regs.eip;
		esp[11] = current->regs.eax;
		esp[10] = current->regs.ecx;
		esp[9] = current->regs.edx;
		esp[8] = current->regs.ebx;
		esp[7] = current->regs.ebp;
		esp[6] = current->regs.esi;
		esp[5] = current->regs.edi;
		esp[4] = current->regs.ds;
		esp[3] = current->regs.es;
		esp[2] = current->regs.fs;
		esp[1] = current->regs.gs;

		// Adresse de retour pour %eip 
		esp[0] = (u32) &esp[18];


		current->regs.esp = (u32) esp;
		current->regs.eip = (u32) current->sigfn[sig];

		// Efface le signal et retablit le handler par defaut *
		current->sigfn[sig] = (void*) SIG_DFL;
		if (sig != SIGCHLD)
			clear_signal(&(current->signal), sig);
	}

	return 0;
}


}

================================================
FILE: src/kernel/arch/x86/x86.h
================================================
#ifndef __X86__
#define __X86__

#include <runtime/types.h>

#define IDTSIZE		0xFF	/* nombre max. de descripteurs dans la table */
#define GDTSIZE		0xFF	/* nombre max. de descripteurs dans la table */

#define IDTBASE		0x00000000	/* addr. physique ou doit resider la IDT */
#define GDTBASE		0x00000800	/* addr. physique ou doit resider la gdt */

#define INTGATE  0x8E00		/* utilise pour gerer les interruptions */
#define TRAPGATE 0xEF00		/* utilise pour faire des appels systemes */

#define	KERN_PDIR			0x00001000
#define	KERN_STACK			0x0009FFF0
#define	KERN_BASE			0x00100000
#define KERN_PG_HEAP		0x00800000
#define KERN_PG_HEAP_LIM	0x10000000
#define KERN_HEAP			0x10000000
#define KERN_HEAP_LIM		0x40000000

#define	USER_OFFSET 		0x40000000
#define	USER_STACK 			0xE0000000
	
#define KERN_PG_1			0x400000
#define KERN_PG_1_LIM 		0x800000

#define	VADDR_PD_OFFSET(addr)	((addr) & 0xFFC00000) >> 22
#define	VADDR_PT_OFFSET(addr)	((addr) & 0x003FF000) >> 12
#define	VADDR_PG_OFFSET(addr)	(addr) & 0x00000FFF
#define PAGE(addr)		(addr) >> 12

#define	PAGING_FLAG 		0x80000000	/* CR0 - bit 31 */
#define PSE_FLAG			0x00000010	/* CR4 - bit 4  */

#define PG_PRESENT			0x00000001	/* page directory / table */
#define PG_WRITE			0x00000002
#define PG_USER				0x00000004
#define PG_4MB				0x00000080

#define	PAGESIZE 			4096
#define	RAM_MAXSIZE			0x100000000
#define	RAM_MAXPAGE			0x100000

/* Descripteur de segment */
struct gdtdesc {
	u16 lim0_15;
	u16 base0_15;
	u8 base16_23;
	u8 acces;
	u8 lim16_19:4;
	u8 other:4;
	u8 base24_31;
} __attribute__ ((packed));

/* Registre GDTR */
struct gdtr {
	u16 limite;
	u32 base;
} __attribute__ ((packed));

struct tss {
	u16 previous_task, __previous_task_unused;
	u32 esp0;
	u16 ss0, __ss0_unused;
	u32 esp1;
	u16 ss1, __ss1_unused;
	u32 esp2;
	u16 ss2, __ss2_unused;
	u32 cr3;
	u32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
	u16 es, __es_unused;
	u16 cs, __cs_unused;
	u16 ss, __ss_unused;
	u16 ds, __ds_unused;
	u16 fs, __fs_unused;
	u16 gs, __gs_unused;
	u16 ldt_selector, __ldt_sel_unused;
	u16 debug_flag, io_map;
} __attribute__ ((packed));

/* Descripteur de segment */
struct idtdesc {
	u16 offset0_15;
	u16 select;
	u16 type;
	u16 offset16_31;
} __attribute__ ((packed));

/* Registre IDTR */
struct idtr {
	u16 limite;
	u32 base;
} __attribute__ ((packed));

typedef struct
{
	u32 edi, esi, ebp, esp, ebx, edx, ecx, eax;
	u32 ds, es, fs, gs;
	u32 which_int, err_code;
	u32 eip, cs, eflags, user_esp, user_ss;
} __attribute__((packed)) regs_t;

typedef void (*int_desc)(void);

extern "C" {
	void init_gdt_desc(u32, u32, u8, u8, struct gdtdesc *);
	void init_gdt(void);
	void init_idt_desc(u16, u32, u16, struct idtdesc *);
	void init_idt(void);
	void init_pic(void);
	int install_irq(unsigned int num,unsigned int irq);
	void switch_to_task(process_st* current, int mode);
	extern tss 		default_tss;
	u32 cpu_vendor_name(char *name);
	int dequeue_signal(int);
	int handle_signal(int);
}

#endif


================================================
FILE: src/kernel/arch/x86/x86int.asm
================================================
extern isr_default_int, do_syscalls, isr_schedule_int


%macro	SAVE_REGS 0
	pushad 
	push ds
	push es
	push fs
	push gs 
	push ebx
	mov bx,0x10
	mov ds,bx
	pop ebx
%endmacro

%macro	RESTORE_REGS 0
	pop gs
	pop fs
	pop es
	pop ds
	popad
%endmacro

%macro	INTERRUPT 1
global _asm_int_%1
_asm_int_%1:
	SAVE_REGS
	push %1
	call isr_default_int
	pop eax	;;a enlever sinon
	mov al,0x20
	out 0x20,al
	RESTORE_REGS
	iret
%endmacro

extern isr_GP_exc, isr_PF_exc 
global _asm_syscalls, _asm_exc_GP, _asm_exc_PF
_asm_syscalls:
	SAVE_REGS
	push eax                 ; transmission du numero d'appel
	call do_syscalls
	pop eax
	cli
	sti
	RESTORE_REGS
	iret


_asm_exc_GP:
	SAVE_REGS
	call isr_GP_exc
	RESTORE_REGS
	add esp,4
	iret

_asm_exc_PF:
	SAVE_REGS
	call isr_PF_exc
	RESTORE_REGS
	add esp,4
	iret

global _asm_schedule
_asm_schedule:
	SAVE_REGS
	call isr_schedule_int
	mov al,0x20
	out 0x20,al
	RESTORE_REGS
	iret

INTERRUPT 1
INTERRUPT 2


================================================
FILE: src/kernel/config.h
================================================
#ifndef CONFIG_H
#define CONFIG_H

#define KERNEL_NAME		"devos"		/* kernel name */
#define KERNEL_VERSION	"1"		/* kernel version */
#define KERNEL_DATE		__DATE__
#define KERNEL_TIME		__TIME__
#define KERNEL_LICENCE	"Apache License"	/* license */
#define KERNEL_COMPUTERNAME	"test-pc"	/* default name for the machine */

/* identifiant du processeur */
#ifdef __x86__
#define KERNEL_PROCESSOR_IDENTIFIER "x86"
#else
#define KERNEL_PROCESSOR_IDENTIFIER "(null)"
#endif

/* max open file */
#define CONFIG_MAX_FILE	32

#endif


================================================
FILE: src/kernel/core/Makefile
================================================
OBJS:=  $(OBJS) core/class.o core/elf_loader.o core/file.o \
	core/filesystem.o core/kernel.o core/api_posix.o\
	core/process.o core/syscalls.o core/device.o core/system.o \
	core/env.o core/user.o core/modulelink.o core/socket.o
	


================================================
FILE: src/kernel/core/api/dev/clock.h
================================================
#ifndef __API_CLOCK__
#define __API_CLOCK__

typedef unsigned int clock_d;

struct clock_info{
	clock_d		h;
	clock_d		m;
	clock_d		s;
	
	clock_d		day;
	clock_d		month;
	clock_d		year;
};

#define API_CLOCK_GET_INFO		0x6122

#endif


================================================
FILE: src/kernel/core/api/dev/fb.h
================================================
#ifndef __API_FB__
#define __API_FB__

struct fb_info{
	unsigned int		w;	//largeur
	unsigned int		h;	//hauteur
	char				bpp;	//bit per pixel
	char				state;	//etat de la carte
	unsigned int*		vmem;	//video memory
};

enum{
	FB_NOT_ACTIVE=0,
	FB_ACTIVE=1,
};

#define API_FB_IS_AVAILABLE			0x801
#define API_FB_GET_INFO				0x802	//info actuel
#define API_FB_GET_BINFO			0x803	//meilleur info
#define API_FB_SET_INFO				0x804


#endif


================================================
FILE: src/kernel/core/api/dev/ioctl.h
================================================
#ifndef __API_IOCTL__
#define __API_IOCTL__


#define DEV_GET_TYPE		0x01	/* Renvoie le type de peripherique */
#define	DEV_GET_STATE		0x02	/* renvoie l'etat du peripherique */
#define	DEV_GET_FORMAT		0x03	/* renvoie le format du peripherique */

//Type de peripherique :
#define DEV_TYPE_TTY 0x01
#define DEV_TYPE_DISK 0x02
#define DEV_TYPE_FB 0x03
#define DEV_TYPE_HID 0x04 //Added by NoMaitener (aka William). HID stand for Human Interface Device

//Format du peripherique
#define DEV_FORMAT_CHAR 0x01
#define DEV_FORMAT_BLOCK 0x02
#define DEV_FORMAT_FB 0x03

//Etat du peripherique
#define DEV_STATE_OK 0x01
#define DEV_STATE_NOTREADY 0x02 //Added by NoMaitener (aka William). Discuss here of "NOTREADY"


#endif


================================================
FILE: src/kernel/core/api/dev/ipc.h
================================================
#ifndef __API_IPC__
#define __API_IPC__

#define STDIPC_FILENO	3
#define SIGIPC		SIGUSR1


//iotcl
#define API_TTY_SWITCH_SCREEN	0xff52



#endif


================================================
FILE: src/kernel/core/api/dev/keyboard.h
================================================
#ifndef __API_KEYBOARD__
#define __API_KEYBOARD__


//keyboard
enum {
    KEY_TAB = 7,
    KEY_BACKSPACE = 8,
    KEY_ENTER = 10,
    KEY_ESCAPE = 27,
    KEY_F1 = 255,
    KEY_F2 = 254,
    KEY_F3 = 253,
    KEY_F4 = 252,
    KEY_F5 = 251,
    KEY_F6 = 250,
    KEY_F7 = 249,
    KEY_F8 = 248,
    KEY_F9 = 247,
    KEY_F10 = 246,
    KEY_F11 = 245,
    KEY_F12 = 244
};

#define TABLE_KEYBOARD_SIZE			388

#define API_KEYBOARD_SET_TABLE		0x4122

#endif


================================================
FILE: src/kernel/core/api/dev/proc.h
================================================
#ifndef __API_PROC__
#define __API_PROC__

struct proc_info{
	char				name[32];
	unsigned int		pid;
	unsigned int		tid;
	unsigned char		state;
	unsigned int		vmem;
	unsigned int		pmem;
};

enum{
	PROC_STATE_RUN=0,
	PROC_STATE_ZOMBIE=1,
	PROC_STATE_THREAD=2,
};

#define API_PROC_GET_PID		0x5200
#define API_PROC_GET_INFO		0x5201

#endif


================================================
FILE: src/kernel/core/api/dev/tty.h
================================================
#ifndef __API_TTY__
#define __API_TTY__

#include <api/dev/keyboard.h>

#define TTY_NAME_LEN	16

//tty info
struct tty_info_static{
	char			name[TTY_NAME_LEN];
	char			state;
	char			type;
	unsigned int	flags;
};

struct tty_info_moving{
	unsigned int	x;
	unsigned int	y;
	unsigned int	attrf;
	unsigned int	attrb;
};


//tty type
enum {
    TTY_TYPE_IOSTD=0,
	TTY_TYPE_SERIAL=1,
	TTY_TYPE_SCREEN=2,
	TTY_TYPE_VIRTUAL=3,
	TTY_TYPE_GUI=4
};

//tty state
enum {
    TTY_STATE_RUN=0,
	TTY_STATE_SWITCH=1,
	TTY_STATE_ERROR=2,
	TTY_STATE_PAUSE=3
};


enum TTY_Colour
{
	Black       =0,
	Blue        =1,
	Green       =2,
	Cyan        =3,
	Red         =4,
	Magenta     =5,
	Orange      =6,
	LightGrey   =7,
	DarkGrey    =8,
	LightBlue   =9,
	LightGreen  =10,
	LightCyan   =11,
	LightRed    =12,
	LightMagenta=13,
	Yellow      =14,
	White       =15
};
		  
//iotcl
#define API_TTY_SWITCH_SCREEN	0xff52
#define API_TTY_CLEAR_SCREEN	0xff53
#define API_TTY_GET_SINFO		0xff54
#define API_TTY_GET_MINFO		0xff55
#define API_TTY_SET_MINFO		0xff56

#endif


================================================
FILE: src/kernel/core/api/kernel/syscall.h
================================================

#ifndef _OS_SYSCALL_H_
#define _OS_SYSCALL_H_


int syscall0( int number );
int syscall1( int number, unsigned int p1 );
int syscall2( int number, unsigned int p1, unsigned int p2 );
int syscall3( int number, unsigned int p1, unsigned int p2, unsigned int p3 );
int syscall4( int number, unsigned int p1, unsigned int p2, unsigned int p3, unsigned int p4 );
int syscall5( int number, unsigned int p1, unsigned int p2, unsigned int p3, unsigned int p4, unsigned int p5 );

#endif


================================================
FILE: src/kernel/core/api/kernel/syscall_table.h
================================================

#ifndef _OS_SYSCALL_TABLE_H_
#define _OS_SYSCALL_TABLE_H_


#define NOT_DEFINED 0

enum {
	SYS_rewinddir			=NOT_DEFINED,
	SYS_sbrk				=45,	//	(count)
	SYS_fork				=NOT_DEFINED,
	SYS_write				=4,		//	(fd,buffer,count)
	SYS_read				=3,		//	(fd,buffer,count)
	SYS_open				=5,		//	(filename,flag)
	SYS_close				=6,		//	(fd)
	SYS_execve				=11,		//	(filename,argv,envp )
	SYS_dup					=NOT_DEFINED,
	SYS_dup2				=38,
	SYS_pwrite				=NOT_DEFINED,
	SYS_pread				=NOT_DEFINED,
	SYS_exit				=1,	//	(status)
	SYS_getdents			=89,
	SYS_fchdir				=NOT_DEFINED,
	SYS_isatty				=NOT_DEFINED,
	SYS_lseek				=19,
	SYS_unlink				=17,
	SYS_link				=18,
	SYS_readlink			=19,
	SYS_sleep_thread		=NOT_DEFINED,
	SYS_access				=NOT_DEFINED,
	SYS_chdir				=12,
	SYS_getpid				=20,
	SYS_getuid				=70,
	SYS_gettid				=NOT_DEFINED,
	SYS_rmdir				=NOT_DEFINED,
	SYS_symlink				=9,		//	(oldname,newname)
	SYS_fcntl				=NOT_DEFINED,
	SYS_get_system_time		=NOT_DEFINED,
	SYS_stat				=106,
	SYS_fstat				=NOT_DEFINED,
	SYS_stime				=NOT_DEFINED,
	SYS_mkdir				=15,
	SYS_ioctl				=54,	//	(fd,adress,buffer)
	SYS_select				=NOT_DEFINED,
	SYS_mount				=13,
	SYS_unmount				=14,
	SYS_lstat				=NOT_DEFINED,
	SYS_utime				=NOT_DEFINED,
	SYS_wait4				=7,
	SYS_socket				=NOT_DEFINED,
	SYS_connect				=NOT_DEFINED,
	SYS_sigaction			=67,
	SYS_kill				=37,
	SYS_sigprocmask			=NOT_DEFINED,
	SYS_dbprintf			=NOT_DEFINED,
	SYS_create_semaphore	=NOT_DEFINED,
	SYS_delete_semaphore	=NOT_DEFINED,
	SYS_lock_semaphore		=NOT_DEFINED,
	SYS_unlock_semaphore	=NOT_DEFINED,
	SYS_create_thread		=101,
	SYS_wake_up_thread		=NOT_DEFINED,
	SYS_kill_thread			=NOT_DEFINED,
	SYS_mmap				=55,
	
	SYS_loadmod				=71,
	SYS_login				=72,
	SYS_newuser				=73,
};




#endif 


================================================
FILE: src/kernel/core/api.h
================================================
#ifndef API_H
#define API_H

//posix
void call_open();
void call_close();
void call_read();
void call_write();
void call_sbrk();
void call_ioctl();
void call_exit();
void call_execv();
void call_symlink();
void call_getdents();
void call_wait();
void call_dup2();
void call_fork();
void call_chdir();
void call_mmap();

#endif


================================================
FILE: src/kernel/core/api_posix.cc
================================================
#include <os.h>


/*
 *	u32 open(char* name,u32 flag);
 */
void call_open(){
	char*name=(char*)arch.getArg(0);
	u32 flag=arch.getArg(1);
	
	Process* p=arch.pcurrent;
	if (p==NULL){
		arch.setRet((u32)-1);
		return;
	}
	
	File* fp=fsm.path(name);
	fp->open(flag);
	u32 fd=p->addFile(fp,flag);
	
	arch.setRet(fd);
}

/*
 *	void close(u32 fd);
 */
void call_close(){
	u32 fd=arch.getArg(0);
	Process* p=arch.pcurrent;
	if (p==NULL){
		arch.setRet((u32)-1);
		return;
	}
		
	File* fp=p->getFile(fd);
	if (fp==NULL){
		return;
	}
	
	fp->close();
	p->deleteFile(fd);
}

/*
 *	u32 read(u32 fd,char* buf,u32 size);
 */
void call_read(){
	u32 fd=arch.getArg(0);
	u8*buf=(u8*)arch.getArg(1);
	u32 size=arch.getArg(2);
	
	Process* p=arch.pcurrent;
	if (p==NULL){
		arch.setRet((u32)-1);
		return;
	}
		
	File* fp=p->getFile(fd);
	if (fp==NULL){
		arch.setRet((u32)-1);
		return;
	}
	openfile* info = p->getFileInfo(fd);
	u32 ret=fp->read(info->ptr,buf,size);
	info->ptr=info->ptr + ret;
	arch.setRet(ret);
}

/*
 *	u32 write(u32 fd,char* buf,u32 size);
 */
void call_write(){
	u32 fd=arch.getArg(0);
	u8*buf=(u8*)arch.getArg(1);
	u32 size=arch.getArg(2);
	
	Process* p=arch.pcurrent;
	if (p==NULL){
		arch.setRet((u32)-1);
		return;
	}
		
	File* fp=p->getFile(fd);
	if (fp==NULL){
		arch.setRet(-1);
		return;
	}
	openfile* info = p->getFileInfo(fd);
	u32 ret=fp->write(info->ptr,buf,size);
	info->ptr=info->ptr + ret;
	arch.setRet(ret);
}

/*
 *	u32 ioctl(u32 fd,u32 pos,char* buf);
 */
void call_ioctl(){
	u32 fd=arch.getArg(0);
	u8*buf=(u8*)arch.getArg(2);
	u32 pos=arch.getArg(1);
	
	Process* p=arch.pcurrent;
	if (p==NULL){
		arch.setRet((u32)-1);
		return;
	}
		
	File* fp=p->getFile(fd);
	if (fp==NULL){
		arch.setRet(-1);
		return;
	}
	
	u32 ret=fp->ioctl(pos,buf);
	arch.setRet(ret);
}

/*
 *	char* sbrk(int size);
 */
void call_sbrk(){
	int size;
	size=arch.getArg(0);
	char *ret;
	Process* p=arch.pcurrent;
	process_st* current=p->getPInfo();
	ret = current->e_heap;

	current->e_heap += size;
	
	arch.setRet((u32)ret);
	return;
}


/*
 *	void exit(int code);
 */
void call_exit(){
	int code;
	code=arch.getArg(0);
	
	Process* p=arch.pcurrent;
	p->exit();
	return;
}

/*
 *	int execv(const char* filename, char* const argv[], char* const envp[] );
 */
void call_execv(){
	char* filename,**argv,**envp;
	filename=(char*)arch.getArg(0);
	argv=(char**)arch.getArg(1);
	envp=(char**)arch.getArg(2);
	int argc;
	char **ap;
	
	ap = argv;
	argc = 0;
	while (*ap++) 
		argc++;
		
	int ret=execv(filename,argc,argv);
	arch.setRet((u32)ret);
	return;
}


/*
 *	int symlink(const char* oldpath, const char* newpath);
 */
void call_symlink(){
	char* oldpath,*path;
	oldpath=(char*)arch.getArg(0);
	path=(char*)arch.getArg(1);

	int ret=fsm.link(oldpath,path);
	arch.setRet((u32)ret);
	return;
}

struct dirent {
    u64	 d_ino;
    char d_name[256];
};

/*
 *	int getdents(int fd,dirrent* entry,int size);
 */
void call_getdents(){
	dirent nentry;
	u32 fd=arch.getArg(0);
	dirent* entry=(dirent*)arch.getArg(1);
	int size=arch.getArg(2);
	
	Process* p=arch.pcurrent;
	if (p==NULL){
		arch.setRet((u32)0);
		return;
	}
	
	File* fp=p->getFile(fd);
	if (fp==NULL){
		arch.setRet(0);
		return;
	}
	openfile* info = p->getFileInfo(fd);
	int i=0;
	File* child=fp->getChild();
	while (child!=NULL){
		if (i==(info->ptr)){
			//io.print("readdir=%s  - size=%d  entry=%x\n",child->getName(),size,entry);
			nentry.d_ino=child->getInode();
			strncpy(nentry.d_name,child->getName(),256);
			memcpy((char*)entry,(char*)&nentry,size);
			info->ptr++;
			arch.setRet(1);
			return;
		}
		i++;
		child=child->getNext();
	}
	arch.setRet((u32)0);
	return;
}

/*
 *	int wait(int* status);
 */
void call_wait(){
	u32*status=(u32*)arch.getArg(1);
	*status=0;
	Process* p=arch.pcurrent;
	u32 ret=p->wait();
	//arch.setRet(ret);
}

/*
 *	int dup2( int old_fd, int new_fd );
 */
void call_dup2(){
	u32 oldfd=arch.getArg(0);
	u32 newfd=arch.getArg(1);
	//io.print("dup2 %d to %d\n",oldfd,newfd);
	u32 ret=newfd;
	Process* p=arch.pcurrent;
	p->setFile((u32)newfd,p->getFile(oldfd),0, 0);
	arch.setRet((u32)ret);
}

/*
 *	int fork();
 */
void call_fork(){
	Process* p=arch.pcurrent;
	int ret=p->fork();
	arch.setRet((u32)ret);
}
 
/*
 *	int chdir(char* n);
 */
void call_chdir(){
	char* n;
	n=(char*)arch.getArg(0);
	
	Process* p=arch.pcurrent;
	File*f=fsm.path(n);
	if (f==NULL){
		arch.setRet((u32)-1);
		return;
	}
	
	p->setCurrentDir(f);
	arch.setRet((u32)1);
	return;
}

/*
 *	void * mmap (void *addr,size_t len,int prot,int flags,int fd,off_t offset)
 */
void call_mmap(){
	u32 fd=arch.getArg(3);
	u32 size=arch.getArg(0);
	u32 prot=0;
	u32 flags=0;
	u32 offset=0;
	
	Process* p=arch.pcurrent;
	if (p==NULL){
		arch.setRet((u32)-1);
		return;
	}
		
	File* fp=p->getFile(fd);
	if (fp==NULL){
		arch.setRet((u32)-1);
		return;
	}
	openfile* info = p->getFileInfo(fd);
	u32 ret=fp->mmap(size,flags,offset,prot);
	arch.setRet(ret);
}


================================================
FILE: src/kernel/core/boot.h
================================================
#ifndef __MY_BOOT__
#define __MY_BOOT__

#include <runtime/types.h>

struct multiboot_info {
	u32 flags;
	u32 low_mem;
	u32 high_mem;
	u32 boot_device;
	u32 cmdline;
	u32 mods_count;
	u32 mods_addr;
	struct {
		u32 num;
		u32 size;
		u32 addr;
		u32 shndx;
	} elf_sec;
	unsigned long mmap_length;
	unsigned long mmap_addr;
	unsigned long drives_length;
	unsigned long drives_addr;
	unsigned long config_table;
	unsigned long boot_loader_name;
	unsigned long apm_table;
	unsigned long vbe_control_info;
	unsigned long vbe_mode_info;
	unsigned long vbe_mode;
	unsigned long vbe_interface_seg;
	unsigned long vbe_interface_off;
	unsigned long vbe_interface_len;
};



/* VBE controller information.  */
struct vbe_controller
{
  unsigned char signature[4];
  unsigned short version;
  unsigned long oem_string;
  unsigned long capabilities;
  unsigned long video_mode;
  unsigned short total_memory;
  unsigned short oem_software_rev;
  unsigned long oem_vendor_name;
  unsigned long oem_product_name;
  unsigned long oem_product_rev;
  unsigned char reserved[222];
  unsigned char oem_data[256];
} __attribute__ ((packed));

/* VBE mode information.  */
struct vbe_mode
{
  unsigned short mode_attributes;
  unsigned char win_a_attributes;
  unsigned char win_b_attributes;
  unsigned short win_granularity;
  unsigned short win_size;
  unsigned short win_a_segment;
  unsigned short win_b_segment;
  unsigned long win_func;
  unsigned short bytes_per_scanline;

  /* >=1.2 */
  unsigned short x_resolution;
  unsigned short y_resolution;
  unsigned char x_char_size;
  unsigned char y_char_size;
  unsigned char number_of_planes;
  unsigned char bits_per_pixel;
  unsigned char number_of_banks;
  unsigned char memory_model;
  unsigned char bank_size;
  unsigned char number_of_image_pages;
  unsigned char reserved0;

  /* direct color */
  unsigned char red_mask_size;
  unsigned char red_field_position;
  unsigned char green_mask_size;
  unsigned char green_field_position;
  unsigned char blue_mask_size;
  unsigned char blue_field_position;
  unsigned char reserved_mask_size;
  unsigned char reserved_field_position;
  unsigned char direct_color_mode_info;

  /* >=2.0 */
  unsigned long phys_base;
  unsigned long reserved1;
  unsigned short reversed2;

  /* >=3.0 */
  unsigned short linear_bytes_per_scanline;
  unsigned char banked_number_of_image_pages;
  unsigned char linear_number_of_image_pages;
  unsigned char linear_red_mask_size;
  unsigned char linear_red_field_position;
  unsigned char linear_green_mask_size;
  unsigned char linear_green_field_position;
  unsigned char linear_blue_mask_size;
  unsigned char linear_blue_field_position;
  unsigned char linear_reserved_mask_size;
  unsigned char linear_reserved_field_position;
  unsigned long max_pixel_clock;

  unsigned char reserved3[189];
} __attribute__ ((packed));

#endif

================================================
FILE: src/kernel/core/class.cc
================================================
#include <os.h>

/*
Static objects
*/

Io 				io;			/* Input/Output interface */
Architecture 	arch;		/*	Cpu and architecture interface */
Vmm 			vmm;		/*	Virtual memory manager interface */
Filesystem		fsm;		/*	Filesystem interface */
Module			modm;		/* Module manager */
Syscalls		syscall;	/* Syscalls manager */
System			sys;		/* System manager */


================================================
FILE: src/kernel/core/device.cc
================================================
#include <os.h>



Device::~Device(){
	
}

Device::Device(char* n) : File(n,TYPE_DEVICE)
{
	fsm.addFile("/dev",this);
}

u32	Device::open(u32 flag){
	return NOT_DEFINED;
}

u32	Device::close(){
	return NOT_DEFINED;
}

u32	Device::read(u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	Device::write(u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	Device::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

u32	Device::remove(){
	delete this;
}

void Device::scan(){

}



================================================
FILE: src/kernel/core/device.h
================================================
#ifndef DEVICE_H
#define DEVICE_H

#include <core/file.h>
#include <runtime/list.h>


class Device : public File
{
	public:
		Device(char* n);
		~Device();
		
		virtual u32		open(u32 flag);
		virtual u32		close();
		virtual u32		read(u8* buffer,u32 size);
		virtual u32		write(u8* buffer,u32 size);
		virtual u32		ioctl(u32 id,u8* buffer);
		virtual u32		remove();
		virtual void	scan();
		
		
	protected:

};

#endif

================================================
FILE: src/kernel/core/elf_loader.cc
================================================
#include <os.h>

/*
Chargeur de module externe au format elf32 :
pour le moment compil en static sans librairies partags */


char* __default_proc_name="_proc_";	/* nom par default avec en plus un nombre */
char 	nb_default='0';

 
/* 
 * Teste si le fichier dont l'adresse est passee en argument
 * est au format ELF
 */
int is_elf(char *file)
{
	Elf32_Ehdr *hdr;

	hdr = (Elf32_Ehdr *) file;
	if (hdr->e_ident[0] == 0x7f && hdr->e_ident[1] == 'E'
	    && hdr->e_ident[2] == 'L' && hdr->e_ident[3] == 'F')
		return RETURN_OK;
	else
		return ERROR_PARAM;
}

/*
 *	Charge le fichier elf dans la memoire virtuelle et renvoie l'adresse de depart
 */
u32 load_elf(char *file,process_st *proc)
{
	char *p;
	u32 v_begin, v_end;
	Elf32_Ehdr *hdr;
	Elf32_Phdr *p_entry;
	Elf32_Scdr *s_entry;
	int i, pe;

	hdr = (Elf32_Ehdr *) file;
	p_entry = (Elf32_Phdr *) (file + hdr->e_phoff);

	s_entry= (Elf32_Scdr*) (file + hdr->e_shoff);
	
	if (is_elf(file)==ERROR_PARAM) {
		io.print("INFO: load_elf(): file not in ELF format !\n");
		return 0;
	}
	
	for (pe = 0; pe < hdr->e_phnum; pe++, p_entry++) {	/* Read each entry */

		if (p_entry->p_type == PT_LOAD) {
			v_begin = p_entry->p_vaddr;
			v_end = p_entry->p_vaddr + p_entry->p_memsz;
			if (v_begin < USER_OFFSET) {
				io.print ("INFO: load_elf(): can't load executable below %p\n", USER_OFFSET);
				return 0;
			}

			if (v_end > USER_STACK) {
				io.print ("INFO: load_elf(): can't load executable above %p\n", USER_STACK);
				return 0;
			}

			// Description de la zone exec + rodata 
			if (p_entry->p_flags == PF_X + PF_R) {	
				proc->b_exec = (char*) v_begin;
				proc->e_exec = (char*) v_end;
			}

			// Description de la zone bss 
			if (p_entry->p_flags == PF_W + PF_R) {	
				proc->b_bss = (char*) v_begin;
				proc->e_bss = (char*) v_end;
			}
			//io.print("elf : %x to %x \n",(file + p_entry->p_offset),v_begin);
			memcpy((char *) v_begin, (char *) (file + p_entry->p_offset), p_entry->p_filesz);
			if (p_entry->p_memsz > p_entry->p_filesz)
				for (i = p_entry->p_filesz, p = (char *) p_entry->p_vaddr; i < (int)(p_entry->p_memsz); i++)
					p[i] = 0;
			
			
			
		}
	}
	/* Return program entry point */
	
	return hdr->e_entry;
}

/*
 *	Charge un fichier en creant un nouveau processus
 */
int execv(char* file,int argc,char** argv){
	char* map_elf=NULL;
	File* fp=fsm.path(file);
	if (fp==NULL)
		return ERROR_PARAM;
	
	map_elf=(char*)kmalloc(fp->getSize());
	fp->open(NO_FLAG);
	fp->read(0,(u8*)map_elf,fp->getSize());
	fp->close();
	
	char* name;
	__default_proc_name[strlen(__default_proc_name)-1]=nb_default;
	nb_default++;
	if (argc<=0)
		name=__default_proc_name;
	else
		name=argv[0];
	//io.print("exec %s > %s\n",file,name);

	Process* proc=new Process(name);
	proc->create(map_elf,argc,argv);
	kfree(map_elf);
	return (int)proc->getPid();
}

/*
 *	Charge un module
 */
void execv_module(u32 entry,int argc,char** argv){
	char* name;
	__default_proc_name[strlen(__default_proc_name)-1]=nb_default;
	nb_default++;
	if (argc<=0)
		name=__default_proc_name;
	else
		name=argv[0];
	
	Process* proc=new Process(name);
	proc->create((char*)entry,argc,argv);
}




================================================
FILE: src/kernel/core/elf_loader.h
================================================
#ifndef ELF_H
#define ELF_H

#include <runtime/types.h>
#include <process.h>

/*
 * ELF HEADER
 */
typedef struct {
	unsigned char e_ident[16];	/* ELF identification */
	u16 e_type;		/* 2 (exec file) */
	u16 e_machine;		/* 3 (intel architecture) */
	u32 e_version;		/* 1 */
	u32 e_entry;		/* starting point */
	u32 e_phoff;		/* program header table offset */
	u32 e_shoff;		/* section header table offset */
	u32 e_flags;		/* various flags */
	u16 e_ehsize;		/* ELF header (this) size */

	u16 e_phentsize;	/* program header table entry size */
	u16 e_phnum;		/* number of entries */

	u16 e_shentsize;	/* section header table entry size */
	u16 e_shnum;		/* number of entries */

	u16 e_shstrndx;		/* index of the section name string table */
} Elf32_Ehdr;

/* 
 * ELF identification
 */
#define	EI_MAG0		0
#define	EI_MAG1		1
#define	EI_MAG2		2
#define	EI_MAG3		3
#define	EI_CLASS	4
#define	EI_DATA		5
#define	EI_VERSION	6
#define EI_PAD		7

/* EI_MAG */
#define	ELFMAG0		0x7f
#define	ELFMAG1		'E'
#define	ELFMAG2		'L'
#define	ELFMAG3		'F'

/* EI_CLASS */
#define	ELFCLASSNONE	0	/* invalid class */
#define	ELFCLASS32	1	/* 32-bit objects */
#define	ELFCLASS64	2	/* 64-bit objects */

/* EI_DATA */
#define	ELFDATANONE	0	/* invalide data encoding */
#define	ELFDATA2LSB	1	/* least significant byte first (0x01020304 is 0x04 0x03 0x02 0x01) */
#define	ELFDATA2MSB	2	/* most significant byte first (0x01020304 is 0x01 0x02 0x03 0x04) */

/* EI_VERSION */
#define	EV_CURRENT	1
#define	ELFVERSION	EV_CURRENT

/* 
 * PROGRAM HEADER 
 */
typedef struct {
	u32 p_type;		/* type of segment */
	u32 p_offset;
	u32 p_vaddr;
	u32 p_paddr;
	u32 p_filesz;
	u32 p_memsz;
	u32 p_flags;
	u32 p_align;
} Elf32_Phdr;

/* p_type */
#define	PT_NULL             0
#define	PT_LOAD             1
#define	PT_DYNAMIC          2
#define	PT_INTERP           3
#define	PT_NOTE             4
#define	PT_SHLIB            5
#define	PT_PHDR             6
#define	PT_LOPROC  0x70000000
#define	PT_HIPROC  0x7fffffff

/* p_flags */
#define PF_X	0x1
#define PF_W	0x2
#define PF_R	0x4









enum eElfSectionTypes {
	SHT_NULL,	//0
	SHT_PROGBITS,	//1
	SHT_SYMTAB,	//2
	SHT_STRTAB,	//3
	SHT_RELA,	//4
	SHT_HASH,	//5
	SHT_DYNAMIC,	//6
	SHT_NOTE,	//7
	SHT_NOBITS,	//8
	SHT_REL,	//9
	SHT_SHLIB,	//A
	SHT_DYNSYM,	//B
	SHT_LAST,	//C
	SHT_LOPROC = 0x70000000,
	SHT_HIPROC = 0x7fffffff,
	SHT_LOUSER = 0x80000000,
	SHT_HIUSER = 0xffffffff
};


typedef struct {
	u32		name;
	u32	type;
	u32	flags;
	u32	address;
	u32	offset;
	u32	size;
	u32	link;
	u32	info;
	u32	addralign;
	u32	entsize;
} Elf32_Scdr;





enum {
	R_386_NONE=0,	// none
	R_386_32,	// S+A
	R_386_PC32,	// S+A-P
	R_386_GOT32,	// G+A-P
	R_386_PLT32,	// L+A-P
	R_386_COPY,	// none
	R_386_GLOB_DAT,	// S
	R_386_JMP_SLOT,	// S
	R_386_RELATIVE,	// B+A
	R_386_GOTOFF,	// S+A-GOT
	R_386_GOTPC,	// GOT+A-P
	R_386_LAST	// none
};

typedef struct {
	u16	d_tag;
	u32	d_val;	//Also d_ptr
} Elf32_dyn;


enum {
	DT_NULL,	//!< Marks End of list
	DT_NEEDED,	//!< Offset in strtab to needed library
	DT_PLTRELSZ,	//!< Size in bytes of PLT
	DT_PLTGOT,	//!< Address of PLT/GOT
	DT_HASH,	//!< Address of symbol hash table
	DT_STRTAB,	//!< String Table address
	DT_SYMTAB,	//!< Symbol Table address
	DT_RELA,	//!< Relocation table address
	DT_RELASZ,	//!< Size of relocation table
	DT_RELAENT,	//!< Size of entry in relocation table
	DT_STRSZ,	//!< Size of string table
	DT_SYMENT,	//!< Size of symbol table entry
	DT_INIT,	//!< Address of initialisation function
	DT_FINI,	//!< Address of termination function
	DT_SONAME,	//!< String table offset of so name
	DT_RPATH,	//!< String table offset of library path
	DT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable
	DT_REL,		//!< Relocation Entries (Elf32_Rel instead of Elf32_Rela)
	DT_RELSZ,	//!< Size of above table (bytes)
	DT_RELENT,	//!< Size of entry in above table
	DT_PLTREL,	//!< Relocation entry of PLT
	DT_DEBUG,	//!< Debugging Entry - Unknown contents
	DT_TEXTREL,	//!< Indicates that modifcations to a non-writeable segment may occur
	DT_JMPREL,	//!< Address of PLT only relocation entries
	DT_LOPROC = 0x70000000,	//!< Low Definable
	DT_HIPROC = 0x7FFFFFFF	//!< High Definable
};


int is_elf(char *);
u32 load_elf(char *,process_st *);

int execv(char* file,int argc,char** argv);
void execv_module(u32 entry,int argc,char** argv);

#endif


================================================
FILE: src/kernel/core/env.cc
================================================
#include <os.h>

/*
 *	Definis la structure d'une variable d'environnement
 *	chaque variable est un fichier stoqu dans le dossier virtuel /sys/env
 */

/*
 *	Destructeur de la variable
 */
Variable::~Variable(){
	if (value!=NULL)
		kfree(value);
}

/* 
 *	Constructeur :
 *		n : nom
 *		v : valeur
 */
Variable::Variable(char* n,char* v) : File(n,TYPE_FILE)
{
	fsm.addFile("/sys/env/",this);
	if (v!=NULL){
		io.print("env: create %s (%s) \n",n,v);
		value=(char*)kmalloc(strlen(v)+1);
		memcpy(value,v,strlen(v)+1);
		setSize(strlen(v)+1);
	}
	else{
		value=NULL;
	}
}

u32	Variable::open(u32 flag){
	return RETURN_OK;
}

u32	Variable::close(){
	return RETURN_OK;
}

/* lecture de la valeur dans buffer */
u32	Variable::read(u32 pos,u8* buffer,u32 size){
	if (value==NULL)
		return NOT_DEFINED;
	else{
		strncpy((char*)buffer,value,size);
		return size;		
	}
}

/* ecriture de buffer dans la variable */
u32	Variable::write(u32 pos,u8* buffer,u32 size){
	if (value!=NULL)
		kfree(value);
	value=(char*)kmalloc(size+1);
	memset((char*)value,0,size+1);
	memcpy(value,(char*)buffer,size+1);
	value[size]=0;	//to make sure it's a string
	setSize(size+1);
	return size;
}

/* controle de la variable (TODO) */
u32	Variable::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

/* destruction de la variable */
u32	Variable::remove(){
	delete this;
	return NOT_DEFINED;
}

/* seulement pour les dossiers */
void Variable::scan(){

}



================================================
FILE: src/kernel/core/env.h
================================================
#ifndef ENV_H
#define ENV_H

#include <core/file.h>
#include <runtime/list.h>


class Variable : public File
{
	public:
		Variable(char* n,char* v);
		~Variable();
		
		u32		open(u32 flag);
		u32		close();
		u32		read(u32 pos,u8* buffer,u32 size);
		u32		write(u32 pos,u8* buffer,u32 size);
		u32		ioctl(u32 id,u8* buffer);
		u32		remove();
		void	scan();
		
		
		
		
	protected:
		char*	value;


};

#endif

================================================
FILE: src/kernel/core/file.cc
================================================

#include <os.h>

/* dans myos quasiment tous herite de cette classe */


/*
 *	Remplace dans s tous les a par to
 */
static void strreplace(char* s,char a,char to){
	if (s==NULL)
		return;
	while (*s){
		if (*s==a)
			*s=to;
		s++;
	}
}


u32	File::inode_system=0;	/* numero d'inode de depart */

/* constructeur */
File::File(char* n,u8 t){
	name=(char*)kmalloc(strlen(n)+1);
	memset(name,0,strlen(n));
	memcpy(name,n,strlen(n));
	name[strlen(n)]=0;
	
	checkName();
	master=arch.pcurrent;	// la creation, le maitre est le processus courant
	inode=inode_system;
	inode_system++;
	size=0;
	type=t;
	parent=NULL;
	child=NULL;
	next=NULL;
	prec=NULL;
	link=NULL;
	map_memory=NULL;
}

/* destructeur */
File::~File(){
	kfree(name);
	
	//on modifie la liste des frere
	
	if (prec==NULL){
		parent->setChild(next);
		next->setPrec(NULL);
	}
	else if (next==NULL){
		prec->setNext(NULL);
	}
	else if (next==NULL && prec==NULL){
		parent->setChild(NULL);
	}
	else{
		io.print("prec (%s) next is now %s\n",prec->getName(),next->getName());
		io.print("next (%s) prec is now %s\n",next->getName(),prec->getName());
		prec->setNext(next);
		next->setPrec(prec);
	}
	
	//on supprime les enfant (dossier)
	File* n=child;
	File* nn=NULL;
	while (n!=NULL){
		//io.print("delete %s \n",n->getName());
		nn=n->getNext();
		delete n;
		n=nn;
	}
	
}

#define CAR_REPLACE '_'


void File::checkName(){
	//Adapte le nom
	strreplace(name,'/',CAR_REPLACE);
	strreplace(name,'\ ',CAR_REPLACE);
	strreplace(name,'?',CAR_REPLACE);
	strreplace(name,':',CAR_REPLACE);
	strreplace(name,'>',CAR_REPLACE);
	strreplace(name,'<',CAR_REPLACE);
	strreplace(name,'*',CAR_REPLACE);
	strreplace(name,'"',CAR_REPLACE);
	strreplace(name,':',CAR_REPLACE);
}

u32 File::addChild(File* n){
	if (!n){
		return PARAM_NULL;
	}
	n->setParent(this);
	n->setPrec(NULL);
	n->setNext(child);
	if (child != NULL)
		child->setPrec(n);
	child=n;
	return RETURN_OK;
}

File*	File::createChild(char* n,u8 t){
	File* fp=new File(n,t);
	addChild(fp);
	return fp;
}

File*	File::getParent(){
	return parent;
}

File*	File::getChild(){
	return child;
}

File*	File::getNext(){
	return next;
}

File*	File::getPrec(){
	return prec;
}

File*	File::getLink(){
	return link;
}

u32	File::getSize(){
	return size;
}

u32	File::getInode(){
	return inode;
}

void File::scan(){

}

void	File::setType(u8 t){
	type=t;
}

void	File::setSize(u32 t){
	size=t;
}

void	File::setParent(File* n){
	parent=n;
}

void	File::setLink(File* n){
	link=n;
}

void	File::setChild(File* n){
	child=n;
}

void	File::setNext(File* n){
	next=n;
}

void	File::setPrec(File* n){
	prec=n;
}

void	File::setName(char* n){
	kfree(name);
	name=(char*)kmalloc(strlen(n));
	memcpy(name,n,strlen(n));
	checkName();
}

u8	File::getType(){
	return type;
}

char* File::getName(){
	return name;
}

File* File::find(char* n){
	File* fp=child;
	while (fp!=0){
		if (!strcmp(fp->getName(),n))
			return fp;
		
		fp=fp->next;
	}
	return NULL;
}



u32	File::open(u32 flag){
	return NOT_DEFINED;
}

u32	File::close(){
	return NOT_DEFINED;
}

u32	File::read(u32 pos,u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	File::write(u32 pos,u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	File::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

u32	File::remove(){
	delete this;
	return NOT_DEFINED;
}

stat_fs File::stat(){
	stat_fs st;
	
	return st;
}

u32 File::mmap(u32 sizee,u32 flags,u32 offset,u32 prot){
	if (map_memory!=NULL){
		int i=0;
		unsigned int adress;
		struct page *pg;
		process_st* current=(arch.pcurrent)->getPInfo();
		for (i=0;i<sizee;i++){
				adress=(unsigned int)(map_memory+i*PAGESIZE);
				//io.print("mmap : %x %d\n",adress,sizee);
				pg = (struct page *) kmalloc(sizeof(struct page));
				pg->p_addr = (char*) (adress);
				pg->v_addr = (char *) (adress & 0xFFFFF000);
				list_add(&pg->list, &current->pglist);
				pd_add_page(pg->v_addr, pg->p_addr, PG_USER, current->pd);
		}
		return (u32)map_memory;
	}
	else{
		return -1;
	}
}



================================================
FILE: src/kernel/core/file.h
================================================

#ifndef FILE_H
#define FILE_H

#include <runtime/types.h>

enum{
	TYPE_FILE,
	TYPE_DIRECTORY,
	TYPE_DEVICE,
	TYPE_PROCESS,
	TYPE_LINK
};


class File
{
	public:
		File(char* n,u8 t);
		~File();
		
		virtual u32		open(u32 flag);
		virtual u32		close();
		virtual u32		read(u32 pos,u8* buffer,u32 size);
		virtual u32		write(u32 pos,u8* buffer,u32 size);
		virtual u32		ioctl(u32 id,u8* buffer);
		virtual u32		remove();
		virtual void	scan();
		
		
		void	checkName();
		
		u32		addChild(File* n);
		File*	createChild(char* n,u8 t);
		File* 	find(char* n);
		u32 	mmap(u32 sizee,u32 flags,u32 offset,u32 prot);
		
		void	setSize(u32 t);
		void	setType(u8 t);
		void	setParent(File* n);
		void	setChild(File* n);
		void	setNext(File* n);
		void	setPrec(File* n);
		void	setLink(File* n);
		void	setName(char* n);
		
		char*	getName();
		File*	getParent();
		File*	getChild();
		File*	getNext();
		File*	getPrec();
		File*	getLink();
		u8		getType();
		u32		getSize();
		u32		getInode();
		
		stat_fs stat();
		
	protected:
		static u32 inode_system;
	
		char*	map_memory;	/* to mmap */
		
		char*	name;		/* Nom du fichier	*/
		u32		size;		/* Taille du fichier */
		u8		type;		/* Type de fichier */
		u32		inode;		/* Inode du fichier */
		File*	dev;		/* the master device, example : /dev/hda */
		File*	link;		/* the real file, if this file is a link */
		
		
		File*	master;	/* processus maitre ou NULL */
		
		File*	parent;
		File*	child;
		File*	next;
		File*	prec;
		
		File*	device;		/* This file is the device master of the current file */
};

#endif


================================================
FILE: src/kernel/core/filesystem.cc
================================================

#include <os.h>

/*
Cette classe organise les fichiers entre eux
*/

Filesystem::Filesystem(){

}

void Filesystem::init(){
	root=new File("/",TYPE_DIRECTORY);
	
	dev=root->createChild("dev",TYPE_DIRECTORY);		//dossier contenant les peripherique
	root->createChild("proc",TYPE_DIRECTORY);			//dossier contenant les processus tournant
	root->createChild("mnt",TYPE_DIRECTORY);			//dossier contenant les points de montages des disques
	File* sysd=root->createChild("sys",TYPE_DIRECTORY);	//dossier contenant toutes les infos du systemes
		var=sysd->createChild("env",TYPE_DIRECTORY);		//dossier contenant toutes les variables d'environnement
		sysd->createChild("usr",TYPE_DIRECTORY);		//dossier contenant tous les utilisateurs
		sysd->createChild("mods",TYPE_DIRECTORY);		//dossier contenant tous les modules disponiles
		sysd->createChild("sockets",TYPE_DIRECTORY);	//dossier contenant tous les sockets actuels
}

Filesystem::~Filesystem(){
	delete root;
}

void Filesystem::mknod(char* module,char* name,u32 flag){
	modm.createDevice(name,module,flag);
}

File* Filesystem::getRoot(){
	return root;
}

File* Filesystem::path(char* p){
	if (!p)
		return NULL;
		
	File* fp=root;
	char *name, *beg_p, *end_p;
	
	if (p[0]=='/')
		fp=root;
	else{
		if (arch.pcurrent!=NULL)		/* prend de le dossier actuel du fichier */
			fp=(arch.pcurrent)->getCurrentDir();
	}
	beg_p = p;
	while (*beg_p == '/')
		beg_p++;
	end_p = beg_p + 1;
	
	while (*beg_p != 0) {
		if (fp->getType() != TYPE_DIRECTORY){
			return NULL;
		}
		while (*end_p != 0 && *end_p != '/')
			end_p++;
		name = (char *) kmalloc(end_p - beg_p + 1);
		memcpy(name, beg_p, end_p - beg_p);
		name[end_p - beg_p] = 0;

		if (strcmp("..", name) == 0) {		// '..' 
			fp = fp->getParent();
		} else if (strcmp(".", name) == 0) {	// '.' 
		
		} else {
			fp->scan();
			if (!(fp = fp->find(name))) {
				kfree(name);
				return 0;
			}
			
			if (fp->getType()==TYPE_LINK && (fp->getLink()!=NULL)){
				fp=fp->getLink();
			}
		}

		beg_p = end_p;
		while (*beg_p == '/')
			beg_p++;
		end_p = beg_p + 1;

		kfree(name);
	}
	
	return fp;
}

File* Filesystem::pivot_root(File* targetdir){
	if (targetdir == NULL)
		return root;
	else
	{
	  File* newRoot = new File("/",TYPE_DIRECTORY);
	  File* mainChild = targetdir->getChild();
	  newRoot->addChild(mainChild);
	  s8 i, ii = 0;
	  File* tempChild = mainChild->getPrec(); //Est que File doit tre initialis ? ou pas ?
	      do
	      {
		  if(tempChild == NULL)
		  {
		    i = 0;
		  }
		  else
		  {
		    newRoot->addChild(tempChild);
		    tempChild = tempChild->getPrec();
		  }
	      }while(i == 1);
	       tempChild = mainChild->getNext();
	      i = 1;
	      do
	      {
		  if(tempChild == NULL)
		    i = 0;
		  else
		  {
		    newRoot->addChild(tempChild);
		    tempChild = tempChild->getNext();
		  }
	      }while(i == 1);
	return newRoot;
	}
 
}

File* Filesystem::path_parent(char* p,char *fname){
	if (!p)
		return NULL;
	File* ofp;
	File* fp=root;
	char *name, *beg_p, *end_p;
	
	if (p[0]=='/')
		fp=root;
		
	beg_p = p;
	while (*beg_p == '/')
		beg_p++;
	end_p = beg_p + 1;
	
	while (*beg_p != 0) {
		if (fp->getType() != TYPE_DIRECTORY)
			return NULL;

		while (*end_p != 0 && *end_p != '/')
			end_p++;
		name = (char *) kmalloc(end_p - beg_p + 1);
		memcpy(name, beg_p, end_p - beg_p);
		name[end_p - beg_p] = 0;


		if (strcmp("..", name) == 0) {		// '..' 
			fp = fp->getParent();
		} else if (strcmp(".", name) == 0) {	// '.' 
		
		} else {
			ofp=fp;
			
			if (fp->getType()==TYPE_LINK && (fp->getLink()!=NULL)){
				fp=fp->getLink();
			}
			
			if (!(fp = fp->find(name))) {
				strcpy(fname,name);
				kfree(name);
				return ofp;
			}
		
		}

		beg_p = end_p;
		while (*beg_p == '/')
			beg_p++;
		end_p = beg_p + 1;

		kfree(name);
	}
	
	return fp;
}

u32 Filesystem::link(char* fname,char *newf){

	File*tolink=path(fname);
	if (tolink==NULL)
		return -1;

	char* nname=(char*)kmalloc(255);
	File* par=path_parent(newf,nname);
	File* fp=new File(nname,TYPE_LINK);
	fp->setLink(tolink);
	par->addChild(fp);
	return RETURN_OK;
}


u32 Filesystem::addFile(char* dir,File* fp){
	File* fdir=path(dir);
	if (fdir==NULL)
		return ERROR_PARAM;
	else{
		return fdir->addChild(fp);
	}
}





================================================
FILE: src/kernel/core/filesystem.h
================================================

#ifndef FILESYSTEM_H
#define FILESYSTEM_H

#include <runtime/types.h>
#include <core/file.h>


class Filesystem
{
	public:
		Filesystem();
		~Filesystem();
		
		void 	init();
		void	mknod(char* module,char* name,u32 flag);
		
		File* 	path(char* p);
		File* 	path_parent(char* p,char *fname);
		
		u32		link(char* fname,char *newf);
		
		
		u32 	addFile(char* dir,File* fp);
		
		File* 	pivot_root(File* targetdir);
		
		File*	getRoot();
		
	private:
		File*	root;
		File*	dev;
		File*	var;
};

extern Filesystem		fsm;
#endif


================================================
FILE: src/kernel/core/kernel.cc
================================================

#include <os.h>
#include <boot.h>


static char* init_argv[2]={"init","-i"};

/* charge les modules de depart */
static void load_modules(multiboot_info* mbi){
	
	if (mbi->mods_count>0){
		u32 initrd_location = *((u32*)mbi->mods_addr);
		u32 initrd_end = *(u32*)(mbi->mods_addr+4);
		u32	initrd_size=initrd_end-initrd_location;
		io.print(" >load module:  location=%x, size=%d \n",initrd_location,initrd_end-initrd_location);
		int i=0;
		unsigned int adress;
	
		for (i=0;i<(initrd_size/4072)+1;i++){	
				adress=(initrd_location+i*4096);
				vmm.kmap(adress,adress);
		}
		execv_module(initrd_location,1,init_argv);
	}
}


/* le main du noyau */
extern "C" void kmain(multiboot_info* mbi){
	io.clear();
	io.print("%s - %s -- %s %s \n",	KERNEL_NAME,
									KERNEL_VERSION,
									KERNEL_DATE,
									KERNEL_TIME);
	
	io.print("%s \n",KERNEL_LICENCE);
	arch.init();
	
	io.print("Loading Virtual Memory Management \n");
	vmm.init(mbi->high_mem);
	
	io.print("Loading FileSystem Management \n");
	fsm.init();
	
	io.print("Loading syscalls interface \n");
	syscall.init();
	
	io.print("Loading system \n");
	sys.init();
	
	io.print("Loading modules \n");
	modm.init();
	modm.initLink();


	modm.install("hda0","module.dospartition",0,"/dev/hda");
	modm.install("hda1","module.dospartition",1,"/dev/hda");
	modm.install("hda2","module.dospartition",2,"/dev/hda");
	modm.install("hda3","module.dospartition",3,"/dev/hda");
	modm.mount("/dev/hda0","boot","module.ext2",NO_FLAG);

	arch.initProc();
	
	io.print("Loading binary modules \n");
	load_modules(mbi);
	
	fsm.link("/mnt/boot/bin/","/bin/");

	
	io.print("\n");
	io.print("  ==== System is ready (%s - %s) ==== \n",KERNEL_DATE,KERNEL_TIME);
	arch.enable_interrupt();
	for (;;);
	arch.shutdown();
}



================================================
FILE: src/kernel/core/kernel.h
================================================

#ifndef KERNEL_H
#define KERNEL_H

#include <runtime/alloc.h>
#include <runtime/libc.h>
#include <runtime/string.h>


#include <core/file.h>
#include <core/filesystem.h>
#include <core/elf_loader.h>
#include <core/syscalls.h>
#include <core/env.h>
#include <core/user.h>
#include <core/modulelink.h>
#include <core/device.h>
#include <core/socket.h>
#include <core/system.h>


#include <module.h>


#include <io.h>
#include <architecture.h>
#include <vmm.h>
#include <process.h>

#endif


================================================
FILE: src/kernel/core/keyboard.h
================================================


#ifndef __KBD__
#define __KBD__

#include <api/dev/tty.h>

char kbdmap_default[] = {
	KEY_ESCAPE, KEY_ESCAPE, KEY_ESCAPE, KEY_ESCAPE,	/*      esc     (0x01)  */
	'1', '!', '1', '1',
	'2', '@', '2', '2',
	'3', '#', '3', '3',
	'4', '$', '4', '4',
	'5', '%', '5', '5',
	'6', ':', '6', '6',
	'7', '&', '7', '7',
	'8', '*', '8', '8',
	'9', '(', '9', '9',
	'0', ')', '0', '0',
	'-', '_', '-', '-',
	'=', '+', '=', '=',
	0x08, 0x08, 0x7F, 0x08,	/*      backspace       */
	0x09, 0x09, 0x09, 0x09,	/*      tab     */
	'a', 'A', 'a', 'a',
	'z', 'Z', 'z', 'z',
	'e', 'E', 'e', 'e',
	'r', 'R', 'r', 'r',
	't', 'T', 't', 't',
	'y', 'Y', 'y', 'y',
	'u', 'U', 'u', 'u',
	'i', 'I', 'i', 'i',
	'o', 'O', 'o', 'o',
	'p', 'P', 'p', 'p',
	'^', '"', '^', '^',
	'$', '£', ' ', '$',
	0x0A, 0x0A, 0x0A, 0x0A,	/*      enter   */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      ctrl    */
	'q', 'Q', 'q', 'q',
	's', 'S', 's', 's',
	'd', 'D', 'd', 'd',
	'f', 'F', 'f', 'f',
	'g', 'G', 'g', 'g',
	'h', 'H', 'h', 'h',
	'j', 'J', 'j', 'j',
	'k', 'K', 'k', 'k',
	'l', 'L', 'l', 'l',
	'm', 'M', 'm', 'm',
	0x27, 0x22, 0x27, 0x27,	/*      '"      */
	'*', '~', '`', '`',	/*      `~      */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      Lshift  (0x2a)  */
	'<', '>', '\\', '\\',
	'w', 'W', 'w', 'w',
	'x', 'X', 'x', 'x',
	'c', 'C', 'c', 'c',
	'v', 'V', 'v', 'v',
	'b', 'B', 'b', 'b',
	'n', 'N', 'n', 'n',
	',', '?', ',', ',',
	0x2C, 0x3C, 0x2C, 0x2C,	/*      ,<      */
	0x2E, 0x3E, 0x2E, 0x2E,	/*      .>      */
	0x2F, 0x3F, 0x2F, 0x2F,	/*      /?      */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      Rshift  (0x36)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x37)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x38)  */
	' ', ' ', ' ', ' ',	/*      space   */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x3a)  */
	KEY_F1, 0xFF, 0xFF, 0xFF,	/*      (0x3b)  */
	KEY_F2, 0xFF, 0xFF, 0xFF,	/*      (0x3c)  */
	KEY_F3, 0xFF, 0xFF, 0xFF,	/*      (0x3d)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x3e)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x3f)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x40)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x41)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x42)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x43)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x44)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x45)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x46)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x47)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x48)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x49)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x4a)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x4b)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x4c)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x4d)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x4e)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x4f)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x50)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x51)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x52)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x53)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x54)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x55)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x56)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x57)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x58)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x59)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x5a)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x5b)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x5c)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x5d)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x5e)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x5f)  */
	0xFF, 0xFF, 0xFF, 0xFF,	/*      (0x60)  */
	0xFF, 0xFF, 0xFF, 0xFF	/*      (0x61)  */
};

char* kbdmap=kbdmap_default;

#endif


================================================
FILE: src/kernel/core/modulelink.cc
================================================

#include <os.h>



ModLink::~ModLink(){
	
}

ModLink::ModLink(char* n) : File(n,TYPE_FILE)
{
	fsm.addFile("/sys/mods/",this);
}

u32	ModLink::open(u32 flag){
	return RETURN_OK;
}

u32	ModLink::close(){
	return RETURN_OK;
}

u32	ModLink::read(u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	ModLink::write(u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	ModLink::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

u32	ModLink::remove(){
	delete this;
}

void ModLink::scan(){

}



================================================
FILE: src/kernel/core/modulelink.h
================================================

#ifndef MODLINK_H
#define MODLINK_H

#include <core/file.h>
#include <runtime/list.h>


class ModLink : public File
{
	public:
		ModLink(char* n);
		~ModLink();
		
		u32		open(u32 flag);
		u32		close();
		u32		read(u8* buffer,u32 size);
		u32		write(u8* buffer,u32 size);
		u32		ioctl(u32 id,u8* buffer);
		u32		remove();
		void	scan();
		
		
		
		
	protected:

};

#endif


================================================
FILE: src/kernel/core/os.h
================================================
#ifndef OS_H
#define OS_H

#include <config.h>
#include <kernel.h>


typedef File* (*device_driver)	(char* name,u32 flag,File* dev);

struct module_class{
	int					module_type;
	char*			module_name;
	char*			class_name;
	device_driver	drive;
};




/*
 *	Module Macro
 */
#define MODULE_DEVICE		0
#define MODULE_FILESYSTEM	1
#define module(name,type,classe,mknod)	module_class classe##_module={type,\
																name, \
																#classe, \
																(device_driver)mknod};	

#define import_module(classe) 	extern module_class  classe##_module

#define run_module_builder	module_class* module_builder[]=
#define build_module(classe) 	&classe##_module
#define end_module() 		NULL

#define std_buildin_module	void Module::init()
#define	run_module(n,m,f) createDevice(#m,#n,f);

/*
 *	Asm Macro
 */
#define asm 		__asm__
#define asmv 		__asm__ __volatile__



#endif


================================================
FILE: src/kernel/core/process.cc
================================================

#include <os.h>
#include <api/dev/proc.h>

/* Definis un process (/dev/proc) */

char* Process::default_tty="/dev/tty";

u32 Process::proc_pid=0;

Process::~Process(){
	delete ipc;
	arch.change_process_father(this,pparent);	//on change le pere des enfants	
}

Process::Process(char* n) : File(n,TYPE_PROCESS)
{
	fsm.addFile("/proc/",this);
	pparent=arch.pcurrent;
	pid=proc_pid;
	proc_pid++;
	if (pparent!=NULL)
		cdir=pparent->getCurrentDir();
	else
		cdir=fsm.getRoot();
		
	arch.addProcess(this);
	info.vinfo=(void*)this;
	int i;
	for (i=0;i<CONFIG_MAX_FILE;i++){	//open files
		openfp[i].fp=NULL;
	}
	ipc= new Buffer();	//ipc buffer
}

u32	Process::open(u32 flag){
	return RETURN_OK;
}

u32	Process::close(){
	return RETURN_OK;
}

Process* Process::getPParent(){
	return pparent;
}

void Process::setPParent(Process*p){
	pparent=p;
}

u32	Process::read(u32 pos,u8* buffer,u32 sizee){
	u32 ret=RETURN_OK;
	arch.enable_interrupt();
	while (ipc->isEmpty());
	ret=ipc->get(buffer,sizee);
	
	arch.disable_interrupt();
	return ret;
}

u32	Process::write(u32 pos,u8* buffer,u32 sizee){
	ipc->add(buffer,sizee);
	return size;
}

u32	Process::ioctl(u32 id,u8* buffer){
	u32 ret;
	switch (id){
		case API_PROC_GET_PID:
			ret= pid;
			break;
			
		case API_PROC_GET_INFO:
			reset_pinfo();
			memcpy((char*)buffer,(char*)&ppinfo,sizeof(proc_info));
			break;
			
			
		default:
			ret=NOT_DEFINED;
			break;
	}
	
	return ret;
}

int	Process::fork(){
	/*Process* p=new Process("fork_child");
	return arch.fork(p->getPInfo(),&info);*/
	if (pparent!=NULL)
		pparent->sendSignal(SIGCHLD);	
	return 0;
}

u32	Process::wait(){
	arch.enable_interrupt();
	while (is_signal(info.signal, SIGCHLD)==0);
	clear_signal(&(info.signal), SIGCHLD);
	arch.destroy_all_zombie();
	arch.disable_interrupt();
	return 1;
}

u32	Process::remove(){
	delete this;
	return RETURN_OK;
}

void Process::scan(){

}

void Process::exit(){
	setState(ZOMBIE);
	if (pparent!=NULL)
		pparent->sendSignal(SIGCHLD);
}

void Process::setPNext(Process* p){
	pnext=p;
}

process_st* Process::getPInfo(){
	return &info;
}

Process* Process::getPNext(){
	return pnext;
}

u32 Process::create(char* file, int argc, char **argv){
	int ret=arch.createProc(&info,file,argc,argv);
	if (ret==1)
		setState(CHILD);
	else
		setState(ZOMBIE);
		
	//stdin stdout et stderr du parent
	if (pparent!=NULL){
		memcpy((char*)&openfp[0],(char*)pparent->getFileInfo(0),sizeof(openfile));
		memcpy((char*)&openfp[1],(char*)pparent->getFileInfo(1),sizeof(openfile));
		memcpy((char*)&openfp[2],(char*)pparent->getFileInfo(2),sizeof(openfile));
		addFile(this,0);
	}
	else{
		addFile(fsm.path(default_tty),0);
		addFile(fsm.path(default_tty),0);
		addFile(fsm.path(default_tty),0);
		
	}
	
	return RETURN_OK;
}

void Process::setFile(u32 fd,File* fp,u32 ptr, u32 mode){
	if (fd<0 || fd>CONFIG_MAX_FILE)
		return;
	openfp[fd].fp=fp;
	openfp[fd].ptr=ptr;
	openfp[fd].mode=mode;
}

u32 Process::addFile(File* f,u32 m){
	int i;
	for (i=0;i<CONFIG_MAX_FILE;i++){
		if (openfp[i].fp==NULL && f!=NULL){
			//io.print("%s:  add %s in %d\n",name,f->getName(),i);
			openfp[i].fp=f;
			openfp[i].mode=m;
			openfp[i].ptr=0;
			return i;
		}
	}
}

File* Process::getFile(u32 fd){
	if (fd<0 || fd>CONFIG_MAX_FILE)
		return NULL;
	return openfp[fd].fp;
}

openfile* Process::getFileInfo(u32 fd){
	if (fd<0 || fd>CONFIG_MAX_FILE)
		return NULL;
	return &openfp[fd];
}

void Process::deleteFile(u32 fd){
	if (fd<0 || fd>CONFIG_MAX_FILE)
		return;
	openfp[fd].fp=NULL;
	openfp[fd].mode=0;
	openfp[fd].ptr=0;
}

Process* Process::schedule(){
	Process* n=this;
	int out=1;
	n=n->getPNext();
	while (out){
		
		if (n==NULL){
			n=arch.plist;
		}
		//io.print("testing %s\n",n->getName());
		
		
		if (n->getState() !=ZOMBIE){
			out=0;
		}
		else{
			n=n->getPNext();
		}
		
	}
	
	arch.pcurrent=n;
	
	return n;
}


File* Process::getCurrentDir(){
	return cdir;
}

void Process::setCurrentDir(File* f){
	cdir=f;
}



void Process::setState(u8 st){
	state=st;
}

u8	Process::getState(){
	return state;
}


void Process::setPid(u32 st){
	pid=st;
}

u32	Process::getPid(){
	return pid;
}

void Process::sendSignal(int sig){
	set_signal(&(info.signal),sig);
}

void Process::reset_pinfo(){
	strncpy(ppinfo.name,name,32);
	ppinfo.pid=pid;
	ppinfo.tid=0;
	ppinfo.state=state;
	ppinfo.vmem=10*1024*1024;
	ppinfo.pmem=10*1024*1024;
}



================================================
FILE: src/kernel/core/process.h
================================================

#ifndef PROC_H
#define PROC_H

#include <core/file.h>
#include <runtime/list.h>
#include <archprocess.h>	/* definition de process_st */

#include <core/signal.h>

#include <runtime/buffer.h>

#include <api/dev/proc.h>

#define ZOMBIE	PROC_STATE_ZOMBIE
#define CHILD	PROC_STATE_RUN

struct openfile
{
	u32				mode;	/* Mode d'ouverture */
	u32				ptr;	/* Pointeur de lecture/ecriture */
	File*			fp;		/* Fichier ouvert */
};

class Process : public File
{
	public:
		Process(char* n);
		~Process();
		
		u32		open(u32 flag);
		u32		close();
		u32		read(u32 pos,u8* buffer,u32 size);
		u32		write(u32 pos,u8* buffer,u32 size);
		u32		ioctl(u32 id,u8* buffer);
		u32		remove();
		void	scan();
		
		
		u32		create(char* file, int argc, char **argv);
		void	sendSignal(int sig);
		u32		wait();
		
		u32 	addFile(File* fp,u32 m);
		File*	getFile(u32 fd);
		void	deleteFile(u32 fd);
		openfile*	getFileInfo(u32 fd);
		
		void	exit();
		int		fork();
		
		
		void	setState(u8 st);
		u8		getState();
		void	setFile(u32 fd,File* fp,u32 ptr, u32 mode);
		void	setPid(u32 st);
		u32		getPid();
		
		void			setPNext(Process* p);
		
		Process* 		schedule();
		Process*		getPNext();
		Process*		getPParent();
		process_st* 	getPInfo();
		void			setPParent(Process*p);
		
		void			reset_pinfo();
		
		process_st		info;
		
		File*	getCurrentDir();
		void	setCurrentDir(File* f);
		
	protected:
		static u32	proc_pid;
		
		u32 		pid;
		u8			state;
		Process*	pparent;
		Process*	pnext;
		openfile	openfp[CONFIG_MAX_FILE];
		proc_info	ppinfo;
		File*		cdir;
		
		Buffer*		ipc;
		
		static char*	default_tty;

};


#endif


================================================
FILE: src/kernel/core/signal.h
================================================

#ifndef SIGNAL_H
#define SIGNAL_H


#include <runtime/types.h>
#include <process.h>

	#define SIGHUP    1       /* Hangup (POSIX).  */
	#define SIGINT    2       /* Interrupt (ANSI).  */
	#define SIGQUIT   3       /* Quit (POSIX).  */
	#define SIGILL    4       /* Illegal instruction (ANSI).  */
	#define SIGTRAP   5       /* Trace trap (POSIX).  */
	#define SIGABRT   6       /* Abort (ANSI).  */
	#define SIGIOT    6       /* IOT trap (4.2 BSD).  */
	#define SIGBUS    7       /* BUS error (4.2 BSD).  */
	#define SIGFPE    8       /* Floating-point exception (ANSI).  */
	#define SIGKILL   9       /* Kill, unblockable (POSIX).  */
	#define SIGUSR1   10      /* User-defined signal 1 (POSIX).  */
	#define SIGSEGV   11      /* Segmentation violation (ANSI).  */
	#define SIGUSR2   12      /* User-defined signal 2 (POSIX).  */
	#define SIGPIPE   13      /* Broken pipe (POSIX).  */
	#define SIGALRM   14      /* Alarm clock (POSIX).  */
	#define SIGTERM   15      /* Termination (ANSI).  */
	#define SIGSTKFLT 16      /* Stack fault.  */
	#define SIGCLD    SIGCHLD /* Same as SIGCHLD (System V).  */
	#define SIGCHLD   17      /* Child status has changed (POSIX).  */
	#define SIGCONT   18      /* Continue (POSIX).  */
	#define SIGSTOP   19      /* Stop, unblockable (POSIX).  */
	#define SIGTSTP   20      /* Keyboard stop (POSIX).  */
	#define SIGTTIN   21      /* Background read from tty (POSIX).  */
	#define SIGTTOU   22      /* Background write to tty (POSIX).  */
	#define SIGURG    23      /* Urgent condition on socket (4.2 BSD).  */
	#define SIGXCPU   24      /* CPU limit exceeded (4.2 BSD).  */
	#define SIGXFSZ   25      /* File size limit exceeded (4.2 BSD).  */
	#define SIGVTALRM 26      /* Virtual alarm clock (4.2 BSD).  */
	#define SIGPROF   27      /* Profiling alarm clock (4.2 BSD).  */
	#define SIGWINCH  28      /* Window size change (4.3 BSD, Sun).  */
	#define SIGPOLL   SIGIO   /* Pollable event occurred (System V).  */
	#define SIGIO     29      /* I/O now possible (4.2 BSD).  */
	#define SIGPWR    30      /* Power failure restart (System V).  */
	#define SIGSYS    31      /* Bad system call.  */

	#define SIGEVENT	SIGPOLL
	#define SIGIPC		SIGUSR1
	
	
	
	#define SIG_DFL		0	/* default signal handling */
	#define SIG_IGN		1	/* ignore signal */

	#define set_signal(mask, sig)	*(mask) |= ((u32) 1 << (sig - 1))
	#define clear_signal(mask, sig)	*(mask) &= ~((u32) 1 << (sig - 1))
	#define is_signal(mask, sig)	(mask & ((u32) 1 << (sig - 1)))




#endif


================================================
FILE: src/kernel/core/socket.cc
================================================

#include <os.h>



Socket::~Socket(){
	
}

Socket::Socket(char* n) : File(n,TYPE_FILE)
{
	fsm.addFile("/sys/sockets/",this);
}

u32	Socket::open(u32 flag){
	return RETURN_OK;
}

u32	Socket::close(){
	return RETURN_OK;
}

u32	Socket::read(u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	Socket::write(u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	Socket::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

u32	Socket::remove(){
	delete this;
}

void Socket::scan(){

}



================================================
FILE: src/kernel/core/socket.h
================================================

#ifndef SOCKET_H
#define SOCKET_H

#include <core/file.h>
#include <runtime/list.h>


class Socket : public File
{
	public:
		Socket(char* n);
		~Socket();
		
		u32		open(u32 flag);
		u32		close();
		u32		read(u8* buffer,u32 size);
		u32		write(u8* buffer,u32 size);
		u32		ioctl(u32 id,u8* buffer);
		u32		remove();
		void	scan();
		
		
		
		
	protected:

};

#endif


================================================
FILE: src/kernel/core/syscalls.cc
================================================

#include <os.h>
#include <api.h>

#include <api/kernel/syscall_table.h>

#define sysc(a,h) add(a,(syscall_handler)h)

void Syscalls::init(){
	int i;
	for (i=0;i<NB_SYSCALLS;i++)
		calls[i]=NULL;
	sysc(SYS_open,		&call_open);
	sysc(SYS_close,		&call_close);
	sysc(SYS_read,		&call_read);
	sysc(SYS_write,		&call_write);
	sysc(SYS_sbrk,		&call_sbrk);
	sysc(SYS_ioctl,		&call_ioctl);
	sysc(SYS_exit,		&call_exit);
	sysc(SYS_execve,	&call_execv);
	sysc(SYS_symlink,	&call_symlink);
	sysc(SYS_getdents,	&call_getdents);
	sysc(SYS_wait4,		&call_wait);
	sysc(SYS_dup2,		&call_dup2);
	sysc(SYS_fork,		&call_fork);
	sysc(SYS_chdir,		&call_chdir);
	sysc(SYS_mmap,		&call_mmap);
}


void Syscalls::add(u32 num,syscall_handler h){
	calls[num]=h;
}

void Syscalls::call(u32 num){
	if (calls[num]!=NULL)
		calls[num]();
}


================================================
FILE: src/kernel/core/syscalls.h
================================================

#ifndef SYSCALL_H
#define SYSCALL_H

#include <core/file.h>
#include <runtime/list.h>


#define NB_SYSCALLS	100


typedef void (*syscall_handler)(void);

class Syscalls 
{
	public:
		void	init();
		void	add(u32 num,syscall_handler h);
		void	call(u32 num);
		
	protected:
		syscall_handler		calls[NB_SYSCALLS];

};

extern Syscalls	syscall;

#endif


================================================
FILE: src/kernel/core/system.cc
================================================

#include <os.h>

/**
 *	10/04/06 (Samy Pess) : creation du fichier
 *							ajout gestion login et variable d'environnement
 *	10/04/07 (Samy Pess) : la classe System gere maintenant une liste chain des utilisateur (User)
 **/
 


/*
Cette classe organise le systeme en lui meme : utilisateur, variable, ...
*/

System::System(){
	
}

System::~System(){

}


void System::init(){
	var=fsm.path("/sys/env/");

	/** System user **/
	root=new User("root");
	root->setUType(USER_ROOT);
	
	actual=new User("liveuser");

	
	/** Environnement variable **/
	uservar=new Variable("USER","liveuser");
	new Variable("OS_NAME",KERNEL_NAME);
	new Variable("OS_VERSION",KERNEL_VERSION);
	new Variable("OS_DATE",KERNEL_DATE);
	new Variable("OS_TIME",KERNEL_TIME);
	new Variable("OS_LICENCE",KERNEL_LICENCE);
	new Variable("COMPUTERNAME",KERNEL_COMPUTERNAME);
	new Variable("PROCESSOR_IDENTIFIER",KERNEL_PROCESSOR_IDENTIFIER);
	new Variable("PROCESSOR_NAME",arch.detect());
	new Variable("PATH","/bin/");
	new Variable("SHELL","/bin/sh");
}

//fonction de login
int	System::login(User* us,char* pass){
	if (us==NULL)
		return ERROR_PARAM;
	if (us->getPassword() != NULL){	//si il ya un password
		
		if (pass==NULL)	//si on a pass un code
			return PARAM_NULL;
			//
		if (strncmp(pass,us->getPassword(),strlen(us->getPassword())))	//test password
			return RETURN_FAILURE;
		//io.print("login %s with %s (%s)\n",us->getName(),pass,us->getPassword());
	}
		
	uservar->write(0,(u8*)us->getName(),strlen(us->getName()));
	actual=us;
	return RETURN_OK;
}

/* ne pas oubliez de faire un free de la variable */
char* System::getvar(char* name){
	char* varin;
	File* temp=var->find(name);
	if (temp==NULL){
		return NULL;
	}
	varin=(char*)kmalloc(temp->getSize());
	memset(varin,0,temp->getSize());
	temp->read(0,(u8*)varin,temp->getSize());
	return varin;
}

User* System::getUser(char* nae){
	User* us=listuser;
	while (us!=NULL){
		//io.print("test '%s' with '%s'\n",nae,us->getName());
		if (!strncmp(nae,us->getName(),strlen(us->getName())))
			return us;
		us=us->getUNext();
	}
	return NULL;
}

void System::addUserToList(User* us){
	if (us==NULL)
		return;
	us->setUNext(listuser);
	listuser=us;
}

u32 System::isRoot(){
	if (actual!=NULL){
		if (actual->getUType() == USER_ROOT)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}


================================================
FILE: src/kernel/core/system.h
================================================

#ifndef SYSTEM_H
#define SYSTEM_H

#include <runtime/types.h>
#include <core/env.h>
#include <core/user.h>


class System
{
	public:
		System();
		~System();
		
		void	init();
		char*	getvar(char* name);
		
		
		void	addUserToList(User* us);
		
		User*	getUser(char* nae);
		
		int		login(User* us,char* pass);
		u32 	isRoot();			//renvoie 1 si root
		
		
	private:
		User*		listuser;
	
		File*		var;
		
		User*		actual;
		User*		root;
		
		Variable*	uservar;
};

extern System		sys;
#endif


================================================
FILE: src/kernel/core/user.cc
================================================

#include <os.h>



User::~User(){
	
}

User::User(char* n) : File(n,TYPE_FILE)
{
	fsm.addFile("/sys/usr/",this);
	unext=0;
	sys.addUserToList(this);
	utype=USER_NORM;
	memset(password,0,512);
}

u32	User::open(u32 flag){
	return RETURN_OK;
}

u32	User::close(){
	return RETURN_OK;
}

u32	User::read(u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	User::write(u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	User::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

u32	User::remove(){
	delete this;
}

void User::scan(){

}

void User::setPassword(char *n){
	if (n!=NULL)
		return;
	memset(password,0,512);
	strcpy(password,n);
}

char* User::getPassword(){
	if (password[0]=0)
		return NULL;
	else
		return password;
}

User* User::getUNext(){
	return unext;
}

void User::setUNext(User* us){
	unext=us;
}

void User::setUType(u32 t){
	utype=t;
}

u32	User::getUType(){
	return utype;
}



================================================
FILE: src/kernel/core/user.h
================================================

#ifndef USER_H
#define USER_H

#include <core/file.h>
#include <runtime/list.h>


enum {
	USER_ROOT,	//root
	USER_NORM	//utilisateur normal
};

class User : public File
{
	public:
		User(char* n);
		~User();
		
		u32		open(u32 flag);
		u32		close();
		u32		read(u8* buffer,u32 size);
		u32		write(u8* buffer,u32 size);
		u32		ioctl(u32 id,u8* buffer);
		u32		remove();
		void	scan();
		
		
		void	setPassword(char *n);
		char*	getPassword();
		
		User*	getUNext();
		void	setUNext(User* us);
		
		void	setUType(u32 t);
		u32		getUType();
		
	protected:
		u32		utype;
	
		User*	unext;
		char	password[512];
		
};

#endif


================================================
FILE: src/kernel/modules/Makefile
================================================
OBJS:=  $(OBJS) modules/module.o \
		modules/null.o modules/stdtty.o modules/x86serial.o\
		modules/ide.o modules/bochsvbe.o \
		modules/ext2.o modules/dospartition.o \
		modules/clock_x86.o modules/keys.o



================================================
FILE: src/kernel/modules/bochsvbe.cc
================================================

#include <os.h>
#include <bochsvbe.h>

/* Driver video pour bios VBE/Bios */


static void BgaWriteRegister(unsigned short IndexValue, unsigned short DataValue)
{
    io.outw(VBE_DISPI_IOPORT_INDEX, IndexValue);
    io.outw(VBE_DISPI_IOPORT_DATA, DataValue);
}
 
static unsigned short BgaReadRegister(unsigned short IndexValue)
{
    io.outw(VBE_DISPI_IOPORT_INDEX, IndexValue);
    return io.inw(VBE_DISPI_IOPORT_DATA);
}
 
static int BgaIsAvailable(void)
{
    return (BgaReadRegister(VBE_DISPI_INDEX_ID) == VBE_DISPI_ID4);
}
 
static void BgaSetVideoMode(unsigned int Width, unsigned int Height, unsigned int BitDepth, int UseLinearFrameBuffer, int ClearVideoMemory)
{
    BgaWriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
    BgaWriteRegister(VBE_DISPI_INDEX_XRES, Width);
    BgaWriteRegister(VBE_DISPI_INDEX_YRES, Height);
    BgaWriteRegister(VBE_DISPI_INDEX_BPP, BitDepth);
    BgaWriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED |
        (UseLinearFrameBuffer ? VBE_DISPI_LFB_ENABLED : 0) |
        (ClearVideoMemory ? 0 : VBE_DISPI_NOCLEARMEM));
}
 
static void BgaSetBank(unsigned short BankNumber)
{
    BgaWriteRegister(VBE_DISPI_INDEX_BANK, BankNumber);
}

File* bochs_mknod(char* name,u32 flag,File* dev){
	Bochs* cons=new Bochs(name);
	return cons;
}

module("module.bvbe",MODULE_DEVICE,Bochs,bochs_mknod)

Bochs::~Bochs(){
	
}

Bochs::Bochs(char* n) : Device(n)
{
	fbinfo_best.w=1024;
	fbinfo_best.h=768;
	fbinfo_best.bpp=32;
	fbinfo_best.state=FB_ACTIVE;
	fbinfo_best.vmem=(unsigned int*)VBE_DISPI_LFB_PHYSICAL_ADDRESS;
	
	fbinfo.w=0;
	fbinfo.h=0;
	fbinfo.bpp=0;
	fbinfo.state=FB_NOT_ACTIVE;
	fbinfo.vmem=(unsigned int*)VBE_DISPI_LFB_PHYSICAL_ADDRESS;
	map_memory=(char*)VBE_DISPI_LFB_PHYSICAL_ADDRESS;
}

u32	Bochs::open(u32 flag){
	return RETURN_OK;
}

u32	Bochs::read(u32 pos,u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	Bochs::write(u32 pos,u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	Bochs::close(){
	return RETURN_OK;
}

void Bochs::scan(){

}


u32	Bochs::ioctl(u32 id,u8* buffer){
	u32 ret=0;
	switch (id){
		case DEV_GET_TYPE:
			ret=DEV_TYPE_FB;
			break;
			
		case DEV_GET_STATE:
			ret=DEV_STATE_OK;
			break;
			
		case DEV_GET_FORMAT:
			ret=DEV_FORMAT_FB;
			break;
			
			
		case API_FB_IS_AVAILABLE:
			ret=(u32)BgaIsAvailable();
			break;
			
		case API_FB_GET_INFO:
			memcpy((char*)buffer,(char*)&fbinfo,sizeof(fb_info));
			break;
			
		case API_FB_SET_INFO:
			memcpy((char*)&fbinfo,(char*)buffer,sizeof(fb_info));
			BgaSetVideoMode(fbinfo.w, fbinfo.h, (unsigned int)fbinfo.bpp/8, 1, 1);
			break;
			
		case API_FB_GET_BINFO:
			memcpy((char*)buffer,(char*)&fbinfo_best,sizeof(fb_info));
			break;
			
		default:
			ret=NOT_DEFINED;
			break;
	}
	return ret;
}

u32	Bochs::remove(){
	delete this;
	return RETURN_OK;
}


================================================
FILE: src/kernel/modules/bochsvbe.h
================================================

#ifndef __BOCHS_VBE__
#define __BOCHS_VBE__

#include <runtime/types.h>
#include <core/device.h>
#include <io.h>

#include <api/dev/ioctl.h>
#include <api/dev/fb.h>


#define VBE_DISPI_ENABLED (0x01)
#define VBE_DISPI_DISABLED (0x00)
#define VBE_DISPI_INDEX_ENABLE (4)
#define VBE_DISPI_ID4 (0xB0C4)
#define VBE_DISPI_LFB_ENABLED (0x40)
#define VBE_DISPI_NOCLEARMEM (0x80)
#define VBE_DISPI_IOPORT_INDEX (0x01CE)
#define VBE_DISPI_INDEX_ID (0)
#define VBE_DISPI_INDEX_XRES (1)
#define VBE_DISPI_INDEX_YRES (2)
#define VBE_DISPI_INDEX_BPP (3)
#define VBE_DISPI_INDEX_ENABLE (4)
#define VBE_DISPI_INDEX_BANK (5)
#define VBE_DISPI_INDEX_VIRT_WIDTH (6)
#define VBE_DISPI_INDEX_VIRT_HEIGHT (7)
#define VBE_DISPI_INDEX_X_OFFSET (8)
#define VBE_DISPI_INDEX_Y_OFFSET (9) 
#define VBE_DISPI_IOPORT_DATA (0x01CF)
 
#define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE0000000


class Bochs : public Device
{
	public:
		Bochs(char* n);
		~Bochs();
		
		
		u32		open(u32 flag);
		u32		close();
		u32		read(u32 pos,u8* buffer,u32 size);
		u32		write(u32 pos,u8* buffer,u32 size);
		u32		ioctl(u32 id,u8* buffer);
		u32		remove();
		void	scan();
		
		
	private:
		fb_info	fbinfo_best;
		fb_info	fbinfo;
};

#endif


================================================
FILE: src/kernel/modules/clock_x86.cc
================================================

#include <os.h>
#include <clock_x86.h>

#include <api/dev/ioctl.h>


static void GetWeekday(unsigned int *Weekday)
{
	unsigned int DataWeekday;

	io.outb(0x70, 0x95);

	io.outb(0x70, 6);
	DataWeekday = io.inb(0x71);
	if(DataWeekday<6) *Weekday = DataWeekday + 2;
	else *Weekday = DataWeekday - 5;
}

static void GetDate(unsigned int *Year, unsigned int *Month, unsigned int *Day)
{
	unsigned int DataYear, DataMonth, DataDay;

	io.outb(0x70, 0x95);

	io.outb(0x70, 9);
	DataYear = io.inb(0x71);
	*Year = DataYear - ((unsigned int) DataYear/16) * 6;

	io.outb(0x70, 8);
	DataMonth = io.inb(0x71);
	*Month = DataMonth - ((unsigned int) DataMonth/16) * 6;

	io.outb(0x70, 7);
	DataDay = io.inb(0x71);
	*Day = DataDay - ((unsigned int) DataDay/16) * 6;
}

static void GetTime(unsigned int *Hour, unsigned int *Minute, unsigned int *Second)
{
	unsigned int DataHour, DataMinute, DataSecond;

	io.outb(0x70, 0x95);

	io.outb(0x70, 4);
	DataHour = io.inb(0x71);
	*Hour = DataHour - ((unsigned int) DataHour/16) * 6;

	io.outb(0x70, 2);
	DataMinute = io.inb(0x71);
	*Minute = DataMinute - ((unsigned int) DataMinute/16) * 6;	
	
	io.outb(0x70, 0);
	DataSecond = io.inb(0x71);
	*Second = DataSecond - ((unsigned int) DataSecond/16) * 6;
}




File* clockx86_mknod(char* name,u32 flag,File* dev){
	Clock_x86* cons=new Clock_x86(name);
	return cons;
}

module("module.clock_x86",MODULE_DEVICE,Clock_x86,clockx86_mknod)

Clock_x86::~Clock_x86(){
	
}

Clock_x86::Clock_x86(char* n) : Device(n)
{

}

void Clock_x86::scan(){

}

u32	Clock_x86::close(){
	return RETURN_OK;
}

u32	Clock_x86::open(u32 flag){
	return RETURN_OK;
}

u32	Clock_x86::read(u32 pos,u8* buffer,u32 size){
	return NOT_DEFINED;
}

u32	Clock_x86::write(u32 pos,u8* buffer,u32 size){
	return NOT_DEFINED;
}

void Clock_x86::reset_info(){
	GetDate(&(cinfo.year),&(cinfo.month), &(cinfo.day));
	GetTime(&(cinfo.h),&(cinfo.m), &(cinfo.s));
}

u32	Clock_x86::ioctl(u32 id,u8* buffer){
	u32 ret=0;
	switch (id){
		case DEV_GET_TYPE:
			ret=DEV_TYPE_TTY;
			break;
			
		case DEV_GET_STATE:
			ret=DEV_STATE_OK;
			break;
			
		case DEV_GET_FORMAT:
			ret=DEV_FORMAT_CHAR;
			break;
			
		case API_CLOCK_GET_INFO:
			reset_info();
			memcpy((char*)buffer,(char*)&cinfo,sizeof(clock_info));
			break;
	
		default:
			ret=NOT_DEFINED;
	}
	return ret;
}

u32	Clock_x86::remove(){
	delete this;
	return RETURN_OK;
}


================================================
FILE: src/kernel/modules/clock_x86.h
================================================

#ifndef __CLOCK__
#define __CLOCK__

#include <runtime/types.h>
#include <core/device.h>
#include <io.h>

#include <api/dev/clock.h>

class Clock_x86 : public Device
{
	public:
		Clock_x86(char* n);
		~Clock_x86();
		
		
		u32		open(u32 flag);
		u32		close();
		u32		read(u32 pos,u8* buffer,u32 size);
		u32		write(u32 pos,u8* buffer,u32 size);
		u32		ioctl(u32 id,u8* buffer);
		u32		remove();
		void	scan();
		
		void 	reset_info();
	private:
		clock_info	cinfo;
};

#endif


================================================
FILE: src/kernel/modules/dospartition.cc
================================================
#include <os.h>
#include <dospartition.h>

/*
 *	Flag indique le numero de partition
 */
File* dospartition_mount(char* name,u32 flag,File* dev){
	DosPartition* dos=new DosPartition(name,dev,flag);
	return dos;
}

module("module.dospartition",MODULE_FILESYSTEM,DosPartition,dospartition_mount)

DosPartition::~DosPartition(){
	
}

DosPartition::DosPartition(char* n,File* dev,u32 num) : Device(n)
{
	device=dev;
	numpart=num;
	partition_info=NULL;
	if (device!=NULL){
		partition_info=(dos_partition*)kmalloc(sizeof(dos_partition));
		device->read((u32)(DOS_PART_1+(u32)(numpart*sizeof(dos_partition))),
					 (u8*)partition_info,
					 sizeof(dos_partition));	
	}
}

void DosPartition::scan(){
	
}

u32	DosPartition::close(){
	if (partition_info!=NULL && device!=NULL){
		return device->close();
	}
	return ERROR_PARAM;
}

u32	DosPartition::open(u32 flag){
	if (partition_info!=NULL && device!=NULL){
		return device->open(flag);
	}
	return ERROR_PARAM;
}

u32	DosPartition::read(u32 pos,u8* buffer,u32 sizee){
	if (partition_info!=NULL && device!=NULL){
		return device->read(((partition_info->s_lba)*512)+pos,buffer,sizee);
	}
	return ERROR_PARAM;
}

u32	DosPartition::write(u32 pos,u8* buffer,u32 sizee){
	if (partition_info!=NULL && device!=NULL){
		return device->write((partition_info->s_lba*512)+pos,buffer,sizee);
	}
	return ERROR_PARAM;
}

u32	DosPartition::ioctl(u32 id,u8* buffer){
	if (partition_info!=NULL && device!=NULL){
		return device->ioctl(id,buffer);
	}
	return ERROR_PARAM;
}

u32	DosPartition::remove(){
	delete this;
	return RETURN_OK;
}




================================================
FILE: src/kernel/modules/dospartition.h
================================================

#ifndef __DOS_PARTITION__
#define __DOS_PARTITION__

#include <runtime/types.h>
#include <core/file.h>
#include <io.h>

#define DOS_PART_1	0x01BE
#define DOS_PART_2	0x01CE
#define DOS_PART_3	0x01DE
#define DOS_PART_4	0x01EE

struct dos_partition {
	u8 bootable;			/* 0 = no, 0x80 = bootable */
	u8 s_head;				/* Starting head */
	u16 s_sector:6;			/* Starting sector */
	u16 s_cyl:10;			/* Starting cylinder */
	u8 id;					/* System ID */
	u8 e_head;				/* Ending Head */
	u16 e_sector:6;			/* Ending Sector */
	u16 e_cyl:10;			/* Ending Cylinder */
	u32 s_lba;				/* Starting LBA value */
	u32 size;				/* Total Sectors in partition */
} __attribute__ ((packed));
 
/*
 *	Driver class
 */
class DosPartition : public Device
{
	public:
		DosPartition(char* n,File* dev,u32 num);
		~DosPartition();
		
		
		u32		open(u32 flag);
		u32		close();
		u32		read(u32 pos,u8* buffer,u32 sizee);
		u32		write(u32 pos,u8* buffer,u32 sizee);
		u32		ioctl(u32 id,u8* buffer);
		u32		remove();
		void	scan();
		

	private:
		u32 			numpart;
		dos_partition*	partition_info;
};

#endif


================================================
FILE: src/kernel/modules/ext2.cc
================================================

 
#include <os.h>
#include <ext2.h>


File* ext2_mount(char* name,u32 flag,File* dev){
	int ret=ext2_check_disk(dev);
	if (ret!=RETURN_OK){
		io.print("ext2: can't mount %s in %s \n",dev->getName(),name);
		return NULL;
	}
	else{	
		io.print("ext2:  mount %s in %s \n",dev->getName(),name);
		Ext2* ret=new Ext2(name);
		ret->ext2inode=EXT2_INUM_ROOT;
		ext2_get_disk_info(dev,ret);
		ret->scan();
		return ret;
	}
}

module("module.ext2",MODULE_FILESYSTEM,Ext2,ext2_mount)

Ext2::~Ext2(){
	
}

Ext2::Ext2(char* n) : File(n,TYPE_DIRECTORY)
{
	map=NULL;
}

void Ext2::scan(){
	ext2_scan(this);
}

u32	Ext2::close(){
	return NOT_DEFINED;
}

u32	Ext2::open(u32 flag){
	ext2_inode *inodee=ext2_read_inode(disk,ext2inode);
	map=ext2_read_file(disk,inodee);
	kfree(inodee);
	return RETURN_OK;
}

u32	Ext2::read(u32 pos,u8* buffer,u32 sizee){
	u32 bufsize=sizee;
	if ((pos + bufsize) > (size))
		bufsize = (u32)(size) - pos;
	memcpy((char*)buffer, (char *) (map + pos), bufsize);
	return bufsize;
}

u32	Ext2::write(u32 pos,u8* buffer,u32 sizee){
	return NOT_DEFINED;
}

u32	Ext2::ioctl(u32 id,u8* buffer){
	return NOT_DEFINED;
}

u32	Ext2::remove(){
	delete this;
	return RETURN_OK;
}



/*
 *	EXT2 specification
 */
int ext2_read_sb(File* dev,ext2_super_block *sb)
{
	if (dev!=NULL){
		dev->read((u32)1024,(u8 *) sb,sizeof(ext2_super_block));
		return RETURN_OK;
	}
	else
		return ERROR_PARAM;
}

int ext2_read_gd(File* fdev,ext2_group_desc *gd,ext2_disk* info)
{
	if (fdev!=NULL){
		u32 offset;
		offset = ((info->blocksize == 1024) ? 2048 : info->blocksize);
		int gd_size = (info->groups * ((int)sizeof(struct ext2_group_desc)));
		fdev->read(offset,(u8*) gd,gd_size);
		return RETURN_OK;
	}
	else
		return ERROR_PARAM;
}

void ext2_get_disk_info(File*dev,Ext2 *fp)
{
	ext2_disk* info=(ext2_disk*)kmalloc(sizeof(ext2_disk));
	info->sb=(ext2_super_block*)kmalloc(sizeof(ext2_super_block));
	info->dev=dev;
	int i, j;
	ext2_read_sb(dev,info->sb);
	info->blocksize = 1024 << ((info->sb)->s_log_block_size);
	i = (info->sb->s_blocks_count / info->sb->s_blocks_per_group) + ((info->sb->s_blocks_count % info->sb->s_blocks_per_group) ? 1 : 0);
	j = (info->sb->s_inodes_count / info->sb->s_inodes_per_group) + ((info->sb->s_inodes_count % info->sb->s_inodes_per_group) ? 1 : 0);
	info->groups = (i > j) ? i : j;
	int gd_size = info->groups * ((int)sizeof(ext2_group_desc));
	info->gd = (ext2_group_desc *) kmalloc(gd_size);
	ext2_read_gd(info->dev,info->gd,info);
	fp->disk=info;
	return;
}
int ext2_check_disk(File *dev)
{
	ext2_super_block *sb=(ext2_super_block *)kmalloc(sizeof(ext2_super_block));
	if (ext2_read_sb(dev,sb)!=RETURN_OK)
		return ERROR_PARAM;
	if (sb->s_magic==0xEF53){
		kfree(sb);
		return RETURN_OK;
	}
	else{
		kfree(sb);
		return ERROR_PARAM;
	}
}
ext2_inode *ext2_read_inode(ext2_disk* hd, int i_num)
{
	int gr_num, index;
	u32 offset;
	ext2_inode *inode;
	ext2_group_desc * info=hd->gd;
	inode = (ext2_inode *) kmalloc((hd->sb)->s_inode_size);//sizeof(ext2_inode));
	gr_num = (i_num - 1) / ((hd->sb)->s_inodes_per_group);
	index = (i_num - 1) % ((hd->sb)->s_inodes_per_group);
	offset = (info[gr_num].bg_inode_table * (hd->blocksize)) + (index * ((hd->sb)->s_inode_size));
	if ((hd->dev)!=NULL){
		(hd->dev)->read(offset,(u8*) inode,(hd->sb)->s_inode_size);
	}
	return inode;
}
int ext2_is_directory(Ext2 *fp)
{
	ext2_inode *inod=ext2_read_inode(fp->disk,fp->ext2inode);
	int ret=(inod->i_mode & EXT2_S_IFDIR) ? 1 : 0;
	kfree(inod);
	return ret;
}
char *ext2_read_file(ext2_disk *hd,ext2_inode *inode)
{
	File *dev=hd->dev;
	
	char *mmap_base, *mmap_head, *buf;

	int *p, *pp, *ppp;
	int i, j, k;
	int n, size;

	buf = (char *) kmalloc(hd->blocksize);
	p = (int *) kmalloc(hd->blocksize);
	pp = (int *) kmalloc(hd->blocksize);
	ppp = (int *) kmalloc(hd->blocksize);

	/* taille totale du fichier */
	size = inode->i_size;
	mmap_head = mmap_base = (char*)kmalloc(size);
	/* direct block number */
	for (i = 0; i < 12 && inode->i_block[i]; i++) {
        dev->read((u32)(inode->i_block[i] * hd->blocksize),(u8*) buf, (hd->blocksize));
		n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
		memcpy(mmap_head, buf, n);
		mmap_head += n;
		size -= n;
	}
	/* indirect block number */
	if (inode->i_block[12]) {
	    dev->read((u32)(inode->i_block[12] * hd->blocksize), (u8*) p, (hd->blocksize));


		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            dev->read((u32)(p[i] * hd->blocksize),(u8*)buf, (hd->blocksize));
			n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
			memcpy(mmap_head, buf, n);
			mmap_head += n;
			size -= n;
		}
	}

	/* bi-indirect block number */
	if (inode->i_block[13]) {
	    dev->read((u32)(inode->i_block[13] * hd->blocksize), (u8*) p, (hd->blocksize));

		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            dev->read((u32)(p[i] * (int)hd->blocksize), (u8*) pp,(hd->blocksize));
			for (j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) {
                dev->read((u32)(pp[j] * hd->blocksize),(u8*)buf,(hd->blocksize));
				n = ((size > (int)hd-> blocksize) ? (int)hd->blocksize : size);
				memcpy(mmap_head, buf, n);
				mmap_head += n;
				size -= n;
			}
		}
	}
	/* tri-indirect block number */
	if (inode->i_block[14]) {
        dev->read((u32)(inode->i_block[14] * hd->blocksize), (u8*) p,(hd->blocksize));
		for (i = 0; i < (int)hd->blocksize / 4 && p[i]; i++) {
            dev->read((u32)(p[i] * hd->blocksize), (u8*) pp,(hd->blocksize));
			for (j = 0; j < (int)hd->blocksize / 4 && pp[j]; j++) {
                dev->read((u32)(pp[j] * hd->blocksize), (u8*) ppp,(hd->blocksize));
				for (k = 0; k < (int)hd->blocksize / 4 && ppp[k]; k++) {
                    dev->read((u32)(ppp[k] * hd->blocksize),(u8*)buf,(hd->blocksize));
					n = ((size > (int)hd->blocksize) ? (int)hd->blocksize : size);
					memcpy(mmap_head, buf, n);
					mmap_head += n;
					size -= n;
				}
			}
		}
	}
	kfree(buf);
	kfree(p);
	kfree(pp);
	kfree(ppp);;
	return mmap_base;
}
int ext2_scan(Ext2 *dir)
{
	ext2_directory_entry *dentry;
	Ext2 *leaf;
	u32 dsize;
	char *filename;
	int f_toclose;
	ext2_inode *inode = ext2_read_inode(dir->disk, dir->ext2inode);
	if (dir->getType()!=TYPE_DIRECTORY) {
		return ERROR_PARAM;
	}
	
	if (!dir->map) {
		dir->map = ext2_read_file(dir->disk, inode);
		f_toclose = 1;
	} else {
		f_toclose = 0;
	}
	
	dsize = inode->i_size;
	dentry = (ext2_directory_entry *) dir->map;
	while (inode && dsize) {
				filename = (char *) kmalloc(dentry->name_len + 1);
				memcpy(filename,(char*)&(dentry->name), dentry->name_len);
				filename[dentry->name_len] = 0;
				if (strcmp(".", filename) && strcmp("..", filename)) {
					if (dir->find(filename)==NULL) {
						leaf= new Ext2(filename);
						leaf->ext2inode = dentry->inode;
						leaf->disk=dir->disk;
						if (ext2_is_directory(leaf))
							leaf->setType(TYPE_DIRECTORY);
						else
							leaf->setType(TYPE_FILE);
						dir->addChild(leaf);
						leaf->map = 0;
						ext2_inode *inod=ext2_read_inode((ext2_disk*)leaf->disk,leaf->ext2inode);
						leaf->setSize(inod->i_size);
						kfree(inod);
					}
				}
				kfree(filename);
		dsize -= dentry->rec_len;
		dentry = (ext2_directory_entry *) ((char *) dentry + dentry->rec_len);
	}
	kfree(inode);
	if (f_toclose == 1) {
		kfree(dir->map);
		dir->map = 0;
	}
	return 0;
}


================================================
FILE: src/kernel/modules/ext2.h
================================================

#ifndef __EXT2__
#define __EXT2__

#include <runtime/types.h>
#include <core/file.h>
#include <io.h>

/*
 *	Ext2 specification
 */
struct ext2_super_block {
	u32 s_inodes_count;	/* Total number of inodes */
	u32 s_blocks_count;	/* Total number of blocks */
	u32 s_r_blocks_count;	/* Total number of blocks reserved for the super user */
	u32 s_free_blocks_count;	/* Total number of free blocks */
	u32 s_free_inodes_count;	/* Total number of free inodes */
	u32 s_first_data_block;	/* Id of the block containing the superblock structure */
	u32 s_log_block_size;	/* Used to compute block size = 1024 << s_log_block_size */
	u32 s_log_frag_size;	/* Used to compute fragment size */
	u32 s_blocks_per_group;	/* Total number of blocks per group */
	u32 s_frags_per_group;	/* Total number of fragments per group */
	u32 s_inodes_per_group;	/* Total number of inodes per group */
	u32 s_mtime;		/* Last time the file system was mounted */
	u32 s_wtime;		/* Last write access to the file system */
	u16 s_mnt_count;	/* How many `mount' since the last was full verification */
	u16 s_max_mnt_count;	/* Max count between mount */
	u16 s_magic;		/* = 0xEF53 */
	u16 s_state;		/* File system state */
	u16 s_errors;		/* Behaviour when detecting errors */
	u16 s_minor_rev_level;	/* Minor revision level */
	u32 s_lastcheck;	/* Last check */
	u32 s_checkinterval;	/* Max. time between checks */
	u32 s_creator_os;	/* = 5 */
	u32 s_rev_level;	/* = 1, Revision level */
	u16 s_def_resuid;	/* Default uid for reserved blocks */
	u16 s_def_resgid;	/* Default gid for reserved blocks */
	u32 s_first_ino;	/* First inode useable for standard files */
	u16 s_inode_size;	/* Inode size */
	u16 s_block_group_nr;	/* Block group hosting this superblock structure */
	u32 s_feature_compat;
	u32 s_feature_incompat;
	u32 s_feature_ro_compat;
	u8 s_uuid[16];		/* Volume id */
	char s_volume_name[16];	/* Volume name */
	char s_last_mounted[64];	/* Path where the file system was last mounted */
	u32 s_algo_bitmap;	/* For compression */
	u8 s_padding[820];
} __attribute__ ((packed));


struct ext2_group_desc {
	u32 bg_block_bitmap;	/* Id of the first block of the "block bitmap" */
	u32 bg_inode_bitmap;	/* Id of the first block of the "inode bitmap" */
	u32 bg_inode_table;	/* Id of the first block of the "inode table" */
	u16 bg_free_blocks_count;	/* Total number of free blocks */
	u16 bg_free_inodes_count;	/* Total number of free inodes */
	u16 bg_used_dirs_count;	/* Number of inodes allocated to directories */
	u16 bg_pad;		/* Padding the structure on a 32bit boundary */
	u32 bg_reserved[3];	/* Future implementation */
} __attribute__ ((packed));

struct ext2_inode {
	u16 i_mode;		/* File type + access rights */
	u16 i_uid;
	u32 i_size;
	u32 i_atime;
	u32 i_ctime;
	u32 i_mtime;
	u32 i_dtime;
	u16 i_gid;
	u16 i_links_count;
	u32 i_blocks;		/* 512 bytes blocks ! */
	u32 i_flags;
	u32 i_osd1;

	/*
	 * [0] -> [11] : block number (32 bits per block)
	 * [12]        : indirect block number
	 * [13]        : bi-indirect block number
	 * [14]        : tri-indirect block number
	 */
	u32 i_block[15];

	u32 i_generation;
	u32 i_file_acl;
	u32 i_dir_acl;
	u32 i_faddr;
	u8 i_osd2[12];
} __attribute__ ((packed));

struct ext2_directory_entry {
	u32 inode;		/* inode number or 0 (unused) */
	u16 rec_len;		/* offset to the next dir. entry */
	u8 name_len;		/* name length */
	u8 file_type;
	char name;
} __attribute__ ((packed));


struct ext2_disk {
	ext2_super_block*	sb;
	ext2_group_desc*	gd;
	u32 				blocksize;
	u16 				groups;		/* Total number of groups */
	File*				dev;
};


/* super_block: s_errors */
#define	EXT2_ERRORS_CONTINUE	1
#define	EXT2_ERRORS_RO		2
#define	EXT2_ERRORS_PANIC	3
#define	EXT2_ERRORS_DEFAULT	1

/* inode: i_mode */
#define	EXT2_S_IFMT	0xF000		/* format mask  */
#define	EXT2_S_IFSOCK	0xC000	/* socket */
#define	EXT2_S_IFLNK	0xA000	/* symbolic link */
#define	EXT2_S_IFREG	0x8000	/* regular file */
#define	EXT2_S_IFBLK	0x6000	/* block device */
#define	EXT2_S_IFDIR	0x4000	/* directory */
#define	EXT2_S_IFCHR	0x2000	/* character device */
#define	EXT2_S_IFIFO	0x1000	/* fifo */

#define	EXT2_S_ISUID	0x0800	/* SUID */
#define	EXT2_S_ISGID	0x0400	/* SGID */
#define	EXT2_S_ISVTX	0x0200	/* sticky bit */
#define	EXT2_S_IRWXU	0x01C0	/* user access rights mask */
#define	EXT2_S_IRUSR	0x0100	/* read */
#define	EXT2_S_IWUSR	0x0080	/* write */
#define	EXT2_S_IXUSR	0x0040	/* execute */
#define	EXT2_S_IRWXG	0x0038	/* group access rights mask */
#define	EXT2_S_IRGRP	0x0020	/* read */
#define	EXT2_S_IWGRP	0x0010	/* write */
#define	EXT2_S_IXGRP	0x0008	/* execute */
#define	EXT2_S_IRWXO	0x0007	/* others access rights mask */
#define	EXT2_S_IROTH	0x0004	/* read */
#define	EXT2_S_IWOTH	0x0002	/* write */
#define	EXT2_S_IXOTH	0x0001	/* execute */

#define EXT2_INUM_ROOT	2
 
/*
 *	Driver class
 */
class Ext2 : public File
{
	public:
		Ext2(char* n);
		~Ext2();
Download .txt
gitextract_39nrcw17/

├── .gitignore
├── Chapter-1/
│   └── README.md
├── Chapter-2/
│   └── README.md
├── Chapter-3/
│   └── README.md
├── Chapter-4/
│   └── README.md
├── Chapter-5/
│   └── README.md
├── Chapter-6/
│   └── README.md
├── Chapter-7/
│   └── README.md
├── Chapter-8/
│   └── README.md
├── LICENSE
├── README.md
├── SUMMARY.md
├── chapter9/
│   └── README.md
└── src/
    ├── Makefile
    ├── Vagrantfile
    ├── kernel/
    │   ├── Makefile
    │   ├── arch/
    │   │   └── x86/
    │   │       ├── Makefile
    │   │       ├── alloc.cc
    │   │       ├── architecture.cc
    │   │       ├── architecture.h
    │   │       ├── archprocess.h
    │   │       ├── config.make
    │   │       ├── io.cc
    │   │       ├── io.h
    │   │       ├── linker.ld
    │   │       ├── start.asm
    │   │       ├── switch.asm
    │   │       ├── vmm.cc
    │   │       ├── vmm.h
    │   │       ├── x86.cc
    │   │       ├── x86.h
    │   │       └── x86int.asm
    │   ├── config.h
    │   ├── core/
    │   │   ├── Makefile
    │   │   ├── api/
    │   │   │   ├── dev/
    │   │   │   │   ├── clock.h
    │   │   │   │   ├── fb.h
    │   │   │   │   ├── ioctl.h
    │   │   │   │   ├── ipc.h
    │   │   │   │   ├── keyboard.h
    │   │   │   │   ├── proc.h
    │   │   │   │   └── tty.h
    │   │   │   └── kernel/
    │   │   │       ├── syscall.h
    │   │   │       └── syscall_table.h
    │   │   ├── api.h
    │   │   ├── api_posix.cc
    │   │   ├── boot.h
    │   │   ├── class.cc
    │   │   ├── device.cc
    │   │   ├── device.h
    │   │   ├── elf_loader.cc
    │   │   ├── elf_loader.h
    │   │   ├── env.cc
    │   │   ├── env.h
    │   │   ├── file.cc
    │   │   ├── file.h
    │   │   ├── filesystem.cc
    │   │   ├── filesystem.h
    │   │   ├── kernel.cc
    │   │   ├── kernel.h
    │   │   ├── keyboard.h
    │   │   ├── modulelink.cc
    │   │   ├── modulelink.h
    │   │   ├── os.h
    │   │   ├── process.cc
    │   │   ├── process.h
    │   │   ├── signal.h
    │   │   ├── socket.cc
    │   │   ├── socket.h
    │   │   ├── syscalls.cc
    │   │   ├── syscalls.h
    │   │   ├── system.cc
    │   │   ├── system.h
    │   │   ├── user.cc
    │   │   └── user.h
    │   ├── modules/
    │   │   ├── Makefile
    │   │   ├── bochsvbe.cc
    │   │   ├── bochsvbe.h
    │   │   ├── clock_x86.cc
    │   │   ├── clock_x86.h
    │   │   ├── dospartition.cc
    │   │   ├── dospartition.h
    │   │   ├── ext2.cc
    │   │   ├── ext2.h
    │   │   ├── ide.cc
    │   │   ├── ide.h
    │   │   ├── keys.cc
    │   │   ├── keys.h
    │   │   ├── module.cc
    │   │   ├── module.h
    │   │   ├── modules.conf
    │   │   ├── null.cc
    │   │   ├── null.h
    │   │   ├── stdtty.cc
    │   │   ├── stdtty.h
    │   │   ├── x86serial.cc
    │   │   └── x86serial.h
    │   └── runtime/
    │       ├── Makefile
    │       ├── alloc.h
    │       ├── buffer.cc
    │       ├── buffer.h
    │       ├── cxx.cc
    │       ├── itoa.cc
    │       ├── libc.h
    │       ├── list.h
    │       ├── memory.cc
    │       ├── string.cc
    │       ├── string.h
    │       └── types.h
    ├── sdk/
    │   ├── Makefile
    │   ├── bootdisk/
    │   │   ├── bin/
    │   │   │   └── .gitkeep
    │   │   └── boot/
    │   │       └── grub/
    │   │           ├── grub.conf
    │   │           ├── menu.lst
    │   │           ├── stage1
    │   │           ├── stage2
    │   │           └── stage2_eltorito
    │   ├── build.mak
    │   ├── diskimage.sh
    │   ├── include/
    │   │   ├── _ansi.h
    │   │   ├── alloca.h
    │   │   ├── arpa/
    │   │   │   └── inet.h
    │   │   ├── assert.h
    │   │   ├── ctype.h
    │   │   ├── dirent.h
    │   │   ├── endian.h
    │   │   ├── errno.h
    │   │   ├── fcntl.h
    │   │   ├── float.h
    │   │   ├── getopt.h
    │   │   ├── inttypes.h
    │   │   ├── limits.h
    │   │   ├── linker.ld
    │   │   ├── locale.h
    │   │   ├── math.h
    │   │   ├── netinet/
    │   │   │   └── in.h
    │   │   ├── os.h
    │   │   ├── pwd.h
    │   │   ├── setjmp.h
    │   │   ├── signal.h
    │   │   ├── stdarg.h
    │   │   ├── stddef.h
    │   │   ├── stdint.h
    │   │   ├── stdio.h
    │   │   ├── stdlib.h
    │   │   ├── string.h
    │   │   ├── strings.h
    │   │   ├── sys/
    │   │   │   ├── cdefs.h
    │   │   │   ├── ioctl.h
    │   │   │   ├── mman.h
    │   │   │   ├── mount.h
    │   │   │   ├── param.h
    │   │   │   ├── resource.h
    │   │   │   ├── select.h
    │   │   │   ├── socket.h
    │   │   │   ├── stat.h
    │   │   │   ├── time.h
    │   │   │   ├── types.h
    │   │   │   └── wait.h
    │   │   ├── termios.h
    │   │   ├── time.h
    │   │   ├── unistd.h
    │   │   └── utime.h
    │   ├── lib/
    │   │   └── .gitkeep
    │   ├── qemu.sh
    │   └── src/
    │       └── libc/
    │           ├── Makefile
    │           ├── arch/
    │           │   └── i386/
    │           │       ├── getpagesize.c
    │           │       ├── longjmp.S
    │           │       ├── math/
    │           │       │   ├── e_atan2.S
    │           │       │   ├── e_exp.S
    │           │       │   ├── e_fmod.S
    │           │       │   ├── e_hypot.S
    │           │       │   ├── e_log.S
    │           │       │   ├── e_log10.S
    │           │       │   ├── e_pow.S
    │           │       │   ├── s_ceil.S
    │           │       │   ├── s_cos.S
    │           │       │   ├── s_fabs.S
    │           │       │   ├── s_finite.S
    │           │       │   ├── s_floor.S
    │           │       │   ├── s_frexp.S
    │           │       │   ├── s_scalbn.S
    │           │       │   └── s_sin.S
    │           │       └── setjmp.S
    │           └── src/
    │               ├── closedir.c
    │               ├── ctype/
    │               │   ├── isalnum.c
    │               │   ├── isalpha.c
    │               │   ├── isascii.c
    │               │   ├── isblank.c
    │               │   ├── iscntrl.c
    │               │   ├── isdigit.c
    │               │   ├── isgraph.c
    │               │   ├── islower.c
    │               │   ├── isprint.c
    │               │   ├── ispunct.c
    │               │   ├── isspace.c
    │               │   ├── isupper.c
    │               │   ├── isxdigit.c
    │               │   ├── toascii.c
    │               │   ├── tolower.c
    │               │   └── toupper.c
    │               ├── fcntl/
    │               │   ├── creat.c
    │               │   ├── fcntl.c
    │               │   └── open.c
    │               ├── getopt/
    │               │   ├── getopt.c
    │               │   ├── getopt_int.h
    │               │   ├── getopt_long.c
    │               │   └── getopt_long_only.c
    │               ├── locale/
    │               │   ├── localeconv.c
    │               │   └── setlocale.c
    │               ├── math/
    │               │   ├── s_ldexp.c
    │               │   └── s_modf.c
    │               ├── network/
    │               │   ├── inet_aton.c
    │               │   └── inet_ntoa.c
    │               ├── opendir.c
    │               ├── os/
    │               │   ├── debug.c
    │               │   ├── ipc.c
    │               │   ├── module.c
    │               │   ├── os.c
    │               │   ├── region.c
    │               │   ├── semaphore.c
    │               │   ├── syscall.c
    │               │   ├── sysinfo.c
    │               │   └── thread.c
    │               ├── pwd/
    │               │   ├── endpwent.c
    │               │   ├── getpwent.c
    │               │   ├── getpwnam.c
    │               │   ├── getpwuid.c
    │               │   └── setpwent.c
    │               ├── readdir.c
    │               ├── rewinddir.c
    │               ├── signal/
    │               │   ├── kill.c
    │               │   ├── killpg.c
    │               │   ├── raise.c
    │               │   ├── sigaction.c
    │               │   ├── sigaddset.c
    │               │   ├── sigdelset.c
    │               │   ├── sigemptyset.c
    │               │   ├── sigfillset.c
    │               │   ├── sigismember.c
    │               │   ├── signal.c
    │               │   └── sigprocmask.c
    │               ├── sscanf.c
    │               ├── start.c
    │               ├── stdio/
    │               │   ├── clearerr.c
    │               │   ├── fclose.c
    │               │   ├── fdopen.c
    │               │   ├── feof.c
    │               │   ├── ferror.c
    │               │   ├── fflush.c
    │               │   ├── fgetc.c
    │               │   ├── fgets.c
    │               │   ├── fileno.c
    │               │   ├── fopen.c
    │               │   ├── fpurge.c
    │               │   ├── fputc.c
    │               │   ├── fputs.c
    │               │   ├── fread.c
    │               │   ├── freopen.c
    │               │   ├── fseek.c
    │               │   ├── ftell.c
    │               │   ├── fwrite.c
    │               │   ├── getc.c
    │               │   ├── perror.c
    │               │   ├── putc.c
    │               │   ├── putchar.c
    │               │   ├── puts.c
    │               │   ├── remove.c
    │               │   ├── rename.c
    │               │   ├── rewind.c
    │               │   ├── setvbuf.c
    │               │   ├── stdio_internal.c
    │               │   ├── stdio_internal.h
    │               │   ├── streams.c
    │               │   ├── support_bufio.c
    │               │   ├── support_pf.c
    │               │   ├── support_supcon.c
    │               │   └── ungetc.c
    │               ├── stdlib/
    │               │   ├── abort.c
    │               │   ├── abs.c
    │               │   ├── atof.c
    │               │   ├── atoi.c
    │               │   ├── atol.c
    │               │   ├── atoll.c
    │               │   ├── bsearch.c
    │               │   ├── getenv.c
    │               │   ├── labs.c
    │               │   ├── llabs.c
    │               │   ├── malloc.c
    │               │   ├── mkstemp.c
    │               │   ├── mktemp.c
    │               │   ├── qsort.c
    │               │   ├── rand.c
    │               │   ├── random.c
    │               │   ├── srand.c
    │               │   ├── srandom.c
    │               │   ├── strtod.c
    │               │   ├── strtol.c
    │               │   ├── strtoll.c
    │               │   ├── strtoul.c
    │               │   └── strtoull.c
    │               ├── string/
    │               │   ├── memchr.c
    │               │   ├── memcmp.c
    │               │   ├── memcpy.c
    │               │   ├── memmove.c
    │               │   ├── memset.c
    │               │   ├── strcasecmp.c
    │               │   ├── strcat.c
    │               │   ├── strchr.c
    │               │   ├── strcmp.c
    │               │   ├── strcpy.c
    │               │   ├── strcspn.c
    │               │   ├── strdup.c
    │               │   ├── strerror.c
    │               │   ├── strlen.c
    │               │   ├── strncasecmp.c
    │               │   ├── strncat.c
    │               │   ├── strncmp.c
    │               │   ├── strncpy.c
    │               │   ├── strndup.c
    │               │   ├── strnlen.c
    │               │   ├── strpbrk.c
    │               │   ├── strrchr.c
    │               │   ├── strsignal.c
    │               │   ├── strspn.c
    │               │   ├── strstr.c
    │               │   ├── strtok.c
    │               │   └── strtok_r.c
    │               ├── sys/
    │               │   ├── chmod.c
    │               │   ├── connect.c
    │               │   ├── fstat.c
    │               │   ├── ioctl.c
    │               │   ├── lstat.c
    │               │   ├── mkdir.c
    │               │   ├── mount.c
    │               │   ├── select.c
    │               │   ├── socket.c
    │               │   ├── stat.c
    │               │   ├── stime.c
    │               │   ├── umask.c
    │               │   ├── umount.c
    │               │   ├── utime.c
    │               │   ├── utimes.c
    │               │   ├── wait.c
    │               │   ├── wait3.c
    │               │   ├── wait4.c
    │               │   └── waitpid.c
    │               ├── termios/
    │               │   ├── tcflow.c
    │               │   ├── tcflush.c
    │               │   ├── tcgetattr.c
    │               │   ├── tcgetpgrp.c
    │               │   ├── tcsetattr.c
    │               │   └── tcsetpgrp.c
    │               ├── time/
    │               │   ├── asctime.c
    │               │   ├── asctime_r.c
    │               │   ├── ctime.c
    │               │   ├── ctime_r.c
    │               │   ├── gettimeofday.c
    │               │   ├── gmtime.c
    │               │   ├── gmtime_r.c
    │               │   ├── localtime.c
    │               │   ├── localtime_r.c
    │               │   ├── mktime.c
    │               │   ├── nanosleep.c
    │               │   ├── strftime.c
    │               │   ├── time.c
    │               │   ├── time_int.c
    │               │   ├── time_int.h
    │               │   └── tzset.c
    │               ├── trio/
    │               │   ├── trio.c
    │               │   ├── trio.h
    │               │   ├── triodef.h
    │               │   ├── trionan.c
    │               │   ├── trionan.h
    │               │   ├── triop.h
    │               │   ├── triostr.c
    │               │   └── triostr.h
    │               ├── udivmoddi4.c
    │               └── unistd/
    │                   ├── access.c
    │                   ├── alarm.c
    │                   ├── chdir.c
    │                   ├── chown.c
    │                   ├── close.c
    │                   ├── dup.c
    │                   ├── dup2.c
    │                   ├── execlp.c
    │                   ├── execv.c
    │                   ├── execve.c
    │                   ├── execvp.c
    │                   ├── exit.c
    │                   ├── fchdir.c
    │                   ├── fork.c
    │                   ├── fpathconf.c
    │                   ├── ftruncate.c
    │                   ├── getcwd.c
    │                   ├── getdents.c
    │                   ├── getdtablesize.c
    │                   ├── getegid.c
    │                   ├── geteuid.c
    │                   ├── getgid.c
    │                   ├── gethostname.c
    │                   ├── getpgid.c
    │                   ├── getpgrp.c
    │                   ├── getpid.c
    │                   ├── getppid.c
    │                   ├── gettid.c
    │                   ├── getuid.c
    │                   ├── isatty.c
    │                   ├── link.c
    │                   ├── lseek.c
    │                   ├── mmap.c
    │                   ├── pipe.c
    │                   ├── pread.c
    │                   ├── pwrite.c
    │                   ├── read.c
    │                   ├── readlink.c
    │                   ├── rmdir.c
    │                   ├── sbrk.c
    │                   ├── setgid.c
    │                   ├── setpgid.c
    │                   ├── setpgrp.c
    │                   ├── setregid.c
    │                   ├── setreuid.c
    │                   ├── setuid.c
    │                   ├── sleep.c
    │                   ├── symlink.c
    │                   ├── ttyname.c
    │                   ├── unlink.c
    │                   └── write.c
    └── userland/
        ├── Makefile
        └── helloworld/
            ├── Makefile
            └── main.c
Download .txt
SYMBOL INDEX (936 symbols across 295 files)

FILE: src/kernel/arch/x86/alloc.cc
  type kmalloc_header (line 8) | struct kmalloc_header
  type kmalloc_header (line 18) | struct kmalloc_header
  type kmalloc_header (line 49) | struct kmalloc_header
  type kmalloc_header (line 52) | struct kmalloc_header
  type kmalloc_header (line 59) | struct kmalloc_header
  type kmalloc_header (line 71) | struct kmalloc_header
  type kmalloc_header (line 74) | struct kmalloc_header
  type kmalloc_header (line 81) | struct kmalloc_header
  type kmalloc_header (line 98) | struct kmalloc_header
  type kmalloc_header (line 109) | struct kmalloc_header
  function kfree (line 113) | void kfree(void *v_addr)

FILE: src/kernel/arch/x86/architecture.cc
  function u32 (line 327) | u32	Architecture::getArg(u32 n){

FILE: src/kernel/arch/x86/architecture.h
  function class (line 10) | class Architecture

FILE: src/kernel/arch/x86/archprocess.h
  type process_st (line 12) | struct process_st {

FILE: src/kernel/arch/x86/io.cc
  function u32 (line 278) | u32 Io::read(char* buf,u32 count){

FILE: src/kernel/arch/x86/io.h
  function class (line 14) | class Io

FILE: src/kernel/arch/x86/vmm.cc
  function page (line 42) | page* get_page_from_heap(void)
  function release_page_from_heap (line 83) | int release_page_from_heap(char *v_addr)
  function Memory_init (line 141) | void Memory_init(u32 high_mem)
  type page_directory (line 204) | struct page_directory
  type page_directory (line 206) | struct page_directory
  type page_directory (line 211) | struct page_directory
  type page_directory (line 211) | struct page_directory
  function page_copy_in_pd (line 236) | void page_copy_in_pd(process_st* current,u32 virtadr){
  type page_directory (line 250) | struct page_directory
  type page_directory (line 250) | struct page_directory
  type page_directory (line 252) | struct page_directory
  type page_directory (line 257) | struct page_directory
  type page_directory (line 257) | struct page_directory
  function pd_destroy (line 282) | int pd_destroy(struct page_directory *pd)
  function pd0_add_page (line 306) | int pd0_add_page(char *v_addr, char *p_addr, int flags)
  function pd_add_page (line 336) | int pd_add_page(char *v_addr, char *p_addr, int flags, struct page_direc...
  function pd_remove_page (line 385) | int pd_remove_page(char *v_addr)

FILE: src/kernel/arch/x86/vmm.h
  type page (line 12) | struct page {
  type page_directory (line 18) | struct page_directory {
  type vm_area (line 23) | struct vm_area {
  type page_directory (line 29) | typedef page_directory proc_memory;
  type page (line 54) | struct page
  type page_directory (line 61) | struct page_directory
  type page_directory (line 62) | struct page_directory
  type page_directory (line 63) | struct page_directory
  type page_directory (line 63) | struct page_directory
  type page_directory (line 70) | struct page_directory
  type kmalloc_header (line 79) | struct kmalloc_header {
  function class (line 86) | class Vmm

FILE: src/kernel/arch/x86/x86.cc
  function regs_t (line 8) | regs_t cpu_cpuid(int code)
  function u32 (line 17) | u32 cpu_vendor_name(char *name)
  function init_gdt_desc (line 63) | void init_gdt_desc(u32 base, u32 limite, u8 acces, u8 other,struct gdtde...
  function init_gdt (line 79) | void init_gdt(void)
  function init_idt_desc (line 121) | void init_idt_desc(u16 select, u32 offset, u16 type, struct idtdesc *desc)
  function do_syscalls (line 137) | void do_syscalls(int num){
  function isr_kbd_int (line 161) | void isr_kbd_int(void)
  function isr_default_int (line 245) | void isr_default_int(int id)
  function isr_schedule_int (line 265) | void isr_schedule_int()
  function isr_GP_exc (line 279) | void isr_GP_exc(void)
  function isr_PF_exc (line 293) | void isr_PF_exc(void)
  function init_idt (line 346) | void init_idt(void)
  function init_pic (line 375) | void init_pic(void)
  function schedule (line 400) | void schedule(){
  function switch_to_task (line 490) | void switch_to_task(process_st* current, int mode)
  function dequeue_signal (line 559) | int dequeue_signal(int mask)
  function handle_signal (line 576) | int handle_signal(int sig)

FILE: src/kernel/arch/x86/x86.h
  type gdtdesc (line 47) | struct gdtdesc {
  type gdtr (line 58) | struct gdtr {
  type tss (line 63) | struct tss {
  type idtdesc (line 84) | struct idtdesc {
  type idtr (line 92) | struct idtr {
  type regs_t (line 97) | typedef struct
  type gdtdesc (line 108) | struct gdtdesc
  type idtdesc (line 110) | struct idtdesc

FILE: src/kernel/core/api/dev/clock.h
  type clock_d (line 4) | typedef unsigned int clock_d;
  type clock_info (line 6) | struct clock_info{

FILE: src/kernel/core/api/dev/fb.h
  type fb_info (line 4) | struct fb_info{

FILE: src/kernel/core/api/dev/proc.h
  type proc_info (line 4) | struct proc_info{

FILE: src/kernel/core/api/dev/tty.h
  type tty_info_static (line 9) | struct tty_info_static{
  type tty_info_moving (line 16) | struct tty_info_moving{
  type TTY_Colour (line 42) | enum TTY_Colour

FILE: src/kernel/core/api_posix.cc
  function call_open (line 7) | void call_open(){
  function call_close (line 27) | void call_close(){
  function call_read (line 47) | void call_read(){
  function call_write (line 72) | void call_write(){
  function call_ioctl (line 97) | void call_ioctl(){
  function call_sbrk (line 121) | void call_sbrk(){
  function call_exit (line 139) | void call_exit(){
  function call_execv (line 151) | void call_execv(){
  function call_symlink (line 173) | void call_symlink(){
  type dirent (line 183) | struct dirent {
  function call_getdents (line 191) | void call_getdents(){
  function call_wait (line 231) | void call_wait(){
  function call_dup2 (line 242) | void call_dup2(){
  function call_fork (line 255) | void call_fork(){
  function call_chdir (line 264) | void call_chdir(){
  function call_mmap (line 283) | void call_mmap(){

FILE: src/kernel/core/boot.h
  type multiboot_info (line 6) | struct multiboot_info {
  type vbe_controller (line 38) | struct vbe_controller
  type vbe_mode (line 55) | struct vbe_mode

FILE: src/kernel/core/device.cc
  function u32 (line 14) | u32	Device::open(u32 flag){
  function u32 (line 18) | u32	Device::close(){
  function u32 (line 22) | u32	Device::read(u8* buffer,u32 size){
  function u32 (line 26) | u32	Device::write(u8* buffer,u32 size){
  function u32 (line 30) | u32	Device::ioctl(u32 id,u8* buffer){
  function u32 (line 34) | u32	Device::remove(){

FILE: src/kernel/core/device.h
  function class (line 8) | class Device : public File

FILE: src/kernel/core/elf_loader.cc
  function is_elf (line 16) | int is_elf(char *file)
  function u32 (line 31) | u32 load_elf(char *file,process_st *proc)
  function execv (line 94) | int execv(char* file,int argc,char** argv){
  function execv_module (line 123) | void execv_module(u32 entry,int argc,char** argv){

FILE: src/kernel/core/elf_loader.h
  type Elf32_Ehdr (line 10) | typedef struct {
  type Elf32_Phdr (line 65) | typedef struct {
  type eElfSectionTypes (line 100) | enum eElfSectionTypes {
  type Elf32_Scdr (line 121) | typedef struct {
  type Elf32_dyn (line 153) | typedef struct {

FILE: src/kernel/core/env.cc
  function u32 (line 35) | u32	Variable::open(u32 flag){
  function u32 (line 39) | u32	Variable::close(){
  function u32 (line 44) | u32	Variable::read(u32 pos,u8* buffer,u32 size){
  function u32 (line 54) | u32	Variable::write(u32 pos,u8* buffer,u32 size){
  function u32 (line 66) | u32	Variable::ioctl(u32 id,u8* buffer){
  function u32 (line 71) | u32	Variable::remove(){

FILE: src/kernel/core/env.h
  function class (line 8) | class Variable : public File

FILE: src/kernel/core/file.cc
  function strreplace (line 10) | static void strreplace(char* s,char a,char to){
  function u32 (line 95) | u32 File::addChild(File* n){
  function File (line 108) | File*	File::createChild(char* n,u8 t){
  function File (line 114) | File*	File::getParent(){
  function File (line 118) | File*	File::getChild(){
  function File (line 122) | File*	File::getNext(){
  function File (line 126) | File*	File::getPrec(){
  function File (line 130) | File*	File::getLink(){
  function u32 (line 134) | u32	File::getSize(){
  function u32 (line 138) | u32	File::getInode(){
  function u8 (line 181) | u8	File::getType(){
  function File (line 189) | File* File::find(char* n){
  function u32 (line 202) | u32	File::open(u32 flag){
  function u32 (line 206) | u32	File::close(){
  function u32 (line 210) | u32	File::read(u32 pos,u8* buffer,u32 size){
  function u32 (line 214) | u32	File::write(u32 pos,u8* buffer,u32 size){
  function u32 (line 218) | u32	File::ioctl(u32 id,u8* buffer){
  function u32 (line 222) | u32	File::remove(){
  function stat_fs (line 227) | stat_fs File::stat(){
  function u32 (line 233) | u32 File::mmap(u32 sizee,u32 flags,u32 offset,u32 prot){

FILE: src/kernel/core/file.h
  function class (line 16) | class File

FILE: src/kernel/core/filesystem.cc
  function File (line 33) | File* Filesystem::getRoot(){
  function File (line 37) | File* Filesystem::path(char* p){
  function File (line 92) | File* Filesystem::pivot_root(File* targetdir){
  function File (line 131) | File* Filesystem::path_parent(char* p,char *fname){
  function u32 (line 187) | u32 Filesystem::link(char* fname,char *newf){
  function u32 (line 202) | u32 Filesystem::addFile(char* dir,File* fp){

FILE: src/kernel/core/filesystem.h
  function class (line 9) | class Filesystem

FILE: src/kernel/core/kernel.cc
  function load_modules (line 9) | static void load_modules(multiboot_info* mbi){
  function kmain (line 29) | void kmain(multiboot_info* mbi){

FILE: src/kernel/core/modulelink.cc
  function u32 (line 15) | u32	ModLink::open(u32 flag){
  function u32 (line 19) | u32	ModLink::close(){
  function u32 (line 23) | u32	ModLink::read(u8* buffer,u32 size){
  function u32 (line 27) | u32	ModLink::write(u8* buffer,u32 size){
  function u32 (line 31) | u32	ModLink::ioctl(u32 id,u8* buffer){
  function u32 (line 35) | u32	ModLink::remove(){

FILE: src/kernel/core/modulelink.h
  function class (line 9) | class ModLink : public File

FILE: src/kernel/core/os.h
  type File (line 8) | typedef File* (*device_driver)	(char* name,u32 flag,File* dev);
  type module_class (line 10) | struct module_class{

FILE: src/kernel/core/process.cc
  function u32 (line 36) | u32	Process::open(u32 flag){
  function u32 (line 40) | u32	Process::close(){
  function Process (line 44) | Process* Process::getPParent(){
  function u32 (line 52) | u32	Process::read(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 62) | u32	Process::write(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 67) | u32	Process::ioctl(u32 id,u8* buffer){
  function u32 (line 96) | u32	Process::wait(){
  function u32 (line 105) | u32	Process::remove(){
  function process_st (line 124) | process_st* Process::getPInfo(){
  function Process (line 128) | Process* Process::getPNext(){
  function u32 (line 132) | u32 Process::create(char* file, int argc, char **argv){
  function u32 (line 164) | u32 Process::addFile(File* f,u32 m){
  function File (line 177) | File* Process::getFile(u32 fd){
  function openfile (line 183) | openfile* Process::getFileInfo(u32 fd){
  function Process (line 197) | Process* Process::schedule(){
  function File (line 224) | File* Process::getCurrentDir(){
  function u8 (line 238) | u8	Process::getState(){
  function u32 (line 247) | u32	Process::getPid(){

FILE: src/kernel/core/process.h
  type openfile (line 18) | struct openfile
  function class (line 25) | class Process : public File

FILE: src/kernel/core/socket.cc
  function u32 (line 15) | u32	Socket::open(u32 flag){
  function u32 (line 19) | u32	Socket::close(){
  function u32 (line 23) | u32	Socket::read(u8* buffer,u32 size){
  function u32 (line 27) | u32	Socket::write(u8* buffer,u32 size){
  function u32 (line 31) | u32	Socket::ioctl(u32 id,u8* buffer){
  function u32 (line 35) | u32	Socket::remove(){

FILE: src/kernel/core/socket.h
  function class (line 9) | class Socket : public File

FILE: src/kernel/core/syscalls.h
  function class (line 14) | class Syscalls

FILE: src/kernel/core/system.cc
  function User (line 81) | User* System::getUser(char* nae){
  function u32 (line 99) | u32 System::isRoot(){

FILE: src/kernel/core/system.h
  function class (line 10) | class System

FILE: src/kernel/core/user.cc
  function u32 (line 19) | u32	User::open(u32 flag){
  function u32 (line 23) | u32	User::close(){
  function u32 (line 27) | u32	User::read(u8* buffer,u32 size){
  function u32 (line 31) | u32	User::write(u8* buffer,u32 size){
  function u32 (line 35) | u32	User::ioctl(u32 id,u8* buffer){
  function u32 (line 39) | u32	User::remove(){
  function User (line 61) | User* User::getUNext(){
  function u32 (line 73) | u32	User::getUType(){

FILE: src/kernel/core/user.h
  function class (line 14) | class User : public File

FILE: src/kernel/modules/bochsvbe.cc
  function BgaWriteRegister (line 8) | static void BgaWriteRegister(unsigned short IndexValue, unsigned short D...
  function BgaReadRegister (line 14) | static unsigned short BgaReadRegister(unsigned short IndexValue)
  function BgaIsAvailable (line 20) | static int BgaIsAvailable(void)
  function BgaSetVideoMode (line 25) | static void BgaSetVideoMode(unsigned int Width, unsigned int Height, uns...
  function BgaSetBank (line 36) | static void BgaSetBank(unsigned short BankNumber)
  function File (line 41) | File* bochs_mknod(char* name,u32 flag,File* dev){
  function u32 (line 68) | u32	Bochs::open(u32 flag){
  function u32 (line 72) | u32	Bochs::read(u32 pos,u8* buffer,u32 size){
  function u32 (line 76) | u32	Bochs::write(u32 pos,u8* buffer,u32 size){
  function u32 (line 80) | u32	Bochs::close(){
  function u32 (line 89) | u32	Bochs::ioctl(u32 id,u8* buffer){
  function u32 (line 129) | u32	Bochs::remove(){

FILE: src/kernel/modules/bochsvbe.h
  function class (line 35) | class Bochs : public Device

FILE: src/kernel/modules/clock_x86.cc
  function GetWeekday (line 8) | static void GetWeekday(unsigned int *Weekday)
  function GetDate (line 20) | static void GetDate(unsigned int *Year, unsigned int *Month, unsigned in...
  function GetTime (line 39) | static void GetTime(unsigned int *Hour, unsigned int *Minute, unsigned i...
  function File (line 61) | File* clockx86_mknod(char* name,u32 flag,File* dev){
  function u32 (line 81) | u32	Clock_x86::close(){
  function u32 (line 85) | u32	Clock_x86::open(u32 flag){
  function u32 (line 89) | u32	Clock_x86::read(u32 pos,u8* buffer,u32 size){
  function u32 (line 93) | u32	Clock_x86::write(u32 pos,u8* buffer,u32 size){
  function u32 (line 102) | u32	Clock_x86::ioctl(u32 id,u8* buffer){
  function u32 (line 128) | u32	Clock_x86::remove(){

FILE: src/kernel/modules/clock_x86.h
  function class (line 11) | class Clock_x86 : public Device

FILE: src/kernel/modules/dospartition.cc
  function File (line 7) | File* dospartition_mount(char* name,u32 flag,File* dev){
  function u32 (line 35) | u32	DosPartition::close(){
  function u32 (line 42) | u32	DosPartition::open(u32 flag){
  function u32 (line 49) | u32	DosPartition::read(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 56) | u32	DosPartition::write(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 63) | u32	DosPartition::ioctl(u32 id,u8* buffer){
  function u32 (line 70) | u32	DosPartition::remove(){

FILE: src/kernel/modules/dospartition.h
  type dos_partition (line 14) | struct dos_partition {
  function class (line 30) | class DosPartition : public Device

FILE: src/kernel/modules/ext2.cc
  function File (line 7) | File* ext2_mount(char* name,u32 flag,File* dev){
  function u32 (line 38) | u32	Ext2::close(){
  function u32 (line 42) | u32	Ext2::open(u32 flag){
  function u32 (line 49) | u32	Ext2::read(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 57) | u32	Ext2::write(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 61) | u32	Ext2::ioctl(u32 id,u8* buffer){
  function u32 (line 65) | u32	Ext2::remove(){
  function ext2_read_sb (line 75) | int ext2_read_sb(File* dev,ext2_super_block *sb)
  function ext2_read_gd (line 85) | int ext2_read_gd(File* fdev,ext2_group_desc *gd,ext2_disk* info)
  function ext2_get_disk_info (line 98) | void ext2_get_disk_info(File*dev,Ext2 *fp)
  function ext2_check_disk (line 115) | int ext2_check_disk(File *dev)
  function ext2_inode (line 129) | ext2_inode *ext2_read_inode(ext2_disk* hd, int i_num)
  function ext2_is_directory (line 144) | int ext2_is_directory(Ext2 *fp)
  function ext2_scan (line 229) | int ext2_scan(Ext2 *dir)

FILE: src/kernel/modules/ext2.h
  type ext2_super_block (line 12) | struct ext2_super_block {
  type ext2_group_desc (line 52) | struct ext2_group_desc {
  type ext2_inode (line 63) | struct ext2_inode {
  type ext2_directory_entry (line 92) | struct ext2_directory_entry {
  type ext2_disk (line 101) | struct ext2_disk {
  function class (line 147) | class Ext2 : public File

FILE: src/kernel/modules/ide.cc
  function bl_wait (line 11) | int bl_wait(unsigned short base)
  function bl_common (line 20) | int bl_common(int drive, int numblock, int count)
  function bl_read (line 39) | int bl_read(int drive, int numblock, int count, char *buf)
  function bl_write (line 61) | int bl_write(int drive, int numblock, int count, char *buf)
  function File (line 83) | File* ide_mknod(char* name,u32 flag,File* dev){
  function u32 (line 100) | u32	Ide::close(){
  function u32 (line 108) | u32	Ide::open(u32 flag){
  function u32 (line 112) | u32	Ide::read(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 132) | u32	Ide::write(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 136) | u32	Ide::ioctl(u32 idd,u8* buffer){
  function u32 (line 160) | u32	Ide::remove(){

FILE: src/kernel/modules/ide.h
  function class (line 9) | class Ide : public Device

FILE: src/kernel/modules/keys.cc
  function File (line 9) | File* keys_mknod(char* name,u32 flag,File* dev){
  function u32 (line 29) | u32	Keyboard::close(){
  function u32 (line 33) | u32	Keyboard::open(u32 flag){
  function u32 (line 37) | u32	Keyboard::read(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 41) | u32	Keyboard::write(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 45) | u32	Keyboard::ioctl(u32 id,u8* buffer){
  function u32 (line 72) | u32	Keyboard::remove(){

FILE: src/kernel/modules/keys.h
  function class (line 11) | class Keyboard : public Device

FILE: src/kernel/modules/module.cc
  function File (line 29) | File* Module::createDevice(char* name,char* module,u32 flag){
  function File (line 46) | File* Module::mount(char* dev,char* dir,char* module,u32 flag){
  function File (line 69) | File* Module::install(char* dir,char* module,u32 flag,char* dev){

FILE: src/kernel/modules/module.h
  function class (line 12) | class Module

FILE: src/kernel/modules/null.cc
  function File (line 7) | File* null_mknod(char* name,u32 flag,File* dev){
  function u32 (line 27) | u32	Null::close(){
  function u32 (line 31) | u32	Null::open(u32 flag){
  function u32 (line 35) | u32	Null::read(u32 pos,u8* buffer,u32 size){
  function u32 (line 40) | u32	Null::write(u32 pos,u8* buffer,u32 size){
  function u32 (line 44) | u32	Null::ioctl(u32 id,u8* buffer){
  function u32 (line 65) | u32	Null::remove(){

FILE: src/kernel/modules/null.h
  function class (line 9) | class Null : public Device

FILE: src/kernel/modules/stdtty.cc
  function File (line 8) | File* console_mknod(char* name,u32 flag,File* dev){
  function u32 (line 46) | u32	Console::open(u32 flag){
  function u32 (line 50) | u32	Console::close(){
  function u32 (line 54) | u32	Console::read(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 58) | u32	Console::write(u32 pos,u8* buffer,u32 size){
  function u32 (line 67) | u32	Console::ioctl(u32 id,u8* buffer){
  function u32 (line 109) | u32	Console::remove(){

FILE: src/kernel/modules/stdtty.h
  function class (line 12) | class Console : public Device

FILE: src/kernel/modules/x86serial.cc
  function File (line 11) | File* x86serial_mknod(char* name,u32 flag,File* dev){
  function u32 (line 38) | u32	X86Serial::open(u32 flag){
  function u32 (line 52) | u32	X86Serial::close(){
  function u32 (line 60) | u32	X86Serial::read(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 69) | u32	X86Serial::write(u32 pos,u8* buffer,u32 sizee){
  function u32 (line 78) | u32	X86Serial::ioctl(u32 id,u8* buffer){
  function u32 (line 99) | u32	X86Serial::remove(){

FILE: src/kernel/modules/x86serial.h
  function class (line 19) | class X86Serial : public Device

FILE: src/kernel/runtime/buffer.cc
  function u32 (line 32) | u32 Buffer::get(u8* c,u32 s){
  function u32 (line 44) | u32 Buffer::isEmpty(){
  function Buffer (line 57) | Buffer &Buffer::operator>>(char *c)

FILE: src/kernel/runtime/buffer.h
  function class (line 6) | class Buffer

FILE: src/kernel/runtime/cxx.cc
  type __cxxabiv1 (line 18) | namespace __cxxabiv1
    function __cxa_guard_acquire (line 24) | int __cxa_guard_acquire(__guard *Guard)		{ return ! *(char *) (Guard); }
    function __cxa_guard_release (line 25) | void __cxa_guard_release(__guard *Guard)	{ *(char *) Guard = 1; }
    function __cxa_guard_abort (line 26) | void __cxa_guard_abort(__guard *)			{ }
  function __cxa_atexit (line 31) | int __cxa_atexit(void (*) (void *), void *, void *)
  function _Unwind_Resume (line 36) | void _Unwind_Resume(){
  function __cxa_finalize (line 40) | void __cxa_finalize(void *)
  function __cxa_pure_virtual (line 45) | void __cxa_pure_virtual()
  function __stack_chk_guard_setup (line 50) | void __stack_chk_guard_setup()
  type IntRegs (line 60) | struct IntRegs
  function __stack_chk_fail (line 62) | void __attribute__((noreturn)) __stack_chk_fail()

FILE: src/kernel/runtime/itoa.cc
  function itoa (line 10) | void itoa(char *buf, unsigned long int n, int base)

FILE: src/kernel/runtime/list.h
  type list_head (line 7) | struct list_head {
  function INIT_LIST_HEAD (line 16) | static inline void INIT_LIST_HEAD(struct list_head *list)
  function list_add (line 22) | static inline void list_add(struct list_head *neww, struct list_head *head)
  function list_del (line 30) | static inline void list_del(struct list_head *p)
  function list_empty (line 38) | static inline int list_empty(const struct list_head *head)

FILE: src/kernel/runtime/string.cc
  function strlen (line 8) | int strlen(char *s)
  function strcmp (line 44) | int strcmp(const char *dst, char *src)
  function strcpy (line 57) | int strcpy(char *dst,const char *src)
  function strcat (line 66) | void strcat(void *dest,const void *src)
  function strncmp (line 72) | int strncmp( const char* s1, const char* s2, int c ) {

FILE: src/kernel/runtime/types.h
  type u8 (line 8) | typedef unsigned char 	u8;
  type u16 (line 9) | typedef unsigned short 	u16;
  type u32 (line 10) | typedef unsigned int 	u32;
  type u64 (line 11) | typedef unsigned long long 	u64;
  type s8 (line 14) | typedef signed char 	s8;
  type s16 (line 15) | typedef signed short 	s16;
  type s32 (line 16) | typedef signed int 		s32;
  type s64 (line 17) | typedef signed long long	s64;
  type u_char (line 20) | typedef unsigned char u_char;
  type pid_t (line 23) | typedef int pid_t;
  type s64 (line 24) | typedef s64 ino_t;
  type s64 (line 25) | typedef s64 off_t;
  type dev_t (line 26) | typedef int dev_t;
  type mode_t (line 27) | typedef int mode_t;
  type nlink_t (line 28) | typedef int nlink_t;
  type uid_t (line 29) | typedef int uid_t;
  type gid_t (line 30) | typedef int gid_t;
  type blksize_t (line 31) | typedef int blksize_t;
  type s64 (line 32) | typedef s64 blkcnt_t;
  type stat_fs (line 35) | struct stat_fs {

FILE: src/sdk/include/arpa/inet.h
  type in_addr (line 8) | struct in_addr
  type in_addr (line 14) | struct in_addr
  type in_addr (line 16) | struct in_addr
  type in_addr (line 18) | struct in_addr
  type in_addr (line 20) | struct in_addr

FILE: src/sdk/include/assert.h
  function __assert_fail (line 19) | static inline void __assert_fail( const char* expr, const char* file, in...

FILE: src/sdk/include/ctype.h
  type ldiv_t (line 23) | typedef struct {
  type div_t (line 28) | typedef struct {

FILE: src/sdk/include/dirent.h
  type DIR (line 10) | typedef struct DIR {
  type dirent (line 18) | struct dirent
  type dirent (line 19) | struct dirent
  type dirent (line 19) | struct dirent

FILE: src/sdk/include/getopt.h
  type option_t (line 6) | typedef struct option {
  type option (line 24) | struct option
  type option (line 27) | struct option

FILE: src/sdk/include/locale.h
  type lconv (line 23) | struct lconv {
  type lconv (line 50) | struct lconv

FILE: src/sdk/include/netinet/in.h
  type in_port_t (line 81) | typedef uint16_t in_port_t;
  type in_addr_t (line 82) | typedef uint32_t in_addr_t;
  type in_addr (line 84) | struct in_addr {
  type sockaddr_in (line 88) | struct sockaddr_in {

FILE: src/sdk/include/pwd.h
  type passwd (line 9) | struct passwd {
  type passwd (line 19) | struct passwd
  type passwd (line 20) | struct passwd
  type passwd (line 21) | struct passwd

FILE: src/sdk/include/signal.h
  type sig_atomic_t (line 66) | typedef int sig_atomic_t;
  type sigset_t (line 67) | typedef uint64_t sigset_t;
  type sigval_t (line 68) | typedef int sigval_t;
  type __sighandler_t (line 70) | typedef __sighandler_t sighandler_t;
  type siginfo_t (line 72) | typedef struct siginfo {
  type sigaction (line 94) | struct sigaction {
  type sigaction (line 109) | struct sigaction
  type sigaction (line 109) | struct sigaction

FILE: src/sdk/include/stdarg.h
  type __builtin_va_list (line 6) | typedef __builtin_va_list va_list;

FILE: src/sdk/include/stddef.h
  type wchar_t (line 24) | typedef int	wchar_t;

FILE: src/sdk/include/stdint.h
  type intmax_t (line 20) | typedef signed long int intmax_t;
  type uintmax_t (line 21) | typedef unsigned long int uintmax_t;
  type intmax_t (line 23) | typedef signed long long int intmax_t;
  type uintmax_t (line 24) | typedef unsigned long long int uintmax_t;

FILE: src/sdk/include/stdio.h
  type FILE (line 41) | typedef struct FILE {

FILE: src/sdk/include/sys/resource.h
  type rusage (line 8) | struct rusage {

FILE: src/sdk/include/sys/select.h
  type fd_set (line 21) | typedef struct fd_set {
  type timeval (line 25) | struct timeval

FILE: src/sdk/include/sys/socket.h
  type socket_type (line 80) | enum socket_type {
  type sa_family_t (line 91) | typedef unsigned short int sa_family_t;
  type socklen_t (line 92) | typedef unsigned int socklen_t;
  type sockaddr (line 94) | struct sockaddr {
  type sockaddr (line 100) | struct sockaddr

FILE: src/sdk/include/sys/stat.h
  type stat (line 44) | struct stat {
  type stat (line 60) | struct stat
  type stat (line 61) | struct stat
  type stat (line 62) | struct stat

FILE: src/sdk/include/sys/time.h
  type timeval (line 8) | struct timeval
  type timezone (line 8) | struct timezone

FILE: src/sdk/include/sys/types.h
  type u_char (line 21) | typedef unsigned char u_char;
  type pid_t (line 24) | typedef int pid_t;
  type ino_t (line 25) | typedef int64_t ino_t;
  type off_t (line 26) | typedef int64_t off_t;
  type dev_t (line 27) | typedef int dev_t;
  type mode_t (line 28) | typedef int mode_t;
  type nlink_t (line 29) | typedef int nlink_t;
  type uid_t (line 30) | typedef int uid_t;
  type gid_t (line 31) | typedef int gid_t;
  type blksize_t (line 32) | typedef int blksize_t;
  type blkcnt_t (line 33) | typedef int64_t blkcnt_t;

FILE: src/sdk/include/sys/wait.h
  type rusage (line 14) | struct rusage
  type rusage (line 15) | struct rusage

FILE: src/sdk/include/termios.h
  type cc_t (line 182) | typedef unsigned char cc_t;
  type speed_t (line 183) | typedef unsigned int speed_t;
  type tcflag_t (line 184) | typedef unsigned int tcflag_t;
  type termios (line 186) | struct termios {
  type winsize (line 197) | struct winsize {
  type termios (line 204) | struct termios
  type termios (line 205) | struct termios

FILE: src/sdk/include/time.h
  type clock_t (line 11) | typedef unsigned int clock_t;
  type timeval_t (line 13) | typedef struct timeval {
  type timezone_t (line 18) | typedef struct timezone {
  type timespec (line 23) | struct timespec {
  type tm_t (line 28) | typedef struct tm {
  type tm (line 46) | struct tm
  type timespec (line 63) | struct timespec
  type timespec (line 63) | struct timespec

FILE: src/sdk/include/unistd.h
  type dirent (line 69) | struct dirent {
  type dirent (line 100) | struct dirent

FILE: src/sdk/include/utime.h
  type utimbuf (line 9) | struct utimbuf {
  type utimbuf (line 14) | struct utimbuf

FILE: src/sdk/src/libc/arch/i386/getpagesize.c
  function getpagesize (line 21) | int getpagesize( void ) {

FILE: src/sdk/src/libc/src/closedir.c
  function closedir (line 9) | int closedir( DIR* dir ) {

FILE: src/sdk/src/libc/src/ctype/isalnum.c
  function isalnum (line 6) | int isalnum( int c ) {

FILE: src/sdk/src/libc/src/ctype/isalpha.c
  function isalpha (line 6) | int isalpha( int c ) {

FILE: src/sdk/src/libc/src/ctype/isascii.c
  function isascii (line 6) | int isascii( int c ) {

FILE: src/sdk/src/libc/src/ctype/isblank.c
  function isblank (line 6) | int isblank( int c ) {

FILE: src/sdk/src/libc/src/ctype/iscntrl.c
  function iscntrl (line 6) | int iscntrl( int c ) {

FILE: src/sdk/src/libc/src/ctype/isdigit.c
  function isdigit (line 6) | int isdigit( int c ) {

FILE: src/sdk/src/libc/src/ctype/isgraph.c
  function isgraph (line 6) | int isgraph( int c ) {

FILE: src/sdk/src/libc/src/ctype/islower.c
  function islower (line 6) | int islower( int c ) {

FILE: src/sdk/src/libc/src/ctype/isprint.c
  function isprint (line 6) | int isprint( int c ) {

FILE: src/sdk/src/libc/src/ctype/ispunct.c
  function ispunct (line 6) | int ispunct( int c ) {

FILE: src/sdk/src/libc/src/ctype/isspace.c
  function isspace (line 6) | int isspace( int c ) {

FILE: src/sdk/src/libc/src/ctype/isupper.c
  function isupper (line 6) | int isupper( int c ) {

FILE: src/sdk/src/libc/src/ctype/isxdigit.c
  function isxdigit (line 6) | int isxdigit( int c ) {

FILE: src/sdk/src/libc/src/ctype/toascii.c
  function toascii (line 6) | int toascii( int c ) {

FILE: src/sdk/src/libc/src/ctype/tolower.c
  function tolower (line 6) | int tolower( int c ) {

FILE: src/sdk/src/libc/src/ctype/toupper.c
  function toupper (line 5) | int toupper( int c ) {
  function ldiv_t (line 13) | ldiv_t ldiv(long numerator, long denominator) {
  function div_t (line 20) | div_t div(int numerator, int denominator) {

FILE: src/sdk/src/libc/src/fcntl/creat.c
  function creat (line 6) | int creat( const char *pathname, mode_t mode ) {

FILE: src/sdk/src/libc/src/fcntl/fcntl.c
  function fcntl (line 9) | int fcntl( int fd, int cmd, ... ) {

FILE: src/sdk/src/libc/src/fcntl/open.c
  function open (line 9) | int open( const char* filename, int flags, ... ) {

FILE: src/sdk/src/libc/src/getopt/getopt.c
  type _getopt_data (line 29) | struct _getopt_data
  function exchange (line 31) | static void
  type _getopt_data (line 114) | struct _getopt_data
  function _getopt_internal_r (line 232) | int
  function _getopt_internal (line 954) | int _getopt_internal ( int argc, char *const *argv, const char *optstring,
  function getopt (line 971) | int getopt( int argc, char* const * argv, const char* optstring ) {

FILE: src/sdk/src/libc/src/getopt/getopt_int.h
  type _getopt_data (line 6) | struct _getopt_data
  type option (line 34) | struct option
  type option (line 39) | struct option
  type _getopt_data (line 40) | struct _getopt_data
  type option (line 44) | struct option
  type _getopt_data (line 45) | struct _getopt_data
  type option (line 49) | struct option
  type _getopt_data (line 51) | struct _getopt_data

FILE: src/sdk/src/libc/src/getopt/getopt_long.c
  function getopt_long (line 11) | int getopt_long( int argc, char* const * argv, const char* shortopts,

FILE: src/sdk/src/libc/src/getopt/getopt_long_only.c
  function getopt_long_only (line 11) | int getopt_long_only( int argc, char* const * argv,

FILE: src/sdk/src/libc/src/locale/localeconv.c
  type lconv (line 7) | struct lconv
  type lconv (line 34) | struct lconv
  type lconv (line 35) | struct lconv

FILE: src/sdk/src/libc/src/math/s_ldexp.c
  function ldexp (line 7) | double ldexp( double value, int exp ) {

FILE: src/sdk/src/libc/src/math/s_modf.c
  type ieee_double_shape_type (line 33) | typedef union
  function modf (line 45) | double modf(double x, double *iptr) {

FILE: src/sdk/src/libc/src/network/inet_aton.c
  function inet_aton (line 8) | int inet_aton( const char* cp, struct in_addr* inp ) {

FILE: src/sdk/src/libc/src/network/inet_ntoa.c
  type in_addr (line 9) | struct in_addr

FILE: src/sdk/src/libc/src/opendir.c
  function DIR (line 8) | DIR* opendir( const char* name ) {

FILE: src/sdk/src/libc/src/os/syscall.c
  function syscall0 (line 7) | int syscall0( int number ){
  function syscall1 (line 20) | int syscall1( int number, uint32_t p1 ){
  function syscall2 (line 34) | int syscall2( int number, uint32_t p1, uint32_t p2 ){
  function syscall3 (line 50) | int syscall3( int number, uint32_t p1, uint32_t p2, uint32_t p3 ){
  function syscall4 (line 66) | int syscall4( int number, uint32_t p1, uint32_t p2, uint32_t p3, uint32_...
  function syscall5 (line 83) | int syscall5( int number, uint32_t p1, uint32_t p2, uint32_t p3, uint32_...

FILE: src/sdk/src/libc/src/pwd/endpwent.c
  function endpwent (line 8) | void endpwent( void ) {

FILE: src/sdk/src/libc/src/pwd/getpwent.c
  type passwd_myos (line 7) | typedef struct passwd_myos passwd_myos;
  type passwd_myos (line 8) | struct passwd_myos {
  function passwd_myos (line 20) | passwd_myos* myos_user_getN(const char* name){
  function passwd_myos (line 28) | passwd_myos* myos_user_getID(int id){
  type passwd (line 38) | struct passwd
  function build_tmp_passwd (line 40) | void build_tmp_passwd(){
  type passwd (line 51) | struct passwd

FILE: src/sdk/src/libc/src/pwd/getpwnam.c
  type passwd_myos (line 7) | typedef struct passwd_myos passwd_myos;
  type passwd_myos (line 8) | struct passwd_myos {
  type passwd (line 18) | struct passwd
  type passwd (line 22) | struct passwd

FILE: src/sdk/src/libc/src/pwd/getpwuid.c
  type passwd_myos (line 7) | typedef struct passwd_myos passwd_myos;
  type passwd_myos (line 8) | struct passwd_myos {
  type passwd (line 18) | struct passwd
  type passwd (line 23) | struct passwd

FILE: src/sdk/src/libc/src/pwd/setpwent.c
  function setpwent (line 8) | void setpwent( void ) {

FILE: src/sdk/src/libc/src/readdir.c
  type dirent (line 8) | struct dirent
  type dirent (line 15) | struct dirent
  function readdir_r (line 24) | int readdir_r( DIR* dir, struct dirent* entry, struct dirent** result ) {

FILE: src/sdk/src/libc/src/rewinddir.c
  function rewinddir (line 9) | void rewinddir( DIR* dirp ) {

FILE: src/sdk/src/libc/src/signal/kill.c
  function kill (line 9) | int kill( pid_t pid, int signal ) {

FILE: src/sdk/src/libc/src/signal/killpg.c
  function killpg (line 6) | int killpg( int pgrp, int signal ) {

FILE: src/sdk/src/libc/src/signal/raise.c
  function raise (line 8) | int raise( int signal ) {

FILE: src/sdk/src/libc/src/signal/sigaction.c
  function sigaction (line 9) | int sigaction( int signum, const struct sigaction* act, struct sigaction...

FILE: src/sdk/src/libc/src/signal/sigaddset.c
  function sigaddset (line 7) | int sigaddset( sigset_t* set, int signum ) {

FILE: src/sdk/src/libc/src/signal/sigdelset.c
  function sigdelset (line 7) | int sigdelset( sigset_t* set, int signum ) {

FILE: src/sdk/src/libc/src/signal/sigemptyset.c
  function sigemptyset (line 7) | int sigemptyset( sigset_t* set ) {

FILE: src/sdk/src/libc/src/signal/sigfillset.c
  function sigfillset (line 8) | int sigfillset( sigset_t* set ) {

FILE: src/sdk/src/libc/src/signal/sigismember.c
  function sigismember (line 7) | int sigismember( const sigset_t* set, int signum ) {

FILE: src/sdk/src/libc/src/signal/signal.c
  function sighandler_t (line 7) | sighandler_t signal( int signum, sighandler_t handler ) {

FILE: src/sdk/src/libc/src/signal/sigprocmask.c
  function sigprocmask (line 9) | int sigprocmask( int how, const sigset_t* set, sigset_t* oldset ) {

FILE: src/sdk/src/libc/src/sscanf.c
  function simple_strtoul (line 30) | unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
  function simple_strtol (line 61) | long simple_strtol(const char *cp,char **endp,unsigned int base)
  function simple_strtoull (line 74) | unsigned long long simple_strtoull(const char *cp,char **endp,unsigned i...
  function simple_strtoll (line 105) | long long simple_strtoll(const char *cp,char **endp,unsigned int base)
  function skip_atoi (line 112) | static int skip_atoi(const char **s)
  function vsscanf (line 127) | int vsscanf(const char * buf, const char * fmt, va_list args)
  function sscanf (line 326) | int sscanf(const char * buf, const char * fmt, ...)
  function fscanf (line 337) | int fscanf(FILE*stream,const char * fmt, ...){
  function scanf (line 350) | int scanf(const char * fmt, ...){

FILE: src/sdk/src/libc/src/start.c
  function _start (line 21) | void _start(int argc, char** argv) {

FILE: src/sdk/src/libc/src/stdio/clearerr.c
  function clearerr (line 6) | void clearerr( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fclose.c
  function fclose (line 8) | int fclose( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fdopen.c
  function FILE (line 10) | FILE* fdopen( int fd, const char* mode ) {

FILE: src/sdk/src/libc/src/stdio/feof.c
  function feof (line 6) | int feof( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/ferror.c
  function ferror (line 6) | int ferror( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fflush.c
  function fflush (line 7) | int fflush( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fgetc.c
  function fgetc (line 9) | int fgetc( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fileno.c
  function fileno (line 6) | int fileno( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fopen.c
  function __parse_mode (line 9) | int __parse_mode( const char* mode ) {
  function FILE (line 27) | FILE* __init_file( int fd, int close_on_error, int mode ) {
  function FILE (line 70) | FILE* fopen( const char* path, const char* mode ) {

FILE: src/sdk/src/libc/src/stdio/fpurge.c
  function fpurge (line 8) | int fpurge( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fputc.c
  function fputc (line 9) | int fputc( int c, FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fputs.c
  function fputs (line 7) | int fputs( const char* s, FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fread.c
  function fread (line 8) | size_t fread( void* ptr, size_t size, size_t nmemb, FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/freopen.c
  function FILE (line 11) | FILE* freopen( const char* path, const char* mode, FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fseek.c
  function fseeko (line 7) | int fseeko( FILE* stream, off_t offset, int whence ) {
  function fseek (line 18) | int fseek( FILE* stream, long offset, int whence ) {

FILE: src/sdk/src/libc/src/stdio/ftell.c
  function off_t (line 9) | off_t ftello( FILE* stream ) {
  function ftell (line 29) | long ftell( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/fwrite.c
  function fwrite (line 9) | size_t fwrite( const void* ptr, size_t size, size_t nmemb, FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/getc.c
  function getc (line 5) | int getc( FILE* stream ) {
  function gets (line 9) | int gets(char* buf){

FILE: src/sdk/src/libc/src/stdio/perror.c
  function perror (line 8) | void perror( const char* s ) {

FILE: src/sdk/src/libc/src/stdio/putc.c
  function putc (line 8) | int putc( int c, FILE* stream ) {
  function vfprintf (line 16) | int vfprintf(FILE* stream, const char* format, va_list arg)
  function printf (line 21) | int printf(const char* format, ...)
  function fprintf (line 32) | int fprintf(FILE*stream,const char* format, ...)

FILE: src/sdk/src/libc/src/stdio/putchar.c
  function putchar (line 6) | int putchar( int c ) {

FILE: src/sdk/src/libc/src/stdio/puts.c
  function puts (line 6) | int puts( const char* s ) {

FILE: src/sdk/src/libc/src/stdio/remove.c
  function remove (line 9) | int remove( const char* path ) {

FILE: src/sdk/src/libc/src/stdio/rename.c
  function rename (line 8) | int rename( const char* oldpath, const char* newpath ) {

FILE: src/sdk/src/libc/src/stdio/rewind.c
  function rewind (line 6) | void rewind( FILE* stream ) {

FILE: src/sdk/src/libc/src/stdio/setvbuf.c
  function set_flags (line 9) | static int set_flags( FILE* stream, int flags ) {
  function setvbuf (line 28) | int setvbuf( FILE* stream, char* buf, int flags, size_t size ) {

FILE: src/sdk/src/libc/src/stdio/stdio_internal.c
  function __set_stream_flags (line 8) | int __set_stream_flags( FILE* stream, int new_flags ) {

FILE: src/sdk/src/libc/src/stdio/support_bufio.c
  function bufcon_leni (line 17) | int  bufcon_leni(int num)
  function bufcon_lenui (line 47) | int  bufcon_lenui(unsigned int p)
  function bufcon_lenp (line 63) | int  bufcon_lenp(unsigned int p)
  function bufcon_lenx (line 76) | int  bufcon_lenx( unsigned int  p )
  function bufcon_lens (line 81) | int  bufcon_lens( char *s )

FILE: src/sdk/src/libc/src/stdio/support_pf.c
  function printf_buffer (line 33) | int printf_buffer(int i)
  function support_vfprintf (line 45) | int 	support_vfprintf(FILE* stream, const char* format, va_list ap)
  function sprintf_buffer (line 220) | int sprintf_buffer(char *s, int i)
  function vsnprintf (line 228) | int vsnprintf(char* str, size_t size, const char *format, va_list arg_pt...
  function snprintf (line 232) | int snprintf(char *str,size_t size,const char *format,...)
  function support_vsprintf (line 242) | int 	support_vsprintf(char* buffer, const char* format, va_list ap)

FILE: src/sdk/src/libc/src/stdio/support_supcon.c
  function supcon_leni (line 7) | int  supcon_leni(int num)
  function supcon_lenui (line 37) | int  supcon_lenui(unsigned int p)
  function supcon_lenp (line 53) | int  supcon_lenp(unsigned int p)
  function supcon_lenx (line 66) | int  supcon_lenx( unsigned int  p )
  function supcon_puts (line 75) | void supcon_puts( unsigned char *c )
  function supcon_putc (line 80) | void supcon_putc( unsigned char c )
  function supcon_puti (line 90) | void  supcon_puti( int num )
  function supcon_putui (line 133) | void  supcon_putui( unsigned int num )
  function supcon_putp (line 160) | void  supcon_putp( unsigned int num, char offset )
  function supcon_putx (line 190) | void  supcon_putx( unsigned int num )
  function supcon_putX (line 195) | void  supcon_putX( unsigned int num )

FILE: src/sdk/src/libc/src/stdio/ungetc.c
  function ungetc (line 5) | int ungetc( int c, FILE* stream ) {

FILE: src/sdk/src/libc/src/stdlib/abort.c
  function abort (line 8) | void abort( void ) {

FILE: src/sdk/src/libc/src/stdlib/abs.c
  function abs (line 6) | int abs( int j ) {

FILE: src/sdk/src/libc/src/stdlib/atof.c
  function atof (line 6) | double atof( const char* s ) {

FILE: src/sdk/src/libc/src/stdlib/atoi.c
  function atoi (line 7) | int atoi( const char* s ) {

FILE: src/sdk/src/libc/src/stdlib/atol.c
  function atol (line 7) | long atol( const char* s ) {

FILE: src/sdk/src/libc/src/stdlib/atoll.c
  function atoll (line 7) | long long int atoll( const char* s ) {

FILE: src/sdk/src/libc/src/stdlib/labs.c
  function labs (line 6) | long labs( long j ) {

FILE: src/sdk/src/libc/src/stdlib/llabs.c
  function llabs (line 6) | long long llabs( long long j ) {

FILE: src/sdk/src/libc/src/stdlib/malloc.c
  type malloc_header (line 9) | struct malloc_header {
  type malloc_header (line 29) | struct malloc_header
  type malloc_header (line 31) | struct malloc_header
  type malloc_header (line 46) | struct malloc_header
  type malloc_header (line 51) | struct malloc_header
  type malloc_header (line 54) | struct malloc_header
  type malloc_header (line 56) | struct malloc_header
  type malloc_header (line 61) | struct malloc_header
  type malloc_header (line 66) | struct malloc_header
  type malloc_header (line 79) | struct malloc_header
  type malloc_header (line 88) | struct malloc_header
  function free (line 92) | void free(void *v_addr)
  type malloc_header (line 121) | struct malloc_header
  type malloc_header (line 121) | struct malloc_header

FILE: src/sdk/src/libc/src/stdlib/mkstemp.c
  function mkstemp (line 11) | int mkstemp( char* template ) {

FILE: src/sdk/src/libc/src/stdlib/qsort.c
  function exch (line 7) | static void exch(char* base,size_t size,size_t a,size_t b) {
  function quicksort (line 21) | static void quicksort(char* base,size_t size,ssize_t l,ssize_t r,
  function qsort (line 41) | void qsort(void* base,size_t nmemb,size_t size,int (*compar)(const void*...

FILE: src/sdk/src/libc/src/stdlib/rand.c
  function rand (line 8) | int rand( void ) {

FILE: src/sdk/src/libc/src/stdlib/random.c
  function random (line 6) | long int random( void ) {

FILE: src/sdk/src/libc/src/stdlib/srand.c
  function srand (line 8) | void srand(unsigned int seed){

FILE: src/sdk/src/libc/src/stdlib/srandom.c
  function srandom (line 8) | void srandom(unsigned int seed){

FILE: src/sdk/src/libc/src/stdlib/strtod.c
  function strtod (line 8) | double strtod( const char* s, char** endptr ) {

FILE: src/sdk/src/libc/src/stdlib/strtol.c
  function strtol (line 15) | long int strtol( const char* nptr, char** endptr, int base ) {

FILE: src/sdk/src/libc/src/stdlib/strtoll.c
  function strtoll (line 10) | long long int strtoll( const char* nptr, char** endptr, int base ) {

FILE: src/sdk/src/libc/src/stdlib/strtoul.c
  function strtoul (line 9) | unsigned long int strtoul( const char* ptr, char** endptr, int base ) {

FILE: src/sdk/src/libc/src/stdlib/strtoull.c
  function strtoull (line 10) | unsigned long long int strtoull( const char* ptr, char** endptr, int bas...

FILE: src/sdk/src/libc/src/string/memcmp.c
  function memcmp (line 6) | int memcmp( const void* p1, const void* p2, size_t c ) {

FILE: src/sdk/src/libc/src/string/strcasecmp.c
  function strcasecmp (line 7) | int strcasecmp( const char* s1, const char* s2 ) {

FILE: src/sdk/src/libc/src/string/strcmp.c
  function strcmp (line 6) | int strcmp( const char* s1, const char* s2 ) {

FILE: src/sdk/src/libc/src/string/strcpy.c
  function vsprintf (line 18) | int vsprintf(char* s, const char* format, va_list arg)
  function sprintf (line 24) | int sprintf(char *buffer, const char* format, ...)

FILE: src/sdk/src/libc/src/string/strcspn.c
  function strcspn (line 7) | size_t strcspn( const char* s, const char* reject ) {

FILE: src/sdk/src/libc/src/string/strlen.c
  function strlen (line 6) | size_t strlen( const char* s ) {

FILE: src/sdk/src/libc/src/string/strncasecmp.c
  function strncasecmp (line 7) | int strncasecmp( const char* s1, const char* s2, size_t c ) {

FILE: src/sdk/src/libc/src/string/strncmp.c
  function strncmp (line 6) | int strncmp( const char* s1, const char* s2, size_t c ) {

FILE: src/sdk/src/libc/src/string/strnlen.c
  function strnlen (line 6) | size_t strnlen( const char* s, size_t count ) {

FILE: src/sdk/src/libc/src/string/strspn.c
  function strspn (line 6) | size_t strspn( const char* s, const char* accept ) {

FILE: src/sdk/src/libc/src/sys/chmod.c
  function chmod (line 6) | int chmod( const char* path, mode_t mode ) {

FILE: src/sdk/src/libc/src/sys/connect.c
  function connect (line 9) | int connect( int fd, const struct sockaddr* address, socklen_t addrlen ) {

FILE: src/sdk/src/libc/src/sys/fstat.c
  function fstat (line 9) | int fstat( int fd, struct stat* stat ) {

FILE: src/sdk/src/libc/src/sys/ioctl.c
  function ioctl (line 8) | int ioctl( int fd, int request, ... ) {

FILE: src/sdk/src/libc/src/sys/lstat.c
  function lstat (line 9) | int lstat( const char* path, struct stat* stat ) {

FILE: src/sdk/src/libc/src/sys/mkdir.c
  function mkdir (line 9) | int mkdir( const char* pathname, mode_t mode ) {

FILE: src/sdk/src/libc/src/sys/mount.c
  function mount (line 9) | int mount(

FILE: src/sdk/src/libc/src/sys/select.c
  function select (line 9) | int select( int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfd...

FILE: src/sdk/src/libc/src/sys/socket.c
  function socket (line 9) | int socket( int domain, int type, int protocol ) {

FILE: src/sdk/src/libc/src/sys/stat.c
  function stat (line 8) | int stat( const char* path, struct stat* stat ) {

FILE: src/sdk/src/libc/src/sys/stime.c
  function stime (line 9) | int stime( time_t *t ) {

FILE: src/sdk/src/libc/src/sys/umask.c
  function mode_t (line 6) | mode_t umask( mode_t mask ) {

FILE: src/sdk/src/libc/src/sys/umount.c
  function umount (line 9) | int umount(

FILE: src/sdk/src/libc/src/sys/utime.c
  function utime (line 9) | int utime( const char* filename, const struct utimbuf* times ) {

FILE: src/sdk/src/libc/src/sys/utimes.c
  function utimes (line 9) | int utimes( const char* filename, const timeval_t times[2] ) {

FILE: src/sdk/src/libc/src/sys/wait.c
  function pid_t (line 6) | pid_t wait( int* status ) {

FILE: src/sdk/src/libc/src/sys/wait3.c
  function pid_t (line 6) | pid_t wait3( int* status, int options, struct rusage* rusage ) {

FILE: src/sdk/src/libc/src/sys/wait4.c
  function pid_t (line 9) | pid_t wait4( pid_t pid, int* status, int options, struct rusage* rusage ) {

FILE: src/sdk/src/libc/src/sys/waitpid.c
  function pid_t (line 9) | pid_t waitpid( pid_t pid, int* status, int options ) {

FILE: src/sdk/src/libc/src/termios/tcflow.c
  function tcflow (line 6) | int tcflow( int fd, int action ) {

FILE: src/sdk/src/libc/src/termios/tcflush.c
  function tcflush (line 6) | int tcflush( int fd, int queue_selector ) {

FILE: src/sdk/src/libc/src/termios/tcgetattr.c
  function tcgetattr (line 9) | int tcgetattr( int fd, struct termios* tio ) {

FILE: src/sdk/src/libc/src/termios/tcgetpgrp.c
  function pid_t (line 3) | pid_t tcgetpgrp( int fd ) {

FILE: src/sdk/src/libc/src/termios/tcsetattr.c
  function tcsetattr (line 9) | int tcsetattr( int fd, int optional_actions, const struct termios* tio ) {

FILE: src/sdk/src/libc/src/termios/tcsetpgrp.c
  function tcsetpgrp (line 3) | int tcsetpgrp( int fd, pid_t pgrp ) {

FILE: src/sdk/src/libc/src/time/gettimeofday.c
  function gettimeofday (line 8) | int gettimeofday( struct timeval* tv, struct timezone* tz ) {

FILE: src/sdk/src/libc/src/time/gmtime.c
  function tm_t (line 8) | tm_t* gmtime( const time_t* timep ) {

FILE: src/sdk/src/libc/src/time/gmtime_r.c
  function tm_t (line 8) | tm_t* gmtime_r( const time_t* timep, tm_t* result ) {

FILE: src/sdk/src/libc/src/time/localtime.c
  function tm_t (line 7) | tm_t* localtime( const time_t* timep ) {

FILE: src/sdk/src/libc/src/time/localtime_r.c
  function tm_t (line 6) | tm_t* localtime_r( const time_t* timep, tm_t* result ) {

FILE: src/sdk/src/libc/src/time/mktime.c
  function time_t (line 8) | time_t mktime( tm_t* tm ) {

FILE: src/sdk/src/libc/src/time/nanosleep.c
  function nanosleep (line 10) | int nanosleep( const struct timespec* req, struct timespec* rem ) {

FILE: src/sdk/src/libc/src/time/strftime.c
  function strftime (line 36) | size_t strftime(char* s, size_t max, const char* format,

FILE: src/sdk/src/libc/src/time/time.c
  function time_t (line 8) | time_t time( time_t* t ) {

FILE: src/sdk/src/libc/src/time/time_int.c
  function _gmtime (line 24) | int _gmtime( time_t timeval, tm_t* ret ) {
  function daysdiff (line 77) | int daysdiff( int year, int month, int day ) {
  function dayofweek (line 99) | int dayofweek( int year, int month, int day ) {

FILE: src/sdk/src/libc/src/time/tzset.c
  function tzset (line 4) | void tzset( void ) {

FILE: src/sdk/src/libc/src/trio/trio.c
  type trio_flags_t (line 203) | typedef unsigned long trio_flags_t;
  type wchar_t (line 235) | typedef wchar_t trio_wchar_t;
  type wint_t (line 236) | typedef wint_t trio_wint_t;
  type trio_wchar_t (line 238) | typedef char trio_wchar_t;
  type trio_wint_t (line 239) | typedef int trio_wint_t;
  type trio_longlong_t (line 284) | typedef signed long long int trio_longlong_t;
  type trio_ulonglong_t (line 285) | typedef unsigned long long int trio_ulonglong_t;
  type trio_longlong_t (line 288) | typedef signed __int64 trio_longlong_t;
  type trio_ulonglong_t (line 289) | typedef unsigned __int64 trio_ulonglong_t;
  type trio_longlong_t (line 291) | typedef TRIO_SIGNED long int trio_longlong_t;
  type trio_ulonglong_t (line 292) | typedef unsigned long int trio_ulonglong_t;
  type intmax_t (line 299) | typedef intmax_t trio_intmax_t;
  type uintmax_t (line 300) | typedef uintmax_t trio_uintmax_t;
  type trio_int8_t (line 301) | typedef int8_t trio_int8_t;
  type trio_int16_t (line 302) | typedef int16_t trio_int16_t;
  type trio_int32_t (line 303) | typedef int32_t trio_int32_t;
  type trio_int64_t (line 304) | typedef int64_t trio_int64_t;
  type intmax_t (line 308) | typedef intmax_t trio_intmax_t;
  type uintmax_t (line 309) | typedef uintmax_t trio_uintmax_t;
  type trio_int8_t (line 310) | typedef int8_t trio_int8_t;
  type trio_int16_t (line 311) | typedef int16_t trio_int16_t;
  type trio_int32_t (line 312) | typedef int32_t trio_int32_t;
  type trio_int64_t (line 313) | typedef int64_t trio_int64_t;
  type trio_longlong_t (line 316) | typedef trio_longlong_t trio_intmax_t;
  type trio_ulonglong_t (line 317) | typedef trio_ulonglong_t trio_uintmax_t;
  type __int8 (line 318) | typedef __int8 trio_int8_t;
  type __int16 (line 319) | typedef __int16 trio_int16_t;
  type __int32 (line 320) | typedef __int32 trio_int32_t;
  type __int64 (line 321) | typedef __int64 trio_int64_t;
  type trio_longlong_t (line 323) | typedef trio_longlong_t trio_intmax_t;
  type trio_ulonglong_t (line 324) | typedef trio_ulonglong_t trio_uintmax_t;
  type TRIO_INT8_T (line 326) | typedef TRIO_INT8_T trio_int8_t;
  type TRIO_SIGNED (line 328) | typedef TRIO_SIGNED char trio_int8_t;
  type TRIO_INT16_T (line 331) | typedef TRIO_INT16_T trio_int16_t;
  type trio_int16_t (line 333) | typedef TRIO_SIGNED short trio_int16_t;
  type TRIO_INT32_T (line 336) | typedef TRIO_INT32_T trio_int32_t;
  type TRIO_SIGNED (line 338) | typedef TRIO_SIGNED int trio_int32_t;
  type TRIO_INT64_T (line 341) | typedef TRIO_INT64_T trio_int64_t;
  type trio_longlong_t (line 343) | typedef trio_longlong_t trio_int64_t;
  type trio_parameter_t (line 748) | typedef struct {
  type trio_custom_t (line 799) | typedef struct {
  type trio_class_t (line 808) | typedef struct _trio_class_t {
  type trio_reference_t (line 847) | typedef struct _trio_reference_t {
  type trio_userdef_t (line 854) | typedef struct _trio_userdef_t {
  type lconv (line 883) | struct lconv
  function TrioIsQualifier (line 941) | TrioIsQualifier
  function TRIO_PRIVATE (line 986) | TRIO_PRIVATE void
  function TrioCalcThousandSeparatorLength (line 1033) | TrioCalcThousandSeparatorLength
  function TrioFollowedBySeparator (line 1071) | TrioFollowedBySeparator
  function TrioGetPosition (line 1106) | TrioGetPosition
  function TrioPower (line 1174) | TrioPower
  function TrioLogarithm (line 1236) | TrioLogarithm
  function TrioLogarithmBase (line 1268) | TrioLogarithmBase
  function TrioParseQualifiers (line 1290) | TrioParseQualifiers
  function TrioParseSpecifier (line 1591) | TrioParseSpecifier
  function TrioParse (line 1839) | TrioParse
  function TrioWriteNumber (line 2360) | TrioWriteNumber
  function TrioWriteStringCharacter (line 2565) | TrioWriteStringCharacter
  function TrioWriteString (line 2621) | TrioWriteString
  function TrioWriteWideStringCharacter (line 2700) | TrioWriteWideStringCharacter
  function TrioWriteWideString (line 2740) | TrioWriteWideString
  function TrioWriteDouble (line 2823) | TrioWriteDouble
  function TrioFormatProcess (line 3472) | TrioFormatProcess
  function TrioFormatRef (line 3785) | TrioFormatRef
  function TrioFormat (line 3812) | TrioFormat
  function TrioOutStreamFile (line 3858) | TrioOutStreamFile
  function TrioOutStreamFileDescriptor (line 3886) | TrioOutStreamFileDescriptor
  function TrioOutStreamCustom (line 3915) | TrioOutStreamCustom
  function TrioOutStreamString (line 3950) | TrioOutStreamString
  function TrioOutStreamStringMax (line 3971) | TrioOutStreamStringMax
  function TrioOutStreamStringDynamic (line 3997) | TrioOutStreamStringDynamic
  function printf (line 4042) | printf
  function vprintf (line 4071) | vprintf
  function trio_printfv (line 4097) | trio_printfv
  function fprintf (line 4124) | fprintf
  function vfprintf (line 4153) | vfprintf
  function trio_fprintfv (line 4176) | trio_fprintfv
  function trio_dprintf (line 4205) | trio_dprintf
  function trio_vdprintf (line 4233) | trio_vdprintf
  function trio_dprintfv (line 4255) | trio_dprintfv
  function trio_cprintf (line 4274) | trio_cprintf
  function trio_vcprintf (line 4299) | trio_vcprintf
  function trio_cprintfv (line 4319) | trio_cprintfv
  function sprintf (line 4351) | sprintf
  function vsprintf (line 4379) | vsprintf
  function trio_sprintfv (line 4404) | trio_sprintfv
  function snprintf (line 4435) | snprintf
  function vsnprintf (line 4467) | vsnprintf
  function trio_snprintfv (line 4496) | trio_snprintfv
  function trio_snprintfcat (line 4523) | trio_snprintfcat
  function trio_vsnprintfcat (line 4552) | trio_vsnprintfcat
  function asprintf (line 4644) | asprintf
  function trio_vasprintf (line 4692) | trio_vasprintf
  function trio_asprintfv (line 4737) | trio_asprintfv
  function trio_register (line 4801) | trio_register
  function trio_locale_set_decimal_point (line 5569) | trio_locale_set_decimal_point
  function trio_locale_set_thousand_separator (line 5601) | trio_locale_set_thousand_separator
  function trio_locale_set_grouping (line 5632) | trio_locale_set_grouping
  function TrioSkipWhitespaces (line 5661) | TrioSkipWhitespaces
  function TRIO_PRIVATE (line 5679) | TRIO_PRIVATE void
  function TrioGetCharacterClass (line 5713) | TrioGetCharacterClass
  function TrioReadNumber (line 5972) | TrioReadNumber
  function TrioReadChar (line 6104) | TrioReadChar
  function TrioReadString (line 6170) | TrioReadString
  function TrioReadWideChar (line 6206) | TrioReadWideChar
  function TrioReadWideString (line 6267) | TrioReadWideString
  function TrioReadGroup (line 6314) | TrioReadGroup
  function TrioReadDouble (line 6354) | TrioReadDouble
  function TrioReadPointer (line 6547) | TrioReadPointer
  function TrioScanProcess (line 6599) | TrioScanProcess
  function TrioScan (line 6927) | TrioScan
  function TrioInStreamFile (line 6973) | TrioInStreamFile
  function TrioInStreamFileDescriptor (line 7008) | TrioInStreamFileDescriptor
  function TrioInStreamCustom (line 7047) | TrioInStreamCustom
  function TrioInStreamString (line 7084) | TrioInStreamString
  function scanf (line 7139) | scanf
  function vscanf (line 7167) | vscanf
  function trio_scanfv (line 7189) | trio_scanfv
  function fscanf (line 7218) | fscanf
  function vfscanf (line 7249) | vfscanf
  function trio_fscanfv (line 7274) | trio_fscanfv
  function trio_dscanf (line 7305) | trio_dscanf
  function trio_vdscanf (line 7335) | trio_vdscanf
  function trio_dscanfv (line 7359) | trio_dscanfv
  function trio_cscanf (line 7380) | trio_cscanf
  function trio_vcscanf (line 7405) | trio_vcscanf
  function trio_cscanfv (line 7425) | trio_cscanfv
  function sscanf (line 7457) | sscanf
  function vsscanf (line 7486) | vsscanf
  function trio_sscanfv (line 7509) | trio_sscanfv

FILE: src/sdk/src/libc/src/trio/triodef.h
  type trio_long_double_t (line 208) | typedef double trio_long_double_t;
  type trio_long_double_t (line 230) | typedef long double trio_long_double_t;

FILE: src/sdk/src/libc/src/trio/trionan.c
  function internal_make_double (line 271) | internal_make_double
  function internal_is_special_quantity (line 292) | internal_is_special_quantity
  function internal_is_negative (line 320) | internal_is_negative
  function ms_fpclassify_and_signbit (line 409) | ms_fpclassify_and_signbit
  function trio_fpclassify_and_signbit (line 710) | trio_fpclassify_and_signbit
  function trio_isnan (line 801) | trio_isnan
  function trio_isinf (line 821) | trio_isinf
  function trio_isfinite (line 848) | trio_isfinite
  function trio_signbit (line 876) | trio_signbit
  function trio_fpclassify (line 897) | trio_fpclassify
  function TRIO_PUBLIC_NAN (line 915) | TRIO_PUBLIC_NAN double
  function TRIO_PUBLIC_NAN (line 942) | TRIO_PUBLIC_NAN double
  function TRIO_PUBLIC_NAN (line 996) | TRIO_PUBLIC_NAN double
  function TRIO_PUBLIC_NAN (line 1021) | TRIO_PUBLIC_NAN double
  function main (line 1121) | int main(TRIO_NOARGS)

FILE: src/sdk/src/libc/src/trio/triostr.c
  type _trio_string_t (line 132) | struct _trio_string_t
  function TRIO_PRIVATE_STRING (line 195) | TRIO_PRIVATE_STRING trio_string_t *
  function internal_string_grow (line 224) | internal_string_grow
  function internal_string_grow_to (line 260) | internal_string_grow_to
  function trio_destroy (line 323) | trio_destroy
  function trio_length (line 344) | trio_length
  function trio_length_max (line 363) | trio_length_max
  function trio_append (line 396) | trio_append
  function trio_append_max (line 427) | trio_append_max
  function trio_contains (line 459) | trio_contains
  function trio_copy (line 488) | trio_copy
  function trio_copy_max (line 519) | trio_copy_max
  function trio_equal (line 600) | trio_equal
  function trio_equal_case (line 642) | trio_equal_case
  function trio_equal_case_max (line 672) | trio_equal_case_max
  function trio_equal_locale (line 702) | trio_equal_locale
  function trio_equal_max (line 732) | trio_equal_max
  function trio_format_date_max (line 818) | trio_format_date_max
  function trio_lower (line 929) | trio_lower
  function trio_match (line 956) | trio_match
  function trio_match_case (line 1010) | trio_match_case
  function trio_span_function (line 1059) | trio_span_function
  function trio_to_long_double (line 1196) | trio_to_long_double
  function trio_to_double (line 1334) | trio_to_double
  function trio_to_float (line 1360) | trio_to_float
  function trio_to_lower (line 1407) | trio_to_lower
  function trio_to_upper (line 1460) | trio_to_upper
  function trio_upper (line 1478) | trio_upper
  function trio_string_destroy (line 1546) | trio_string_destroy
  function trio_xstring_set (line 1660) | trio_xstring_set
  function trio_string_size (line 1679) | trio_string_size
  function trio_string_terminate (line 1696) | trio_string_terminate
  function trio_string_append (line 1715) | trio_string_append
  function trio_xstring_append (line 1745) | trio_xstring_append
  function trio_xstring_append_char (line 1774) | trio_xstring_append_char
  function trio_string_contains (line 1806) | trio_string_contains
  function trio_xstring_contains (line 1825) | trio_xstring_contains
  function trio_string_copy (line 1844) | trio_string_copy
  function trio_xstring_copy (line 1865) | trio_xstring_copy
  function trio_string_equal (line 1951) | trio_string_equal
  function trio_xstring_equal (line 1971) | trio_xstring_equal
  function trio_string_equal_max (line 1990) | trio_string_equal_max
  function trio_xstring_equal_max (line 2009) | trio_xstring_equal_max
  function trio_string_equal_case (line 2029) | trio_string_equal_case
  function trio_xstring_equal_case (line 2048) | trio_xstring_equal_case
  function trio_string_equal_case_max (line 2067) | trio_string_equal_case_max
  function trio_xstring_equal_case_max (line 2087) | trio_xstring_equal_case_max
  function trio_string_format_date_max (line 2107) | trio_string_format_date_max
  function trio_string_length (line 2163) | trio_string_length
  function trio_string_lower (line 2184) | trio_string_lower
  function trio_string_match (line 2201) | trio_string_match
  function trio_xstring_match (line 2220) | trio_xstring_match
  function trio_string_match_case (line 2239) | trio_string_match_case
  function trio_xstring_match_case (line 2258) | trio_xstring_match_case
  function trio_string_upper (line 2315) | trio_string_upper

FILE: src/sdk/src/libc/src/trio/triostr.h
  type trio_string_t (line 437) | typedef struct _trio_string_t trio_string_t;

FILE: src/sdk/src/libc/src/udivmoddi4.c
  type SItype (line 4) | typedef int SItype __attribute__(( mode( SI ) ));
  type USItype (line 5) | typedef unsigned int USItype __attribute__(( mode( SI ) ));
  type DItype (line 6) | typedef int DItype __attribute__(( mode( DI ) ));
  type UDItype (line 7) | typedef unsigned int UDItype __attribute__(( mode( DI ) ));
  type DWstruct (line 16) | struct DWstruct {
  type DWunion (line 21) | typedef union {
  function UDWtype (line 44) | static inline __attribute__(( __always_inline__ ))
  function DWtype (line 161) | DWtype __moddi3( DWtype u, DWtype v ) {
  function UDWtype (line 182) | UDWtype __umoddi3( UDWtype u, UDWtype v ) {
  function DWtype (line 190) | DWtype __divdi3( DWtype u, DWtype v ) {
  function UDWtype (line 212) | UDWtype __udivdi3( UDWtype n, UDWtype d ) {

FILE: src/sdk/src/libc/src/unistd/access.c
  function access (line 5) | int access( const char* pathname, int mode ) {

FILE: src/sdk/src/libc/src/unistd/alarm.c
  function alarm (line 4) | unsigned int alarm( unsigned int seconds ) {

FILE: src/sdk/src/libc/src/unistd/chdir.c
  function chdir (line 9) | int chdir( const char* path ) {

FILE: src/sdk/src/libc/src/unistd/chown.c
  function chown (line 4) | int chown( const char* path, uid_t owner, gid_t group ) {

FILE: src/sdk/src/libc/src/unistd/close.c
  function close (line 9) | int close( int fd ) {

FILE: src/sdk/src/libc/src/unistd/dup.c
  function dup (line 9) | int dup( int old_fd ) {

FILE: src/sdk/src/libc/src/unistd/dup2.c
  function dup2 (line 9) | int dup2( int old_fd, int new_fd ) {

FILE: src/sdk/src/libc/src/unistd/execlp.c
  function execlp (line 6) | int execlp( const char* file, const char* arg, ... ) {

FILE: src/sdk/src/libc/src/unistd/execv.c
  function execv (line 5) | int execv( const char* file, char* const argv[] ) {

FILE: src/sdk/src/libc/src/unistd/execve.c
  function execve (line 9) | int execve( const char* filename, char* const argv[], char* const envp[]...

FILE: src/sdk/src/libc/src/unistd/execvp.c
  function execvp (line 9) | int execvp( const char* filename, char* const argv[] ) {

FILE: src/sdk/src/libc/src/unistd/exit.c
  function atexit (line 13) | int atexit( void ( *function )( void ) ) {
  function exit (line 25) | void exit( int status ) {

FILE: src/sdk/src/libc/src/unistd/fchdir.c
  function fchdir (line 9) | int fchdir( int fd ) {

FILE: src/sdk/src/libc/src/unistd/fork.c
  function pid_t (line 5) | pid_t fork( void ) {

FILE: src/sdk/src/libc/src/unistd/fpathconf.c
  function fpathconf (line 7) | long fpathconf( int fd, int name ) {

FILE: src/sdk/src/libc/src/unistd/ftruncate.c
  function ftruncate (line 4) | int ftruncate( int fd, off_t length ) {

FILE: src/sdk/src/libc/src/unistd/getcwd.c
  type stat (line 24) | struct stat
  type dirent (line 64) | struct dirent

FILE: src/sdk/src/libc/src/unistd/getdents.c
  function getdents (line 9) | int getdents( int fd, struct dirent* entry, unsigned int count ) {

FILE: src/sdk/src/libc/src/unistd/getdtablesize.c
  function getdtablesize (line 3) | int getdtablesize( void ) {

FILE: src/sdk/src/libc/src/unistd/getegid.c
  function gid_t (line 3) | gid_t getegid( void ) {

FILE: src/sdk/src/libc/src/unistd/geteuid.c
  function uid_t (line 3) | uid_t geteuid( void ) {

FILE: src/sdk/src/libc/src/unistd/getgid.c
  function gid_t (line 3) | gid_t getgid( void ) {

FILE: src/sdk/src/libc/src/unistd/gethostname.c
  function gethostname (line 4) | int gethostname( char* name, size_t len ) {

FILE: src/sdk/src/libc/src/unistd/getpgid.c
  function pid_t (line 3) | pid_t getpgid( pid_t pid ) {

FILE: src/sdk/src/libc/src/unistd/getpgrp.c
  function pid_t (line 3) | pid_t getpgrp( void ) {

FILE: src/sdk/src/libc/src/unistd/getpid.c
  function pid_t (line 5) | pid_t getpid( void ) {

FILE: src/sdk/src/libc/src/unistd/getppid.c
  function pid_t (line 3) | pid_t getppid( void ) {

FILE: src/sdk/src/libc/src/unistd/gettid.c
  function pid_t (line 9) | pid_t gettid( void ) {

FILE: src/sdk/src/libc/src/unistd/getuid.c
  function uid_t (line 4) | uid_t getuid( void ) {

FILE: src/sdk/src/libc/src/unistd/isatty.c
  function isatty (line 9) | int isatty( int fd ) {

FILE: src/sdk/src/libc/src/unistd/link.c
  function link (line 4) | int link( const char* oldpath, const char* newpath ) {

FILE: src/sdk/src/libc/src/unistd/lseek.c
  function off_t (line 9) | off_t lseek( int fd, off_t offset, int whence ) {

FILE: src/sdk/src/libc/src/unistd/pipe.c
  function pipe (line 4) | int pipe( int pipefd[2] ) {

FILE: src/sdk/src/libc/src/unistd/pread.c
  function pread (line 9) | ssize_t pread( int fd, void* buf, size_t count, off_t offset ) {

FILE: src/sdk/src/libc/src/unistd/pwrite.c
  function pwrite (line 9) | ssize_t pwrite( int fd, const void* buf, size_t count, off_t offset ) {

FILE: src/sdk/src/libc/src/unistd/read.c
  function read (line 9) | ssize_t read( int fd, void* buf, size_t count ) {

FILE: src/sdk/src/libc/src/unistd/readlink.c
  function readlink (line 10) | ssize_t readlink( const char* path, char* buf, size_t bufsiz ) {

FILE: src/sdk/src/libc/src/unistd/rmdir.c
  function rmdir (line 9) | int rmdir( const char* pathname ) {

FILE: src/sdk/src/libc/src/unistd/setgid.c
  function setgid (line 3) | int setgid( gid_t gid ) {

FILE: src/sdk/src/libc/src/unistd/setpgid.c
  function setpgid (line 3) | int setpgid( pid_t pid, pid_t pgid ) {

FILE: src/sdk/src/libc/src/unistd/setpgrp.c
  function setpgrp (line 3) | int setpgrp( void ) {

FILE: src/sdk/src/libc/src/unistd/setregid.c
  function setregid (line 3) | int setregid( gid_t rgid, gid_t egid ) {

FILE: src/sdk/src/libc/src/unistd/setreuid.c
  function setreuid (line 3) | int setreuid( uid_t ruid, uid_t euid ) {

FILE: src/sdk/src/libc/src/unistd/setuid.c
  function setuid (line 3) | int setuid( uid_t uid ) {

FILE: src/sdk/src/libc/src/unistd/sleep.c
  function sleep (line 5) | unsigned int sleep( unsigned int seconds ) {

FILE: src/sdk/src/libc/src/unistd/symlink.c
  function symlink (line 6) | int symlink( const char* oldpath, const char* newpath ) {

FILE: src/sdk/src/libc/src/unistd/ttyname.c
  function ttyname_r (line 8) | int ttyname_r( int fd, char* buf, size_t buflen ) {

FILE: src/sdk/src/libc/src/unistd/unlink.c
  function unlink (line 9) | int unlink( const char* pathname ) {

FILE: src/sdk/src/libc/src/unistd/write.c
  function write (line 6) | ssize_t write( int fd, const void* buf, size_t count ) {

FILE: src/userland/helloworld/main.c
  function main (line 9) | int main(int argc,char **argv){
Condensed preview — 430 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (829K chars).
[
  {
    "path": ".gitignore",
    "chars": 300,
    "preview": "# Compiled Object files\n*.slo\n*.lo\n*.o\n\n# Compiled Dynamic libraries\n*.so\n*.dylib\n\n# Compiled Static libraries\n*.lai\n*.l"
  },
  {
    "path": "Chapter-1/README.md",
    "chars": 1479,
    "preview": "## Chapter 1: Introduction to the x86 architecture and about our OS\n\n### What is the x86 architecture?\n\n> The term x86 d"
  },
  {
    "path": "Chapter-2/README.md",
    "chars": 2233,
    "preview": "## Chapter 2: Setup the development environment\n\nThe first step is to setup a good and viable development environment. U"
  },
  {
    "path": "Chapter-3/README.md",
    "chars": 6366,
    "preview": "## Chapter 3: First boot with GRUB\n\n#### How the boot works?\n\nWhen an x86-based computer is turned on, it begins a compl"
  },
  {
    "path": "Chapter-4/README.md",
    "chars": 2919,
    "preview": "## Chapter 4: Backbone of the OS and C++ runtime\n\n#### C++ kernel run-time\n\nA kernel can be written in C++ just as it ca"
  },
  {
    "path": "Chapter-5/README.md",
    "chars": 4599,
    "preview": "## Chapter 5: Base classes for managing x86 architecture\n\nNow that we know how to compile our C++ kernel and boot the bi"
  },
  {
    "path": "Chapter-6/README.md",
    "chars": 4158,
    "preview": "## Chapter 6: GDT\n\nThanks to GRUB, your kernel is no longer in real-mode, but already in [protected mode](http://en.wiki"
  },
  {
    "path": "Chapter-7/README.md",
    "chars": 8154,
    "preview": "## Chapter 7: IDT and interrupts\n\nAn interrupt is a signal to the processor emitted by hardware or software indicating a"
  },
  {
    "path": "Chapter-8/README.md",
    "chars": 3234,
    "preview": "## Chapter 8: Theory: physical and virtual memory\n\nIn the chapter related to the GDT, we saw that using segmentation a p"
  },
  {
    "path": "LICENSE",
    "chars": 11307,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "README.md",
    "chars": 1594,
    "preview": "How to Make a Computer Operating System\n=======================================\n\nOnline book about how to write a comput"
  },
  {
    "path": "SUMMARY.md",
    "chars": 851,
    "preview": "# Summary\n\n* [Introduction](README.md)\n* [Introduction about the x86 architecture and about our OS](Chapter-1/README.md)"
  },
  {
    "path": "chapter9/README.md",
    "chars": 1305,
    "preview": "# Memory management: physical and virtual\n\nThe kernel knows the size of the physical memory available thanks to [GRUB](."
  },
  {
    "path": "src/Makefile",
    "chars": 490,
    "preview": "SDKDIR=./sdk\n\nhelp:\n\t@echo \"Makefile for Building Dev Operating System.\"\n\t@echo \"Usage: make [ all | clean | help | buil"
  },
  {
    "path": "src/Vagrantfile",
    "chars": 4779,
    "preview": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\n# Vagrantfile API/syntax version. Don't touch unless you know what you're doin"
  },
  {
    "path": "src/kernel/Makefile",
    "chars": 1138,
    "preview": "ARCH=x86\nKERNEL=kernel.elf\nSDKDIR=../sdk\nINCDIR= -I ./ -I ./modules -I ./core -I ./arch/$(ARCH)\n\n\ninclude ./arch/$(ARCH)"
  },
  {
    "path": "src/kernel/arch/x86/Makefile",
    "chars": 189,
    "preview": "OBJS:= arch/$(ARCH)/start.o  $(OBJS) arch/$(ARCH)/alloc.o arch/$(ARCH)/architecture.o \\\n\tarch/$(ARCH)/io.o arch/$(ARCH)/"
  },
  {
    "path": "src/kernel/arch/x86/alloc.cc",
    "chars": 3178,
    "preview": "#include <os.h>\n\nextern \"C\" {\n\t\t\n\t/* change memory segment size */\n\tvoid *ksbrk(int n)\n\t{\n\t\tstruct kmalloc_header *chunk"
  },
  {
    "path": "src/kernel/arch/x86/architecture.cc",
    "chars": 6608,
    "preview": "#include <os.h>\n#include <x86.h>\n\n/* Stack pointer */\nextern u32 *\t\tstack_ptr;\n\n/* Current cpu name */\nstatic char cpu_n"
  },
  {
    "path": "src/kernel/arch/x86/architecture.h",
    "chars": 1578,
    "preview": "#ifndef ARCH_H\n#define ARCH_H\n\n#include <runtime/types.h>\n\n#include <process.h>\n\n\n/** Processor architecture class **/\nc"
  },
  {
    "path": "src/kernel/arch/x86/archprocess.h",
    "chars": 721,
    "preview": "#ifndef APROC_H\n#define APROC_H\n\n#include <runtime/types.h>\n\nextern \"C\" {\n\n#define KERNELMODE\t0\n#define USERMODE\t1\n\n\t/**"
  },
  {
    "path": "src/kernel/arch/x86/config.make",
    "chars": 261,
    "preview": "LDFLAG= -melf_i386 -static  -L ./  -T ./arch/$(ARCH)/linker.ld\nSC=g++\nFLAG= $(INCDIR) -g -O2 -w -trigraphs -fno-builtin "
  },
  {
    "path": "src/kernel/arch/x86/io.cc",
    "chars": 5104,
    "preview": "#include <os.h>\n\nIo* Io::last_io=&io;\t\t/* definis la derniere io avant switch */\nIo* Io::current_io=&io;\t\t/* interface a"
  },
  {
    "path": "src/kernel/arch/x86/io.h",
    "chars": 2249,
    "preview": "\n#ifndef IO_H\n#define IO_H\n\n#include <runtime/types.h>\n\n\n\n#define RAMSCREEN 0xB8000\t/* debut de la memoire video */\n#def"
  },
  {
    "path": "src/kernel/arch/x86/linker.ld",
    "chars": 518,
    "preview": "OUTPUT_FORMAT(elf32-i386)\r\nOUTPUT_ARCH(i386)\r\nENTRY (_start)\r\n\r\nSECTIONS{\r\n    . = 0x00100000;\r\n\r\n    .text :{\r\n        "
  },
  {
    "path": "src/kernel/arch/x86/start.asm",
    "chars": 859,
    "preview": "global _start, _kmain\r\nextern kmain, start_ctors, end_ctors, start_dtors, end_dtors\r\n\r\n    \r\n%define MULTIBOOT_HEADER_MA"
  },
  {
    "path": "src/kernel/arch/x86/switch.asm",
    "chars": 681,
    "preview": "\nglobal do_switch\n\ndo_switch:\n\t; recuper l'adresse de *current \n\tmov esi, [esp]\n\tpop eax\t\t\t; depile @current\n\n\t; prepare"
  },
  {
    "path": "src/kernel/arch/x86/vmm.cc",
    "chars": 11437,
    "preview": "#include <os.h>\n\nextern \"C\" {\n\tchar *kern_heap;\n\tlist_head kern_free_vm;\n\tu32 *pd0 = (u32 *) KERN_PDIR;\t\t\t/* kernel page"
  },
  {
    "path": "src/kernel/arch/x86/vmm.h",
    "chars": 2362,
    "preview": "#ifndef VMM_H\n#define VMM_H\n\n#include <runtime/types.h>\n#include <runtime/list.h>\n#include <runtime/alloc.h>\n#include <x"
  },
  {
    "path": "src/kernel/arch/x86/x86.cc",
    "chars": 14646,
    "preview": "#include <os.h>\n#include <x86.h>\n#include <keyboard.h>\n\n\nextern \"C\" {\n\nregs_t cpu_cpuid(int code)\n{\n\tregs_t r;\n\tasm vola"
  },
  {
    "path": "src/kernel/arch/x86/x86.h",
    "chars": 2961,
    "preview": "#ifndef __X86__\n#define __X86__\n\n#include <runtime/types.h>\n\n#define IDTSIZE\t\t0xFF\t/* nombre max. de descripteurs dans l"
  },
  {
    "path": "src/kernel/arch/x86/x86int.asm",
    "chars": 933,
    "preview": "extern isr_default_int, do_syscalls, isr_schedule_int\n\n\n%macro\tSAVE_REGS 0\n\tpushad \n\tpush ds\n\tpush es\n\tpush fs\n\tpush gs "
  },
  {
    "path": "src/kernel/config.h",
    "chars": 523,
    "preview": "#ifndef CONFIG_H\n#define CONFIG_H\n\n#define KERNEL_NAME\t\t\"devos\"\t\t/* kernel name */\n#define KERNEL_VERSION\t\"1\"\t\t/* kernel"
  },
  {
    "path": "src/kernel/core/Makefile",
    "chars": 232,
    "preview": "OBJS:=  $(OBJS) core/class.o core/elf_loader.o core/file.o \\\n\tcore/filesystem.o core/kernel.o core/api_posix.o\\\n\tcore/pr"
  },
  {
    "path": "src/kernel/core/api/dev/clock.h",
    "chars": 249,
    "preview": "#ifndef __API_CLOCK__\r\n#define __API_CLOCK__\r\n\r\ntypedef unsigned int clock_d;\r\n\r\nstruct clock_info{\r\n\tclock_d\t\th;\r\n\tcloc"
  },
  {
    "path": "src/kernel/core/api/dev/fb.h",
    "chars": 456,
    "preview": "#ifndef __API_FB__\r\n#define __API_FB__\r\n\r\nstruct fb_info{\r\n\tunsigned int\t\tw;\t//largeur\r\n\tunsigned int\t\th;\t//hauteur\r\n\tch"
  },
  {
    "path": "src/kernel/core/api/dev/ioctl.h",
    "chars": 741,
    "preview": "#ifndef __API_IOCTL__\r\n#define __API_IOCTL__\r\n\r\n\r\n#define DEV_GET_TYPE\t\t0x01\t/* Renvoie le type de peripherique */\r\n#def"
  },
  {
    "path": "src/kernel/core/api/dev/ipc.h",
    "chars": 146,
    "preview": "#ifndef __API_IPC__\n#define __API_IPC__\n\n#define STDIPC_FILENO\t3\n#define SIGIPC\t\tSIGUSR1\n\n\n//iotcl\n#define API_TTY_SWITC"
  },
  {
    "path": "src/kernel/core/api/dev/keyboard.h",
    "chars": 484,
    "preview": "#ifndef __API_KEYBOARD__\r\n#define __API_KEYBOARD__\r\n\r\n\r\n//keyboard\r\nenum {\r\n    KEY_TAB = 7,\r\n    KEY_BACKSPACE = 8,\r\n  "
  },
  {
    "path": "src/kernel/core/api/dev/proc.h",
    "chars": 359,
    "preview": "#ifndef __API_PROC__\r\n#define __API_PROC__\r\n\r\nstruct proc_info{\r\n\tchar\t\t\t\tname[32];\r\n\tunsigned int\t\tpid;\r\n\tunsigned int\t"
  },
  {
    "path": "src/kernel/core/api/dev/tty.h",
    "chars": 1108,
    "preview": "#ifndef __API_TTY__\r\n#define __API_TTY__\r\n\r\n#include <api/dev/keyboard.h>\r\n\r\n#define TTY_NAME_LEN\t16\r\n\r\n//tty info\r\nstru"
  },
  {
    "path": "src/kernel/core/api/kernel/syscall.h",
    "chars": 480,
    "preview": "\n#ifndef _OS_SYSCALL_H_\n#define _OS_SYSCALL_H_\n\n\nint syscall0( int number );\nint syscall1( int number, unsigned int p1 )"
  },
  {
    "path": "src/kernel/core/api/kernel/syscall_table.h",
    "chars": 1712,
    "preview": "\n#ifndef _OS_SYSCALL_TABLE_H_\n#define _OS_SYSCALL_TABLE_H_\n\n\n#define NOT_DEFINED 0\n\nenum {\n\tSYS_rewinddir\t\t\t=NOT_DEFINED"
  },
  {
    "path": "src/kernel/core/api.h",
    "chars": 327,
    "preview": "#ifndef API_H\n#define API_H\n\n//posix\nvoid call_open();\nvoid call_close();\nvoid call_read();\nvoid call_write();\nvoid call"
  },
  {
    "path": "src/kernel/core/api_posix.cc",
    "chars": 4899,
    "preview": "#include <os.h>\n\n\n/*\n *\tu32 open(char* name,u32 flag);\n */\nvoid call_open(){\n\tchar*name=(char*)arch.getArg(0);\n\tu32 flag"
  },
  {
    "path": "src/kernel/core/boot.h",
    "chars": 2964,
    "preview": "#ifndef __MY_BOOT__\r\n#define __MY_BOOT__\r\n\r\n#include <runtime/types.h>\r\n\r\nstruct multiboot_info {\r\n\tu32 flags;\r\n\tu32 low"
  },
  {
    "path": "src/kernel/core/class.cc",
    "chars": 351,
    "preview": "#include <os.h>\n\n/*\nStatic objects\n*/\n\nIo \t\t\t\tio;\t\t\t/* Input/Output interface */\nArchitecture \tarch;\t\t/*\tCpu and archite"
  },
  {
    "path": "src/kernel/core/device.cc",
    "chars": 471,
    "preview": "#include <os.h>\n\n\n\nDevice::~Device(){\n\t\n}\n\nDevice::Device(char* n) : File(n,TYPE_DEVICE)\n{\n\tfsm.addFile(\"/dev\",this);\n}\n"
  },
  {
    "path": "src/kernel/core/device.h",
    "chars": 417,
    "preview": "#ifndef DEVICE_H\n#define DEVICE_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nclass Device : public File\n{\n\tpubl"
  },
  {
    "path": "src/kernel/core/elf_loader.cc",
    "chars": 3129,
    "preview": "#include <os.h>\n\n/*\nChargeur de module externe au format elf32 :\npour le moment compil en static sans librairies partags"
  },
  {
    "path": "src/kernel/core/elf_loader.h",
    "chars": 4350,
    "preview": "#ifndef ELF_H\n#define ELF_H\n\n#include <runtime/types.h>\n#include <process.h>\n\n/*\n * ELF HEADER\n */\ntypedef struct {\n\tuns"
  },
  {
    "path": "src/kernel/core/env.cc",
    "chars": 1427,
    "preview": "#include <os.h>\n\n/*\n *\tDefinis la structure d'une variable d'environnement\n *\tchaque variable est un fichier stoqu dans "
  },
  {
    "path": "src/kernel/core/env.h",
    "chars": 407,
    "preview": "#ifndef ENV_H\n#define ENV_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nclass Variable : public File\n{\n\tpublic:\n"
  },
  {
    "path": "src/kernel/core/file.cc",
    "chars": 3960,
    "preview": "\n#include <os.h>\n\n/* dans myos quasiment tous herite de cette classe */\n\n\n/*\n *\tRemplace dans s tous les a par to\n */\nst"
  },
  {
    "path": "src/kernel/core/file.h",
    "chars": 1555,
    "preview": "\n#ifndef FILE_H\n#define FILE_H\n\n#include <runtime/types.h>\n\nenum{\n\tTYPE_FILE,\n\tTYPE_DIRECTORY,\n\tTYPE_DEVICE,\n\tTYPE_PROCE"
  },
  {
    "path": "src/kernel/core/filesystem.cc",
    "chars": 4219,
    "preview": "\n#include <os.h>\n\n/*\nCette classe organise les fichiers entre eux\n*/\n\nFilesystem::Filesystem(){\n\n}\n\nvoid Filesystem::ini"
  },
  {
    "path": "src/kernel/core/filesystem.h",
    "chars": 527,
    "preview": "\n#ifndef FILESYSTEM_H\n#define FILESYSTEM_H\n\n#include <runtime/types.h>\n#include <core/file.h>\n\n\nclass Filesystem\n{\n\tpubl"
  },
  {
    "path": "src/kernel/core/kernel.cc",
    "chars": 1757,
    "preview": "\n#include <os.h>\n#include <boot.h>\n\n\nstatic char* init_argv[2]={\"init\",\"-i\"};\n\n/* charge les modules de depart */\nstatic"
  },
  {
    "path": "src/kernel/core/kernel.h",
    "chars": 488,
    "preview": "\n#ifndef KERNEL_H\n#define KERNEL_H\n\n#include <runtime/alloc.h>\n#include <runtime/libc.h>\n#include <runtime/string.h>\n\n\n#"
  },
  {
    "path": "src/kernel/core/keyboard.h",
    "chars": 3485,
    "preview": "\n\n#ifndef __KBD__\n#define __KBD__\n\n#include <api/dev/tty.h>\n\nchar kbdmap_default[] = {\n\tKEY_ESCAPE, KEY_ESCAPE, KEY_ESCA"
  },
  {
    "path": "src/kernel/core/modulelink.cc",
    "chars": 483,
    "preview": "\n#include <os.h>\n\n\n\nModLink::~ModLink(){\n\t\n}\n\nModLink::ModLink(char* n) : File(n,TYPE_FILE)\n{\n\tfsm.addFile(\"/sys/mods/\","
  },
  {
    "path": "src/kernel/core/modulelink.h",
    "chars": 374,
    "preview": "\n#ifndef MODLINK_H\n#define MODLINK_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nclass ModLink : public File\n{\n\t"
  },
  {
    "path": "src/kernel/core/os.h",
    "chars": 882,
    "preview": "#ifndef OS_H\n#define OS_H\n\n#include <config.h>\n#include <kernel.h>\n\n\ntypedef File* (*device_driver)\t(char* name,u32 flag"
  },
  {
    "path": "src/kernel/core/process.cc",
    "chars": 4340,
    "preview": "\n#include <os.h>\n#include <api/dev/proc.h>\n\n/* Definis un process (/dev/proc) */\n\nchar* Process::default_tty=\"/dev/tty\";"
  },
  {
    "path": "src/kernel/core/process.h",
    "chars": 1601,
    "preview": "\n#ifndef PROC_H\n#define PROC_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n#include <archprocess.h>\t/* definition "
  },
  {
    "path": "src/kernel/core/signal.h",
    "chars": 2491,
    "preview": "\n#ifndef SIGNAL_H\n#define SIGNAL_H\n\n\n#include <runtime/types.h>\n#include <process.h>\n\n\t#define SIGHUP    1       /* Hang"
  },
  {
    "path": "src/kernel/core/socket.cc",
    "chars": 475,
    "preview": "\n#include <os.h>\n\n\n\nSocket::~Socket(){\n\t\n}\n\nSocket::Socket(char* n) : File(n,TYPE_FILE)\n{\n\tfsm.addFile(\"/sys/sockets/\",t"
  },
  {
    "path": "src/kernel/core/socket.h",
    "chars": 369,
    "preview": "\n#ifndef SOCKET_H\n#define SOCKET_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nclass Socket : public File\n{\n\tpub"
  },
  {
    "path": "src/kernel/core/syscalls.cc",
    "chars": 809,
    "preview": "\n#include <os.h>\n#include <api.h>\n\n#include <api/kernel/syscall_table.h>\n\n#define sysc(a,h) add(a,(syscall_handler)h)\n\nv"
  },
  {
    "path": "src/kernel/core/syscalls.h",
    "chars": 350,
    "preview": "\n#ifndef SYSCALL_H\n#define SYSCALL_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\n#define NB_SYSCALLS\t100\n\n\ntyped"
  },
  {
    "path": "src/kernel/core/system.cc",
    "chars": 2323,
    "preview": "\n#include <os.h>\n\n/**\n *\t10/04/06 (Samy Pess) : creation du fichier\n *\t\t\t\t\t\t\tajout gestion login et variable d'environne"
  },
  {
    "path": "src/kernel/core/system.h",
    "chars": 492,
    "preview": "\n#ifndef SYSTEM_H\n#define SYSTEM_H\n\n#include <runtime/types.h>\n#include <core/env.h>\n#include <core/user.h>\n\n\nclass Syst"
  },
  {
    "path": "src/kernel/core/user.cc",
    "chars": 892,
    "preview": "\n#include <os.h>\n\n\n\nUser::~User(){\n\t\n}\n\nUser::User(char* n) : File(n,TYPE_FILE)\n{\n\tfsm.addFile(\"/sys/usr/\",this);\n\tunext"
  },
  {
    "path": "src/kernel/core/user.h",
    "chars": 621,
    "preview": "\n#ifndef USER_H\n#define USER_H\n\n#include <core/file.h>\n#include <runtime/list.h>\n\n\nenum {\n\tUSER_ROOT,\t//root\n\tUSER_NORM\t"
  },
  {
    "path": "src/kernel/modules/Makefile",
    "chars": 207,
    "preview": "OBJS:=  $(OBJS) modules/module.o \\\n\t\tmodules/null.o modules/stdtty.o modules/x86serial.o\\\n\t\tmodules/ide.o modules/bochsv"
  },
  {
    "path": "src/kernel/modules/bochsvbe.cc",
    "chars": 2793,
    "preview": "\n#include <os.h>\n#include <bochsvbe.h>\n\n/* Driver video pour bios VBE/Bios */\n\n\nstatic void BgaWriteRegister(unsigned sh"
  },
  {
    "path": "src/kernel/modules/bochsvbe.h",
    "chars": 1247,
    "preview": "\r\n#ifndef __BOCHS_VBE__\r\n#define __BOCHS_VBE__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r"
  },
  {
    "path": "src/kernel/modules/clock_x86.cc",
    "chars": 2361,
    "preview": "\n#include <os.h>\n#include <clock_x86.h>\n\n#include <api/dev/ioctl.h>\n\n\nstatic void GetWeekday(unsigned int *Weekday)\n{\n\tu"
  },
  {
    "path": "src/kernel/modules/clock_x86.h",
    "chars": 508,
    "preview": "\r\n#ifndef __CLOCK__\r\n#define __CLOCK__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\n#incl"
  },
  {
    "path": "src/kernel/modules/dospartition.cc",
    "chars": 1565,
    "preview": "#include <os.h>\n#include <dospartition.h>\n\n/*\n *\tFlag indique le numero de partition\n */\nFile* dospartition_mount(char* "
  },
  {
    "path": "src/kernel/modules/dospartition.h",
    "chars": 1123,
    "preview": "\r\n#ifndef __DOS_PARTITION__\r\n#define __DOS_PARTITION__\r\n\r\n#include <runtime/types.h>\r\n#include <core/file.h>\r\n#include <"
  },
  {
    "path": "src/kernel/modules/ext2.cc",
    "chars": 7296,
    "preview": "\n \n#include <os.h>\n#include <ext2.h>\n\n\nFile* ext2_mount(char* name,u32 flag,File* dev){\n\tint ret=ext2_check_disk(dev);\n\t"
  },
  {
    "path": "src/kernel/modules/ext2.h",
    "chars": 5717,
    "preview": "\r\n#ifndef __EXT2__\r\n#define __EXT2__\r\n\r\n#include <runtime/types.h>\r\n#include <core/file.h>\r\n#include <io.h>\r\n\r\n/*\r\n *\tEx"
  },
  {
    "path": "src/kernel/modules/ide.cc",
    "chars": 3157,
    "preview": "\n#include <os.h>\n#include <ide.h>\n\n#include <api/dev/ioctl.h>\n\n\n/*\n *\tCette fonction attend que le disque soit pret avan"
  },
  {
    "path": "src/kernel/modules/ide.h",
    "chars": 454,
    "preview": "\r\n#ifndef __IDE__\r\n#define __IDE__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\nclass Ide"
  },
  {
    "path": "src/kernel/modules/keys.cc",
    "chars": 1093,
    "preview": "\n#include <os.h>\n#include <keys.h>\n\n#include <api/dev/ioctl.h>\n\nextern char* kbdmap;\n\nFile* keys_mknod(char* name,u32 fl"
  },
  {
    "path": "src/kernel/modules/keys.h",
    "chars": 502,
    "preview": "\r\n#ifndef __KEYS__\r\n#define __KEYS__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\n#includ"
  },
  {
    "path": "src/kernel/modules/module.cc",
    "chars": 1618,
    "preview": "\n#include <os.h>\n#include <core/file.h>\n#include <runtime/alloc.h>\n#include <runtime/libc.h>\n#include <core/filesystem.h"
  },
  {
    "path": "src/kernel/modules/module.h",
    "chars": 452,
    "preview": "\r\n#ifndef __MODULE__\r\n#define __MODULE__\r\n\r\n#include <runtime/types.h>\r\n#include <core/file.h>\r\n#include <io.h>\r\n\r\n\r\n#de"
  },
  {
    "path": "src/kernel/modules/modules.conf",
    "chars": 1191,
    "preview": "\r\nimport_module(Console);\r\nimport_module(Null);\r\nimport_module(Ide);\r\nimport_module(Bochs);\r\nimport_module(Ext2);\r\nimpor"
  },
  {
    "path": "src/kernel/modules/null.cc",
    "chars": 876,
    "preview": "\n#include <os.h>\n#include <null.h>\n\n#include <api/dev/ioctl.h>\n\nFile* null_mknod(char* name,u32 flag,File* dev){\n\tNull* "
  },
  {
    "path": "src/kernel/modules/null.h",
    "chars": 402,
    "preview": "\r\n#ifndef __NULL__\r\n#define __NULL__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r\n\r\nclass N"
  },
  {
    "path": "src/kernel/modules/stdtty.cc",
    "chars": 1737,
    "preview": "\n#include <os.h>\n#include <stdtty.h>\n\n\n\n\nFile* console_mknod(char* name,u32 flag,File* dev){\n\tConsole* cons=new Console("
  },
  {
    "path": "src/kernel/modules/stdtty.h",
    "chars": 591,
    "preview": "\r\n#ifndef __CONSOLE__\r\n#define __CONSOLE__\r\n\r\n#include <runtime/types.h>\r\n#include <core/file.h>\r\n#include <io.h>\r\n\r\n#in"
  },
  {
    "path": "src/kernel/modules/x86serial.cc",
    "chars": 1567,
    "preview": "\n#include <os.h>\n#include <x86serial.h>\n\n#include <api/dev/ioctl.h>\n#include <api/dev/tty.h>\n\n\nu8 X86Serial::init_serial"
  },
  {
    "path": "src/kernel/modules/x86serial.h",
    "chars": 695,
    "preview": "\r\n#ifndef __X86Serial__\r\n#define __X86Serial__\r\n\r\n#include <runtime/types.h>\r\n#include <core/device.h>\r\n#include <io.h>\r"
  },
  {
    "path": "src/kernel/runtime/Makefile",
    "chars": 101,
    "preview": "OBJS:=  $(OBJS) runtime/cxx.o runtime/itoa.o runtime/buffer.o \\\n\truntime/memory.o runtime/string.o\n\t\n"
  },
  {
    "path": "src/kernel/runtime/alloc.h",
    "chars": 129,
    "preview": "\n#ifndef ALLOC_H\n#define ALLOC_H\n\n\nextern \"C\" {\n\tvoid *ksbrk(int);\n\tvoid *kmalloc(unsigned long);\n\tvoid kfree(void *);\n}"
  },
  {
    "path": "src/kernel/runtime/buffer.cc",
    "chars": 821,
    "preview": "\n#include <os.h>\n#include <runtime/buffer.h>\n\n\n\nBuffer::Buffer(char* n,u32 siz){\n\tmap=(char*)kmalloc(siz);\n\tsize=siz;\n\tm"
  },
  {
    "path": "src/kernel/runtime/buffer.h",
    "chars": 282,
    "preview": "\n#ifndef BUFFER_H\n#define BUFFER_H\n\n\nclass Buffer\n{\n\tpublic:\n\t\tBuffer(char* n,u32 siz);\n\t\tBuffer();\n\t\t~Buffer();\n\t\t\n\t\tvo"
  },
  {
    "path": "src/kernel/runtime/cxx.cc",
    "chars": 1663,
    "preview": "#include <os.h>\n\nextern \"C\"\n{\n\t\n\tint __cxa_atexit(void (*Destructor) (void *), void *Parameter, void *HomeDSO);\n\tvoid __"
  },
  {
    "path": "src/kernel/runtime/itoa.cc",
    "chars": 422,
    "preview": "\n#include <os.h>\n\n\n\n/*\n * Convertit un nombre en chaine de caractre\n */\nextern \"C\" {\n\tvoid itoa(char *buf, unsigned long"
  },
  {
    "path": "src/kernel/runtime/libc.h",
    "chars": 505,
    "preview": "\n#ifndef LIBC_H\n#define LIBC_H\n\n#include <stdarg.h>\n\nextern \"C\" {\n\tvoid \titoa(char *buf, unsigned long int n, int base);"
  },
  {
    "path": "src/kernel/runtime/list.h",
    "chars": 1368,
    "preview": "\n \n#ifndef __LIST__\n#define __LIST__\n\n\n\tstruct list_head {\n\t\tstruct list_head *next, *prev;\n\t};\n\n\t#define LIST_HEAD_INIT"
  },
  {
    "path": "src/kernel/runtime/memory.cc",
    "chars": 406,
    "preview": "#include <os.h>\n\n\nextern \"C\" {\n\n/* \n * La fonction memcpy permet de copier n octets de src vers dest.\n * Les adresses so"
  },
  {
    "path": "src/kernel/runtime/string.cc",
    "chars": 1223,
    "preview": "\n#include <os.h>\n\n\n\nextern \"C\"\n{\n\tint strlen(char *s)\n\t{\n\t\tint i = 0;\n\t\twhile (*s++)\n\t\t\ti++;\n\t\treturn i;\n\t}\n\t\n\tchar *str"
  },
  {
    "path": "src/kernel/runtime/string.h",
    "chars": 44,
    "preview": "\n#ifndef STRING_H\n#define STRING_H\n\n\n#endif\n"
  },
  {
    "path": "src/kernel/runtime/types.h",
    "chars": 1187,
    "preview": "\n#ifndef TYPES_H\n#define TYPES_H\n\n/*\n *\tGeneral C-Types\n */\ntypedef unsigned char \tu8;\ntypedef unsigned short \tu16;\ntype"
  },
  {
    "path": "src/sdk/Makefile",
    "chars": 85,
    "preview": "\nall: \n\t@echo \"Building LibC\"\n\tmake -C ./src/libc\n\t\nclean:\n\tmake -C ./src/libc clean\n"
  },
  {
    "path": "src/sdk/bootdisk/bin/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/sdk/bootdisk/boot/grub/grub.conf",
    "chars": 175,
    "preview": "default=0\ntimeout=30\n\nroot (hd0,0)\n\ntitle=Dev Operating System (with init)\n\tkernel /kernel.elf\n\tmodule /bin/hello\n\tboot\n"
  },
  {
    "path": "src/sdk/bootdisk/boot/grub/menu.lst",
    "chars": 172,
    "preview": "default=0\ntimeout=30\n\nroot (cd)\n\ntitle=Dev Operating System (with init)\n\tkernel /kernel.elf\n\tmodule /bin/hello\n\tboot\n\t\nt"
  },
  {
    "path": "src/sdk/build.mak",
    "chars": 1012,
    "preview": "CP       = cp\nRM       = rm\nMKDIR    = mkdir\nTRUE     = true\n\nCC       = gcc\nCXX      = g++\nAS       = nasm\nLD       = l"
  },
  {
    "path": "src/sdk/diskimage.sh",
    "chars": 368,
    "preview": "#!/bin/bash\nqemu-img create c.img 2M\nfdisk ./c.img  << EOF\nx\nc\n4\nh\n16\ns\n63\nr\nn\np\n1\n1\n4\na\n1\nw\nEOF\nfdisk -l -u ./c.img\nlos"
  },
  {
    "path": "src/sdk/include/_ansi.h",
    "chars": 616,
    "preview": "\n\n#ifndef\t_ANSIDECL_H_\n#define\t_ANSIDECL_H_\n\n\n\n/*  ISO C++.  */\n\n#ifdef __cplusplus\n#if !(defined(_BEGIN_STD_C) && defin"
  },
  {
    "path": "src/sdk/include/alloca.h",
    "chars": 126,
    "preview": "\n \n\n#ifndef _ALLOCA_H_\n#define _ALLOCA_H_\n\n#undef alloca\n#define alloca(size) __builtin_alloca(size)\n\n#endif /* _ALLOCA_"
  },
  {
    "path": "src/sdk/include/arpa/inet.h",
    "chars": 437,
    "preview": "\n\n#ifndef _ARPA_INET_H_\n#define _ARPA_INET_H_\n\n#include <netinet/in.h> /* struct in_addr */\n\nint inet_aton( const char* "
  },
  {
    "path": "src/sdk/include/assert.h",
    "chars": 451,
    "preview": "\n \n\n#undef assert\n\n#ifdef NDEBUG\n#define assert(expr) ((void)0)\n#else\n#define assert(expr) \\\n    if ( !(expr) ) { __asse"
  },
  {
    "path": "src/sdk/include/ctype.h",
    "chars": 597,
    "preview": "\n\n#ifndef _CTYPE_H_\n#define _CTYPE_H_\n\nint isupper( int c );\nint islower( int c );\nint isalpha( int c );\nint isdigit( in"
  },
  {
    "path": "src/sdk/include/dirent.h",
    "chars": 355,
    "preview": "\n \n\n#ifndef _DIRENT_H_\n#define _DIRENT_H_\n\n#include <unistd.h>\n\n\ntypedef struct DIR {\n    int fd;\n    struct dirent entr"
  },
  {
    "path": "src/sdk/include/endian.h",
    "chars": 167,
    "preview": "\n \n\n#ifndef _ENDIAN_H_\n#define _ENDIAN_H_\n\n#define __LITTLE_ENDIAN 1234\n#define __BIG_ENDIAN    4321\n\n#define __BYTE_ORD"
  },
  {
    "path": "src/sdk/include/errno.h",
    "chars": 867,
    "preview": "\n \n\n#ifndef _ERRNO_H_\n#define _ERRNO_H_\n\n#define ENOMEM       1\n#define EINVAL       2\n#define EIO          3\n#define ET"
  },
  {
    "path": "src/sdk/include/fcntl.h",
    "chars": 581,
    "preview": "\n \n\n#ifndef _FCNTL_H_\n#define _FCNTL_H_\n\n#include <sys/cdefs.h>\n#include <sys/types.h>\n\n#define O_RDONLY   0x01\n#define "
  },
  {
    "path": "src/sdk/include/float.h",
    "chars": 6802,
    "preview": "\n\n/*\n * ISO C Standard:  5.2.4.2.2  Characteristics of floating types <float.h>\n */\n\n#ifndef _FLOAT_H___\n#define _FLOAT_"
  },
  {
    "path": "src/sdk/include/getopt.h",
    "chars": 664,
    "preview": "\n \n#ifndef _GETOPT_H_\n#define _GETOPT_H_\n\ntypedef struct option {\n    const char *name;\n    int has_arg;\n    int* flag;\n"
  },
  {
    "path": "src/sdk/include/inttypes.h",
    "chars": 226,
    "preview": "\n \n\n#ifndef _INTTYPES_H_\n#define _INTTYPES_H_\n\n#include <stdint.h>\n\nintmax_t strtoimax( const char *nptr, char** endptr,"
  },
  {
    "path": "src/sdk/include/limits.h",
    "chars": 1029,
    "preview": "\n \n\n#ifndef _LIMITS_H_\n#define _LIMITS_H_\n\n#ifndef __INT_MAX__\n#define __INT_MAX__ 2147483647\n#endif\n#ifndef __LONG_MAX_"
  },
  {
    "path": "src/sdk/include/linker.ld",
    "chars": 518,
    "preview": "OUTPUT_FORMAT(elf32-i386)\r\nOUTPUT_ARCH(i386)\r\nENTRY (_start)\r\n\r\nSECTIONS{\r\n    . = 0x40000000;\r\n\r\n    .text :{\r\n        "
  },
  {
    "path": "src/sdk/include/locale.h",
    "chars": 1061,
    "preview": "\n \n\n#ifndef _LOCALE_H_\n#define _LOCALE_H_\n\nenum {\n    LC_CTYPE = 0,\n    LC_NUMERIC = 1,\n    LC_TIME = 2,\n    LC_COLLATE "
  },
  {
    "path": "src/sdk/include/math.h",
    "chars": 790,
    "preview": "\n \n\n#ifndef _MATH_H_\n#define _MATH_H_\n\n#define HUGE_VAL \\\n  (__extension__                                              "
  },
  {
    "path": "src/sdk/include/netinet/in.h",
    "chars": 3973,
    "preview": "\n\n#ifndef _NETINET_IN_H_\n#define _NETINET_IN_H_\n\n#include <sys/types.h>\n#include <sys/socket.h>\n\n#define ntohs(n) \\\n    "
  },
  {
    "path": "src/sdk/include/os.h",
    "chars": 171,
    "preview": "\n#ifndef _OS_H_\n#define _OS_H_\n\n#include <sys/types.h>\n\n#include \"../../kernel/core/api/kernel/syscall.h\"\n#include \"../."
  },
  {
    "path": "src/sdk/include/pwd.h",
    "chars": 400,
    "preview": "\n \n\n#ifndef _PWD_H_\n#define _PWD_H_\n\n#include <sys/types.h>\n\nstruct passwd {\n    char* pw_name;\n    char* pw_passwd;\n   "
  },
  {
    "path": "src/sdk/include/setjmp.h",
    "chars": 167,
    "preview": "\n \n\n#ifndef _SETJMP_H_\n#define _SETJMP_H_\n\ntypedef unsigned long jmp_buf[ 6 ];\n\nint setjmp( jmp_buf env );\nvoid longjmp("
  },
  {
    "path": "src/sdk/include/signal.h",
    "chars": 5102,
    "preview": "\n \n\n#ifndef _SIGNAL_H_\n#define _SIGNAL_H_\n\n#include <time.h>\n#include <sys/types.h>\n\n#define SIGHUP    1       /* Hangup"
  },
  {
    "path": "src/sdk/include/stdarg.h",
    "chars": 284,
    "preview": "\n\n#ifndef _STDARG_H_\n#define _STDARG_H_\n\ntypedef __builtin_va_list va_list;\n\n#define va_start(a,b)  __builtin_va_start(a"
  },
  {
    "path": "src/sdk/include/stddef.h",
    "chars": 625,
    "preview": "\n#ifndef _STDDEF_H\n#define _STDDEF_H\n\n#ifndef\tNULL\n#define NULL\t\t0\n#endif\n\n\n#ifndef _HAVE_PTRDIFF_T\n#define _HAVE_PTRDIF"
  },
  {
    "path": "src/sdk/include/stdint.h",
    "chars": 1684,
    "preview": "\n \n\n#ifndef _STDINT_H_\n#define _STDINT_H_\n\ntypedef signed char int8_t;\ntypedef signed short int16_t;\ntypedef signed int "
  },
  {
    "path": "src/sdk/include/stdio.h",
    "chars": 3603,
    "preview": "\n \n\n#ifndef _STDIO_H_\n#define _STDIO_H_\n\n#define __need_size_t\n#define __need_NULL\n#include <stddef.h>\n#include <stdarg."
  },
  {
    "path": "src/sdk/include/stdlib.h",
    "chars": 1708,
    "preview": "\n \n\n#ifndef _STDLIB_H_\n#define _STDLIB_H_\n\n\n\n#define __need_size_t\n#define __need_NULL\n#include <stddef.h>\n\n\n#define EXI"
  },
  {
    "path": "src/sdk/include/string.h",
    "chars": 1379,
    "preview": "\n\n#ifndef _STRING_H_\n#define _STRING_H_\n\n#define __need_size_t\n#define __need_NULL\n#include <stddef.h>\n\nvoid* memset( vo"
  },
  {
    "path": "src/sdk/include/strings.h",
    "chars": 70,
    "preview": "\n \n\n#ifndef _STRINGS_H_\n#define _STRINGS_H_\n\n#endif /* _STRINGS_H_ */\n"
  },
  {
    "path": "src/sdk/include/sys/cdefs.h",
    "chars": 134,
    "preview": "\n\n#ifndef _SYS_CDEFS_H_\n#define _SYS_CDEFS_H_\n\n#define __nonnull(params) __attribute__((__nonnull__ params))\n\n#endif // "
  },
  {
    "path": "src/sdk/include/sys/ioctl.h",
    "chars": 184,
    "preview": "\n\n#ifndef _SYS_IOCTL_H_\n#define _SYS_IOCTL_H_\n\n#include <sys/types.h>\n\n#include \"../../kernel/core/api/dev/ioctl.h\"\n\nint"
  },
  {
    "path": "src/sdk/include/sys/mman.h",
    "chars": 1675,
    "preview": "\n\n#ifndef _SYS_MMAN_H_\n#define _SYS_MMAN_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#include <stddef."
  },
  {
    "path": "src/sdk/include/sys/mount.h",
    "chars": 335,
    "preview": "\n\n#ifndef _SYS_MOUNT_H_\n#define _SYS_MOUNT_H_\n\n#define MOUNT_NONE      0\n#define MOUNT_RO        1\n#define MOUNT_NOATIME"
  },
  {
    "path": "src/sdk/include/sys/param.h",
    "chars": 215,
    "preview": "\n\n#ifndef _SYS_PARAM_H_\n#define _SYS_PARAM_H_\n\n#include <limits.h>\n\n#undef MIN\n#define MIN(a,b) ((a)<(b)?(a):(b))\n\n#unde"
  },
  {
    "path": "src/sdk/include/sys/resource.h",
    "chars": 1013,
    "preview": "\n\n#ifndef _SYS_RESOURCE_H_\n#define _SYS_RESOURCE_H_\n\n#include <sys/time.h>\n\nstruct rusage {\n    struct timeval ru_utime;"
  },
  {
    "path": "src/sdk/include/sys/select.h",
    "chars": 551,
    "preview": "\n\n#ifndef _SYS_SELECT_H_\n#define _SYS_SELECT_H_\n\n#include <sys/time.h>\n#include <sys/types.h>\n\n#define FD_ZERO(set) \\\n  "
  },
  {
    "path": "src/sdk/include/sys/socket.h",
    "chars": 4936,
    "preview": "\n\n#ifndef _SYS_SOCKET_H_\n#define _SYS_SOCKET_H_\n\n/* Protocol families.  */\n\n#define PF_UNSPEC       0       /* Unspecifi"
  },
  {
    "path": "src/sdk/include/sys/stat.h",
    "chars": 1539,
    "preview": "\n\n#ifndef _SYS_STAT_H_\n#define _SYS_STAT_H_\n\n#include <time.h>\n#include <sys/types.h>\n\n#define S_IFMT  00170000\n#define "
  },
  {
    "path": "src/sdk/include/sys/time.h",
    "chars": 149,
    "preview": "\n\n#ifndef _SYS_TIME_H_\n#define _SYS_TIME_H_\n\n#include <time.h>\n\nint gettimeofday( struct timeval* tv, struct timezone* t"
  },
  {
    "path": "src/sdk/include/sys/types.h",
    "chars": 574,
    "preview": "\n\n#ifndef _SYS_TYPES_H_\n#define _SYS_TYPES_H_\n\n#include <stdint.h>\n\n#define __need_size_t\n#include <stddef.h>\n\n#ifndef N"
  },
  {
    "path": "src/sdk/include/sys/wait.h",
    "chars": 383,
    "preview": "\n\n#ifndef _SYS_WAIT_H_\n#define _SYS_WAIT_H_\n\n#include <sys/types.h>\n#include <sys/resource.h>\n\n#define WNOHANG   1\n#defi"
  },
  {
    "path": "src/sdk/include/termios.h",
    "chars": 4883,
    "preview": "\n \n\n#ifndef _TERMIOS_H_\n#define _TERMIOS_H_\n\n/*\n * Number of control characters.\n */\n\n#define NCCS 19\n\n/*\n * Control cha"
  },
  {
    "path": "src/sdk/include/time.h",
    "chars": 1564,
    "preview": "\n\n#ifndef _TIME_H_\n#define _TIME_H_\n\n#include <sys/types.h>\n\n#define time_t uint64_t\n#define suseconds_t int\n\ntypedef un"
  },
  {
    "path": "src/sdk/include/unistd.h",
    "chars": 4160,
    "preview": "\n \n\n#ifndef _UNISTD_H_\n#define _UNISTD_H_\n\n#include <string.h>\n#include <sys/types.h>\n\n#define STDIN_FILENO  0\n#define S"
  },
  {
    "path": "src/sdk/include/utime.h",
    "chars": 309,
    "preview": "\n \n\n#ifndef _UTIME_H_\n#define _UTIME_H_\n\n#include <time.h>\n\nstruct utimbuf {\n    time_t actime; /* access time */\n    ti"
  },
  {
    "path": "src/sdk/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/sdk/qemu.sh",
    "chars": 88,
    "preview": "#!/bin/bash\nqemu -m 1024 -s -hda ./c.img  -curses -serial /dev/tty  -redir tcp:2323::23\n"
  },
  {
    "path": "src/sdk/src/libc/Makefile",
    "chars": 6026,
    "preview": "ASMOBJS=arch/i386/setjmp.S \\\narch/i386/longjmp.S \\\narch/i386/math/e_exp.S \\\narch/i386/math/e_log.S \\\narch/i386/math/s_si"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/getpagesize.c",
    "chars": 792,
    "preview": "/* getpagesize function\n *\n * Copyright (c) 2009 Zoltan Kovacs\n *\n * This program is free software; you can redistribute"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/longjmp.S",
    "chars": 1137,
    "preview": "/* longjmp function\n *\n * Copyright (c) 2009 Zoltan Kovacs\n *\n * This program is free software; you can redistribute it "
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_atan2.S",
    "chars": 164,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global atan2\n\n\natan2:\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_exp.S",
    "chars": 880,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n/* e^x = 2^(x * log2(e)) */\n\n.section .text\n\n.ali"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_fmod.S",
    "chars": 199,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global fmod\n\n\nfmod:\n\tf"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_hypot.S",
    "chars": 1577,
    "preview": "/* Compute the hypothenuse of X and Y.\n   Copyright (C) 1998 Free Software Foundation, Inc.\n   This file is part of the "
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_log.S",
    "chars": 1039,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n *\n * Changed to use fyl2xp1 for values near 1, <drepp"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_log10.S",
    "chars": 1063,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n *\n * Changed to use fyl2xp1 for values near 1, <drepp"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/e_pow.S",
    "chars": 6539,
    "preview": "/* ix87 specific implementation of pow function.\n   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007\n   Free"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_ceil.S",
    "chars": 604,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global ceil\n\n\nceil:\n\tf"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_cos.S",
    "chars": 300,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global cos\n\n\ncos:\n\tfld"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_fabs.S",
    "chars": 73,
    "preview": ".section .text\n\n.align 4\n\n.global fabs\n\n\nfabs:\n\tfldl\t4(%esp)\n\tfabs\n\tret\n\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_finite.S",
    "chars": 203,
    "preview": "/*\n * Written by Joe Keane <jgk@jgk.org>.\n */\n\n.section .text\n\n.align 4\n\n.global finite\n\n\nfinite:\n\tmovl\t8(%esp),%eax\n\tmo"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_floor.S",
    "chars": 605,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global floor\n\n\nfloor:\n"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_frexp.S",
    "chars": 1926,
    "preview": "/* ix87 specific frexp implementation for double.\n   Copyright (C) 1997, 2000, 2005 Free Software Foundation, Inc.\n   Th"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_scalbn.S",
    "chars": 179,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global scalbn\n\n\nscalbn"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/math/s_sin.S",
    "chars": 300,
    "preview": "/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n */\n\n.section .text\n\n.align 4\n\n.global sin\n\n\nsin:\n\tfld"
  },
  {
    "path": "src/sdk/src/libc/arch/i386/setjmp.S",
    "chars": 1083,
    "preview": "/* setjmp function\n *\n * Copyright (c) 2009 Zoltan Kovacs\n *\n * This program is free software; you can redistribute it a"
  },
  {
    "path": "src/sdk/src/libc/src/closedir.c",
    "chars": 241,
    "preview": "\n \n\n#include <dirent.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <errno.h>\n\nint closedir( DIR* dir ) {\n    if ( "
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isalnum.c",
    "chars": 102,
    "preview": "\n \n\n#include <ctype.h>\n\nint isalnum( int c ) {\n    return ( ( isalpha( c ) ) || ( isdigit( c ) ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isalpha.c",
    "chars": 94,
    "preview": "\n \n\n#include <ctype.h>\n\nint isalpha( int c ) {\n    return ( islower( c ) || isupper( c ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isascii.c",
    "chars": 90,
    "preview": "\n \n\n#include <ctype.h>\n\nint isascii( int c ) {\n    return ( ( unsigned int )c < 128u );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isblank.c",
    "chars": 87,
    "preview": "\n \n\n#include <ctype.h>\n\nint isblank( int c ) {\n    return ( c == ' ' || c == '\\t' );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/iscntrl.c",
    "chars": 122,
    "preview": "\n \n\n#include <ctype.h>\n\nint iscntrl( int c ) {\n    return ( ( ( unsigned int )c < 32u ) ||\n             ( c == 127 ) );\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isdigit.c",
    "chars": 94,
    "preview": "\n \n\n#include <ctype.h>\n\nint isdigit( int c ) {\n    return ( ( c >= '0' ) && ( c <= '9' ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isgraph.c",
    "chars": 121,
    "preview": "\n \n\n#include <ctype.h>\n\nint isgraph( int c ) {\n    if ( c == ' ' ) {\n        return 0;\n    }\n\n    return isprint( c );\n}"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/islower.c",
    "chars": 94,
    "preview": "\n \n\n#include <ctype.h>\n\nint islower( int c ) {\n    return ( ( c >= 'a' ) && ( c <= 'z' ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isprint.c",
    "chars": 110,
    "preview": "\n \n\n#include <ctype.h>\n\nint isprint( int c ) {\n    c &= 0x7F;\n    return ( ( c >= 0x20 ) && ( c < 0x7F ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/ispunct.c",
    "chars": 138,
    "preview": "\n \n\n#include <ctype.h>\n\nint ispunct( int c ) {\n    return ( isprint( c ) &&\n             !isalnum( c ) &&\n             !"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isspace.c",
    "chars": 139,
    "preview": "\n \n\n#include <ctype.h>\n\nint isspace( int c ) {\n    return ( c == '\\t' || c == '\\n' || c == '\\v' || c == '\\f' || c == '\\r"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isupper.c",
    "chars": 94,
    "preview": "\n \n\n#include <ctype.h>\n\nint isupper( int c ) {\n    return ( ( c >= 'A' ) && ( c <= 'Z' ) );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/isxdigit.c",
    "chars": 197,
    "preview": "\n \n\n#include <ctype.h>\n\nint isxdigit( int c ) {\n    return ( ( ( c >= '0' ) && ( c <= '9' ) ) ||\n             ( ( c >= '"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/toascii.c",
    "chars": 75,
    "preview": "\n \n\n#include <ctype.h>\n\nint toascii( int c ) {\n    return ( c & ~0x80 );\n}\n"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/tolower.c",
    "chars": 137,
    "preview": "\n \n\n#include <ctype.h>\n\nint tolower( int c ) {\n    if ( isupper( c ) ) {\n        return c | 0x20;\n    } else {\n        r"
  },
  {
    "path": "src/sdk/src/libc/src/ctype/toupper.c",
    "chars": 422,
    "preview": "\n \n#include <ctype.h>\n\nint toupper( int c ) {\n    if ( islower( c ) ) {\n        return c & ~0x20;\n    } else {\n        r"
  },
  {
    "path": "src/sdk/src/libc/src/fcntl/creat.c",
    "chars": 140,
    "preview": "\n \n\n#include <fcntl.h>\n\nint creat( const char *pathname, mode_t mode ) {\n    return open( pathname, O_CREAT | O_WRONLY |"
  },
  {
    "path": "src/sdk/src/libc/src/fcntl/fcntl.c",
    "chars": 277,
    "preview": "\n \n\n#include <errno.h>\n#include <fcntl.h>\n\n#include <os.h>\n\nint fcntl( int fd, int cmd, ... ) {\n    int error;\n\n    erro"
  },
  {
    "path": "src/sdk/src/libc/src/fcntl/open.c",
    "chars": 279,
    "preview": "\n \n\n#include <fcntl.h>\n#include <errno.h>\n\n#include <os.h>\n\nint open( const char* filename, int flags, ... ) {\n    int e"
  },
  {
    "path": "src/sdk/src/libc/src/getopt/getopt.c",
    "chars": 26225,
    "preview": "\n \n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/types.h> /* NULL */\n\n#include <getopt.h>\n#in"
  }
]

// ... and 230 more files (download for full content)

About this extraction

This page contains the full source code of the SamyPesse/How-to-Make-a-Computer-Operating-System GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 430 files (729.8 KB), approximately 231.9k tokens, and a symbol index with 936 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!