---
# System prepended metadata

title: Embedded System On Rasberry PI - Exception & ISR
tags: [Embedded System]

---

# 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** 

![](https://i.imgur.com/SQsCWJr.png)



---
