# Writing software for PepperOS

## Why would you want to do that?

Honestly I have no idea. Maybe you have too much free time.  
Keep in mind that the Pepper kernel is a personal project and it's full of bugs, inconsistencies, weird ways of doing things (and I don't care because it's my toy).  
Now if you still want to write something for this OS, thank you. Follow along.

## Headers available in userspace

Of course, all of the freestanding headers are available:
- `<float.h>`: macros for floating-point types
- `<limits.h>`: macros for integer types
- `<iso646.h>`: macros for bitwise and logical operators
- `<stdarg.h>`: variadic function support
- `<stddef.h>`: definitions for `size_t`, `ptrdiff_t`, and others
- `<stdbool.h>`: definitions for boolean types
- `<stdint.h>`: definitions for `int_t` and `uint_t` types

Also available is the `<syscall.h>` header that gives access to low-level system call interface, notably the `syscallX` function family, X being the amount of arguments to use.

(TODO: put the other headers here once libc is more complete)

## 1. Write the source code

PepperOS is able to run programs written in x86 assembly, and C programs.

### x86 Assembly

Start your assembly file with the `bits 64` instruction, to emit 64-bit code.  
You can add sections `.text`, `.data`, `.bss` as you need.  
The three things to take in consideration here are:
- PepperOS does not use the `syscall` instruction, instead it uses the old-fashioned `int 0x80` to trigger a system call.  
- The entry point should be labelled as `_start`.
- At the end of the file, there should be an exit system call followed by a loop, like so:

```nasm
.end:
    mov rax, 0x3C
    mov rdi, 0x0
    int 0x80

.loop:
    jmp .loop
```

For an example, look at the file [pedicel.S](../user/pedicel.S).

### C program

You will find relevant headers in the `libc` directory. They contain system call wrappers, utility functions, and more. See what's implemented there and what's not.  
To invoke a system call you can use the functions defined in `libc/syscall.h`.

## 2. Add the Makefile rule and variable

Now that your code is complete, add a Makefile rule to `user/Makefile` with your program name. You can just copy-paste the rule that applies to you (either from an Assembly source or C source) and change the name of the files (.raw, .elf, etc...) in the rule.  
For clarity, raw binaries have the `.raw` extension, and ELF ones have `.elf`.  
You also now have to add the name of the executable to the `USER_PROGRAMS` variable at the top of the global Makefile.  
Finally, do `make user` to compile your program.

## 3. Run your program

You can now boot up PepperOS, in a VM or on real hardware, and use the kernel's shell to `list` files in the filesystem (to see if your executable was properly added), and then, run it with the `load` command. Congratulations, you made a program for a random hobby OS!

## 4. (Optional) debugging

Use GDB with the `make debug` rule!  
For your information, user programs are loaded at `0x400000`. Can be good to know to set breakpoints.

## 5. (Optional) contribute!

If you like what you've done and you think it could be nice to add it to PepperOS, send it to me by e-mail: `xamidev (at) riseup (dot) net`. It may or may not be added in a future release... who knows?