内核技术 - 代码例子
代码例子
2004-04-23 15:18 pm来自:Linux文档
现载:Www.8s8s.coM
地址:无名
[目录]
--------------------------------------------------------------------------------
header.c
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
/* 1 */
#define KERNEL
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/malloc.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
#include "tdd.h"
/* 2 */
static int tdd_trace;
static int write_busy;
static int read_busy;
static struct tdd_buf *qhead;
static struct tdd_buf *qtail;
/* 3 */
static int tdd_read(struct inode *, struct file *, char *, int);
static int tdd_write(struct inode *, struct file *, char *, int);
static int tdd_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
static int tdd_open(struct inode *, struct file *);
static void tdd_release(struct inode *, struct file *);
extern void console_print(char *);
struct file_operations tdd_fops =
{
NULL,
tdd_read,
tdd_write,
NULL,
NULL,
tdd_ioctl,
NULL,
tdd_open,
tdd_release,
NULL,
NULL,
NULL,
NULL
};
[目录]
--------------------------------------------------------------------------------
init.c
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
void tdd_init(void)
{
tdd_trace = TRUE;
if (register_chrdev(30, "tdd", &tdd_fops))
TRACE_TXT("Cannot register tdd driver as major device 30")
else
TRACE_TXT("Tiny device driver registered successfully")
[目录]
--------------------------------------------------------------------------------
newthread
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
new_thread(int (*start_addr)(void), int stack_size)
{
struct context *ptr;
int esp;
/* 1 */
if (!(ptr = (struct context *)malloc(sizeof(struct context))))
return 0;
/* 2 */
if (!(ptr->stack = (char *)malloc(stack_size)))
return 0;
/* 3 */
esp = (int)(ptr->stack+(stack_size-4));
*(int *)esp = (int)exit_thread;
*(int *)(esp-4) = (int)start_addr;
*(int *)(esp-icon_cool.gif = esp-4;
ptr->ebp = esp-8;
/* 4 */
if (thread_count++)
{
/* 5 */
ptr->next = current->next;
ptr->prev = current;
current->next->prev = ptr;
current->next = ptr;
}
else
{
/* 6 */
ptr->next = ptr;
ptr->prev = ptr;
current = ptr;
switch_context(&main_thread, current);
}
return 1;
}
[目录]
--------------------------------------------------------------------------------
exitthead
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
static exit_thread(void)
{
struct context dump, *ptr;
/* 1 */
if (--thread_count)
{
/* 2 */
ptr = current;
current->prev->next = current->next;
current->next->prev = current->prev;
current = current->next;
free(ptr->stack);
free(ptr);
switch_context(&dump, current);
}
else
{
/* 3 */
free(current->stack);
free(current);
switch_context(&dump, &main_thread);
}
}
[目录]
--------------------------------------------------------------------------------
getchannel
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
get_channel(int number)
{
struct channel *ptr;
/* 1 */
for (ptr = channel_list; ptr; ptr = ptr->link)
if (ptr->number==number)
return((int)ptr);
/* 2 */
if (!(ptr = (struct channel *)malloc(sizeof(struct channel))))
return 0;
/* 3 */
ptr->number = number;
ptr->message_list = 0;
ptr->message_tail = 0;
ptr->sr_flag = 0;
ptr->link = channel_list;
channel_list = ptr;
return((int)ptr);
}
[目录]
--------------------------------------------------------------------------------
def
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
#include <string.h>
struct context /* One structure for each thread */
{
int ebp; /* Base pointer (stack frame pointer) store */
char *stack; /* Pointer to memory block for thread stack */
struct context *next; /* Round robin circular list pointer */
struct context *prev; /* Round robin circular list pointer */
};
struct channel /* One structure for each communication channel */
{
int number; /* Channel number */
int sr_flag; /* 0=no queue, 1=send queued, 2=receive queued */
struct channel *link; /* Link to next channel in list */
struct message *message_list; /* Head of message queue */
struct message *message_tail; /* Tail of message queue */
};
struct message /* One structure for each pending send/receive */
{
int size; /* Size of message in bytes */
char *addr; /* Pointer to start of message */
struct message *link; /* Link to next message in queue */
struct context *thread; /* Which thread blocks on this struct */
};
static struct context main_thread; /* Storage for main() details */
static struct context *current; /* Currently executing thread */
static int thread_count = 0; /* Number of threads to schedule */
static struct channel *channel_list = 0; /* List of all channels */
static int switch_context(struct context *, struct context *);
static int exit_thread(void);
static int rendezvous(struct channel *, char *, int, int);
[目录]
--------------------------------------------------------------------------------
release
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
release(void)
{
/* 1 */
if (thread_count<=1)
return 0;
/* 2 */
current = current->next;
switch_context(current->prev, current);
return 1;
}
static switch_context(struct context *from, struct context *to)
{
/* 3 */
__asm__
(
"movl 8(%ebp),%eax
"
"movl %ebp,(%eax)
"
"movl 12(%ebp),%eax
"
"movl (%eax),%ebp
"
);
}
[目录]
--------------------------------------------------------------------------------
redezvous
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
send(int chan, char *addr, int size)
{
/* 1 */
return(rendezvous((struct channel *)chan, addr, size, 1));
}
receive(int chan, char *addr, int size)
{
/* 2 */
return(rendezvous((struct channel *)chan, addr, size, 2));
}
static int rendezvous(struct channel *chan, char *addr,
int size, int sr_flag)
{
struct message *ptr;
int nbytes;
/* 3 */
if (sr_flag==3-chan->sr_flag)
{
/* 4 */
ptr = chan->message_list;
chan->message_list = ptr->link;
ptr->thread->next = current->next;
ptr->thread->prev = current;
current->next->prev = ptr->thread;
current->next = ptr->thread;
++thread_count;
/* 5 */
nbytes = (size<ptr->size)?size:ptr->size;
ptr->size = nbytes;
/* 6 */
if (sr_flag==1)
memcpy(ptr->addr, addr, nbytes);
else
memcpy(addr, ptr->addr, nbytes);
/* 7 */
if (!chan->message_list)
chan->sr_flag = 0;
return(nbytes);
}
else
{
/* 8 */
ptr = (struct message *)malloc(sizeof(struct message));
if (!chan->message_list)
chan->message_list = ptr;
else
chan->message_tail->link = ptr;
chan->message_tail = ptr;
ptr->link = 0;
ptr->size = size;
ptr->addr = addr;
chan->sr_flag = sr_flag;
ptr->thread = current;
current->prev->next = current->next;
current->next->prev = current->prev;
/* 9 */
if (--thread_count)
{
current = current->next;
switch_context(ptr->thread, current);
}
else
switch_context(ptr->thread, &main_thread);
/* 10 */
nbytes = ptr->size;
free(ptr);
return(nbytes);
}
}
[目录]
--------------------------------------------------------------------------------
unbouded
/***********************************************************************
Case study source code from the book `The linux A to Z'
by Phil Cornes. Published by Prentice Hall, 1996.
Copyright (C) 1996 Phil Cornes
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
int buffer(void);
int start(void);
int ch_desc1, ch_desc2;
main(void)
{
ch_desc1 = get_channel(1);
ch_desc2 = get_channel(2);
new_thread(start, 1024);
}
start(void)
{
int i, n;
new_thread(buffer, 1024);
for (i = 0; i<10, ++i)
{
send(ch_desc1, &i, sizeof(int));
release();
}
for (i = 0; i<10, ++i)
{
receive(ch_desc2, &n, sizeof(int));
printf("i=%d n=%d
", i, n);
release();
}
}
buffer(void)
{
int i;
receive(ch_desc1, &i, sizeof(int));
new_thread(buffer, 1024);
send(ch_desc2, &i, sizeof(int));
}