当前位置:Linux教程 - 内核技术 - 内核技术 - 代码例子

内核技术 - 代码例子

代码例子
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));
}