# Embedded System On Rasberry PI - Exception & ISR
###### tags : `Embedded System`
## Environment
- [x] PC x 1
- [X] Raspberry Pi x 1
- [X] microSD card x 1
## Goal
>Add a ==system call== and observe how OS handles exception.
## Implementation
### 1. Get a linux source code
```shell=
$ git clone --depth=1 https://github.com/raspberrypi/linux -b rpi-4.9.y
```
*The path be call ==<linux source code path>== in following steps*
---
### 2. Modify source code
>#### Create my system call
>**Append following code to <linux source code path>/arch/arm/kernel/calls.S**
```c=
/* this is my sysycall start */
CALL(sys_mysyscall)
/* this is my sysycall end */
```
>#### Add a Serial number for my system call
>**Append to <linux source code path>/arch/arm/include/uapi/asm/unistd.h**
```c=
/* Original code */
#define __NR_pkey_alloc (__NR_SYSCALL_BASE+395)
#define __NR_pkey_free (__NR_SYSCALL_BASE+396)
/* Original code */
/* Append */
#define __NR_mysyscall (__NR_SYSCALL_BASE+397) // number for new syscall
/* Append */
```
>#### Design my sysyem call
>**Go to <linux source code path>/arch/arm/kernel**
**Create mysyscall.c and design in this file**
```c=
// must to include these header files
#include <linux/linkage.h>
#include <linux/kernel.h>
// syscall implementation
asmlinkage void sys_mysyscall(int a, char *b){
printk("system call …\n");
printk("int1:%d, staring:%s in kernel\n", a, b);
}
```
>**Add fuction declare to <linux source code path>/include/linux/syscalls.h**
```c=
asmlinkage void sys_mysyscall(int a, char* b);
```
:::info
==asmlinkage== is a gcc tag .
When **system call handler** want to call **system call routine** , it have to push those parameter which will be passed to **system call routine** to stack.
Beacuse **system call handler** is assembly code , and **system call routine** is C code . When assembly code call C function and pass parameter by stack , we have to add asmlinkage to C function declaration.
:::
>#### Compile linux kernel
>**Add ==mysyscall.o== to Makeile(<linux source code path>/arch/arm/kernel/Makefile)**
```shell=
obj-y := elf.o entry-common.o irq.o opcodes.o \
process.o ptrace.o reboot.o return_address.o \
setup.o signal.o sigreturn_codes.o \
stacktrace.o sys_arm.o time.o traps.o mysyscall.o
```
>**Start compile**
```shell=
$ cd <linux source code path>
$ make ARCH=arm bcm2709_defconfig
// make sure arm-linux-gnueabihf-gcc (or your cross compiler) is in $PATH
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bzImage
```
---
### 3. DEMO
>We can find ==zImage== in <linux source code path>/arch/arm/boot , and put >it to SDcard in first partition
>
>**Write a program to call syscall**
```c=
/* filename: mytestsys.c */
#include <sys/syscall.h>
#include <linux/unistd.h>
#define __NR_mysyscall (__NR_SYSCALL_BASE+397)
#define mysyscall(a,b) syscall(__NR_mysyscall,(a),(b))
int main(){
mysyscall(14,"system_call_lab");
return 0;
}
```
>**Use cross compiler compile the program**
```shell=
$ arm-linux-gnueabihf-gcc -I<linux source code path>/include/
-static -g mytestsys.c -o mytestsys.exe
```
>Put mytestsys.exe to SDcard in second partition(file system)
>
>**mysyscall be called**

---