Skip to content

Commit

Permalink
Lesson 10: 信号机制 Step 1
Browse files Browse the repository at this point in the history
Implement signal handling framework
  • Loading branch information
VOID001 committed May 16, 2017
1 parent 72dab6c commit 7654bdd
Show file tree
Hide file tree
Showing 12 changed files with 318 additions and 53 deletions.
49 changes: 49 additions & 0 deletions include/errno.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef _ERRNO_H
#define _ERRNO_H

// 错误号定义

extern int errno;

#define ERROR 99
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define E2BIG 7
#define ENOEXEC 8
#define EBADF 9
#define ECHILD 10
#define EAGAIN 11
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define ENOTBLK 15
#define EBUSY 16
#define EEXIST 17
#define EXDEV 18
#define ENODEV 19
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define ENFILE 23
#define EMFILE 24
#define ENOTTY 25
#define ETXTBSY 26
#define EFBIG 27
#define ENOSPC 28
#define ESPIPE 29
#define EROFS 30
#define EMLINK 31
#define EPIPE 32
#define EDOM 33
#define ERANGE 34
#define EDEADLK 35
#define ENAMETOOLONG 36
#define ENOLCK 37
#define ENOSYS 38
#define ENOTEMPTY 39

#endif
3 changes: 2 additions & 1 deletion include/linux/sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extern int sys_fork();
extern int sys_pause();
extern int stub_syscall();
extern int serial_debugstr(char *str);
extern int sys_kill(int pid, int sig);

// 目前除了少数syscall之外其余的syscall均为stub状态
fn_ptr sys_call_table[] = {
Expand Down Expand Up @@ -47,7 +48,7 @@ fn_ptr sys_call_table[] = {
stub_syscall,
stub_syscall,
stub_syscall,
stub_syscall,
sys_kill,
stub_syscall,
stub_syscall,
stub_syscall, // 40
Expand Down
22 changes: 0 additions & 22 deletions include/linux/unistd.h

This file was deleted.

62 changes: 62 additions & 0 deletions include/signal.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,55 @@
#ifndef _SIGNAL_H
#define _SIGNAL_H

#include <sys/types.h>

typedef int sig_atomic_t;
typedef unsigned int sigset_t;

#define _NSIG 32 // 32种信号,所以下面的信号集也是32bit啦
#define NSIG _NSIG

// 定义信号宏

#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#define SIGUNUSED 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGUSR1 10
#define SIGSEGV 11
#define SIGUSR2 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGSTKFLT 16
#define SIGCHLD 17
#define SIGCONT 18
#define SIGSTOP 19
#define SIGTSTP 20
#define SIGTTIN 21
#define SIGTTOU 22

// 下面定义 sigaction 需要的结构
#define SA_NOCLDSTOP 1
#define SA_NOMASK 0x40000000 // 表示不阻止在某个信号的信号处理程序中再次收到该信号
#define SA_ONESHOT 0x80000000 // 只调用一次信号处理句柄

#define SIG_BLOCK 0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2

#define SIG_DFL ((void(*) (int))0) // 默认信号处理句柄
#define SIG_IGN ((void(*) (int))1) // 信号处理忽略句柄

void (*signal(int _sig, void(*func)(int)))(int);
int raise(int sig); // 向自身发信号
int kill(pid_t pid, int sig); // 向某个进程发信号

typedef unsigned int sigset_t; // 32bit 信号集,一位表示一个信号,对于linux0.11已经够用了

struct sigaction {
Expand All @@ -10,4 +59,17 @@ struct sigaction {
void (*sa_restorer)(void);
};

// 对阻塞信号集的操作
// Not implemented in sigaction
int sigaddset(sigset_t *mask, int signo);
int sigdelset(sigset_t *mask, int signo);
int sigemptyset(sigset_t *mask);
int sigfillset(sigset_t *mask);
int sigismember(sigset_t *mask, int signo);

int sigpending(sigset_t *set);
int sigprocmask(int how, sigset_t *set, sigset_t *oldset);
// 改变对于某个信号sig的处理过程
int sigaction(int sig, struct sigaction *act, struct sigaction *oldact);

#endif
47 changes: 47 additions & 0 deletions include/sys/types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H

#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif

#ifndef _TIME_T
#define _TIME_T
typedef long time_t;
#endif

#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef long ptrdiff_t;
#endif

#ifndef NULL
#define NULL ((void *) 0)
#endif

typedef int pid_t;
typedef unsigned short uid_t;
typedef unsigned char gid_t;
typedef unsigned short dev_t;
typedef unsigned short ino_t;
typedef unsigned short mode_t;
typedef unsigned short umode_t;
typedef unsigned char nlink_t;
typedef int daddr_t;
typedef long off_t;
typedef unsigned char u_char;
typedef unsigned short ushort;

typedef struct { int quot,rem; } div_t;
typedef struct { long quot,rem; } ldiv_t;

struct ustat {
daddr_t f_tfree;
ino_t f_tinode;
char f_fname[6];
char f_fpack[6];
};

#endif

67 changes: 67 additions & 0 deletions include/unistd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef _UNISTD_H
#define _UNISTD_H

#ifdef __LIBRARY__

#define __NR_fork 2
#define __NR_pause 29
#define __NR_kill 37
#define __NR_sys_debug 72

#define _syscall0(type, name) \
type name(void) \
{ \
long __res; \
__asm__ volatile("int $0x80\n\t" \
: "=a" (__res) \
: "0" (__NR_##name)); \
if (__res >= 0) \
return (type) __res; \
/*errno = -__res;*/ \
return -1;\
}

#define _syscall1(type, name, atype, a) \
type name(atype a) \
{ \
long __res; \
__asm__ volatile("int $0x80\n\t" \
: "=a" (__res) \
: "0" (__NR_##name), "b" ((long) a)); \
if (__res >= 0) \
return (type) __res; \
/*errno = -__res;*/ \
return -1; \
}

#define _syscall2(type, name, atype, a, btype, b) \
type name(atype a, btype b) \
{ \
long __res; \
__asm__ volatile("int $0x80\n\t" \
: "=a" (__res) \
: "0" (__NR_##name), "b" ((long) a), "c" ((long) b)); \
if (__res >= 0) \
return (type) __res; \
/*errno = -__res;*/ \
return -1; \
}

#define _syscall3(type, name, atype, a, btype, b, ctype, c) \
type name(atype a, btype b, ctype c) \
{ \
long __res; \
__asm__ volatile("int $0x80\n\t" \
: "=a" (res) \
: "0" (__NR_##name), "b" ((long) a), "c" ((long) c), "d" ((long) c)); \
if (__res >= 0) \
return (type) __res; \
/* errno = -__res;*/ \
return -1; \
}

#endif

static int pause(void);

#endif
40 changes: 12 additions & 28 deletions init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/unistd.h>
#include <unistd.h>
#include <asm/system.h>
#include <asm/io.h>
// Use to debug serial
Expand All @@ -23,28 +23,9 @@ void init();

static inline int fork(void) __attribute__((always_inline));
static inline int pause(void) __attribute__((always_inline));
static inline int sys_debug(char *str) __attribute__((always_inline));
//static inline _syscall0(int, fork);

static inline int fork(void) {
long __res;
__asm__ volatile("int $0x80\n\t"
:"=a" (__res)
:"0" (__NR_fork));
if( __res >= 0)
return (int) __res;
return -1;
}

static inline int sys_debug(char *str) {
long __res;
__asm__ volatile("int $0x80\n\t"
:"=a" (__res)
:"0" (__NR_sys_debug), "b" ((long)(str)));
if (__res >= 0)
return (int) __res;
return -1;
}
static inline int sys_debug(char *str);
static inline _syscall0(int,fork)
static inline _syscall1(int, sys_debug, char *, str)

static inline int pause(void) {
long __res;
Expand Down Expand Up @@ -72,9 +53,7 @@ static inline int pause(void) {
:::"ax");

int memtest_main(void);

typedef unsigned long size_t;
int snprintf(char *str, size_t size, const char *fmt, ...);
void signal_demo_main(void);

int main() {
video_init();
Expand All @@ -91,13 +70,18 @@ int main() {
// now user process can execute!
// but why cannot schedule!
if(!fork()) {
init();
if(!fork()) {
sched_abcd_demo();
} else {
signal_demo_main();
}
while(1);
}
// while(1);
// sys_debug("B");
}

void init() {
void sched_abcd_demo() {
// Here init process (pid = 1) will
// print AABB randomly
if(!fork()) {
Expand Down
3 changes: 2 additions & 1 deletion kernel/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
include ../Makefile.header

OBJS = printk.o panic.o traps.o asm.o sched.o system_call.o sys.o fork.o serial_debug.o
OBJS = printk.o panic.o traps.o asm.o sched.o system_call.o sys.o fork.o \
serial_debug.o signal.o signal_demo.o exit.o

LDFLAGS += -r
CFLAGS += -I../include
Expand Down
Loading

0 comments on commit 7654bdd

Please sign in to comment.