( 原文:http://www.nyx.net/~ctwong/minix/MinixNetworking.html
文章借助了金山的翻译功能,所以有些地方不太通顺,凑合着看吧 by hugion, 2009.5.20 )
This documentation is written by Charlie Tsz-Hong Wong and is copyrighted to him. Do not use or copy this without permission from him. In general though
since I wish this documentation to be useful for educational purposes I would gladly consider any requests to be used for such purposes.
这一文件是书面的查理慈云康和他的版权。不要使用或复制本,未经允许他。虽然一般,因为我想这个文件是有用的为教育目的,我很乐意考虑任何要求被用于此类目的。
This is documentation for the source code of Minix networking. It describes in detail the basic parts of how the networking system works. The Minix
networking source code is in the inet/ directory. The documentation assumes that the reader has a basic understanding of the ip, tcp, and udp protocols. It
also assumes the reader has an understanding of how Minix works and basic understanding of the C programming language. We shall begin with the main function
at inet/inet.c.
这是文件的源代码Minix联网。它详细阐述了基本的部分网络系统如何工作。在Minix网络源代码是在Inet电子交易系统/目录。该文件假设读者有一个基本的了解的IP , TCP连接,和UDP协议。它还假定读者已经了解如何Minix工程和基本的了解C编程语言。我们将开始与主要功能在Inet / inet.c 。
Minix networking runs as a process called inet. Inet works just like every other operating system process - like the file system process (fs) and the memory
management process (mm). The basic structure of a operating system process can be described as follows in the following c-like program:
Minix网络功能就像进程一样运行,并被称作inet。 Inet,就像所有其他的作业系统的进程-就像文件系统进程(fs)和内存管理进程(mm) 。操作系统的过程可以被描述为如下的下列C程序:
#include <minix/type.h>
#define TRUE 1
int main()
{
init();
while (TRUE)
{
message m;
receive(&m);
processmessage(&m);
}
}
init() initializes the inet process. After inet is initialized inet goes into an endless loop as indicated by the while (TRUE) statement. Inet does 2 things
while in the endless loop. First it waits for a message to be sent to it (usually by the file system process fs) in receive(&m). Second, after it receives
the message, it processes the message in processmessage(&m).
init 初始化在Inet进程。在Inet进程初始化, Inet进程进入一个无限循环, 如while (TRUE)所显示。 无限循环中 Inet进程做2件事情。首先等待消息发送到它(通常是文件系统
的进程fs),然后接收消息。第二,收到后就在消息处理进程中处理消息(&m)。
The main function (which starts the inet process) is at inet/inet.c.
main函数(启动inet进程)在 inet/inet.c.
User processes do not directly call the process inet when it wants to do something. Instead it calls the file system process fs. An example of calling fs in
order to user minix networking is given in the ping program for Minix (commands/simple/ping.c)
用户进程不直接调用进程Inet时,而调用文件系统进程。一个操作minix网络功能的例子(commands/simple/ping.c):
int fd, i;
int result, result1;
nwio_ipopt_t ipopt;
fd= open ("/dev/ip", O_RDWR);
ipopt.nwio_flags= NWIO_COPY | NWIO_PROTOSPEC;
ipopt.nwio_proto= 1;
result= ioctl (fd, NWIOSIPOPT, &ipopt);
First, ping calls the system function open in order to get a file descriptor fd (ie an ip channel) to the ip protocol in the inet process. Afterwards ping
calls the system function ioctl to configure the device referred to by the file descriptor fd. ioctl is a standard unix system call which one uses on a file
descriptor. The specifics of how Minix implements ioctl in inet shall be described later.
首先,ping通过系统调用open,获得一个文件描述符(如同一个ip通道), 该描述符描述inet进程的ip协议。此后ping调用系统调用ioctl通过描述符fd配置设备。 ioctl是标准的
Unix系统调用, 其中使用的一个文件描述符。具体情况如何Minix执行ioctl,在Inet稍后说明。
The file /dev/ip is a device file. The file type of a file is specified in the i_mode field of its inode structure. The inode structure is defined in
fs/inode.h. Specifically its a character file. In Minix opening a device file is implemented as follows.
该文件的/dev/IP协议是一个设备文件。该文件类型的文件中指定i_mode领域的inode上的结构。 inode上结构的定义fs/ inode.h 。特别是字符文件。在Minix打开一个设备文件的
执行情况如下:
1) Every device file has a major number and a minor number attached to it.
1) 每个设备文件具有主设备号和一个次设备号相关联。
2) The major number is an index in to the array dmap defined in fs/table.c. For the inet process in standard Minix 2.0.0, the major device number for inet is
7 = /dev/ip (look at fs/table.c).
2) 主设备号是一个在数组dmap的索引, 该数组定义在fs/ table.c 。在标准Minix 2.0.0 的inet进程中,/dev/IP协议(看看fs/ table.c) 主设备号为7。
3) The minor number is passed as a parameter in the function dmap.dmap_open.
3) 次设备号作为函数dmap.dmap_open的一个参数传入
The dmap structure is defined in the file fs/dev.h.
dmap结构在fs/dev.h中定义。
extern struct dmap {
dmap_t dmap_open;
dmap_t dmap_rw;
dmap_t dmap_close;
int dmap_task;
} dmap[];
For a major device number which corresponds to a driver for a real hardware device (say a hard disk drive) the minor device number typically corresponds to
the specific device. This is because the same driver can be the driver of more than one hardware device (say more than one hard disk). For example a hard
disk driver can handle more than one hard disk drive ie hard disk drive 0 and hard disk drive 1.
一个主设备号对应的驱动程式,一个真正的硬件设备(例如硬盘驱动器)的次要号码是:通常对应于特定的设备。这是因为相同的驱动程序可以驱动一个以上的硬件设备(比如一
个以上硬盘) 。例如硬盘驱动器可以处理一个以上的硬盘驱动器硬盘驱动器即0和硬盘驱动器1 。
The major device number for inet does not correspond to a real device driver. This is because even though its typical to do networking via an Ethernet card,
one doesnt have to. One could do networking through, say, a modem. Or, say, an internal cable modem. The inet process was written to be versatile enough so
that one doesnt have to change the inet source code in order to use the ip protocol if one decides to use a modem instead of a network card ie inet can send
datagrams on different network interfaces.
主设备号同设备驱动程序不是一一对应的。这是因为,即使它的典型做网络通过以太网卡,一个doesn't必须。人们可以通过这样的网络,也就是说,一个调制解调器。或者说,内
部电缆调制解调器。在Inet进程来撰写,多才多艺足以使一个doesn't必须改变在Inet源代码,以便使用次
é IP协议的一个决定,如果使用调制解调器,而不是网络卡即Inet电子交易系统可以传送数据在不同的网络接口。
Since the major device number does not correspond to a real device driver, neither does the minor device number generally correspond to real device. Instead
(generally) it corresponds to a layer in a networking protocol.
由于主要装置号码不相符,真正的设备驱动程序,也没有次设备号一般对应于真正的设备。相反(一般)它符合一层的网络协议。
The minor device numbers for standard Minix 2.0.0 are given in inet/generic/sr.h
次设备号在标准 Minix 2.0.0中,在inet/generic/sr.h定义
#define ETH_DEV ETH_DEV0
#define IP_DEV IP_DEV0
#define ETH_DEV0 0x01
#define IP_DEV0 0x02
#define TCP_DEV0 0x03
#define UDP_DEV0 0x04
#define ETH_DEV1 0x11
#define IP_DEV1 0x12
#define TCP_DEV1 0x13
#define UDP_DEV1 0x14
#define PSIP_DEV0 0x21
#define IP_DEV2 0x22
#define TCP_DEV2 0x23
#define UDP_DEV2 0x24
#define PSIP_DEV1 0x31
#define IP_DEV3 0x32
#define TCP_DEV3 0x33
#define UDP_DEV3 0x34
The defines in inet/generic/sr.h which begin with ETH correspond to the Ethernet layer ie a network card. For example ETH_DEV0 is the minor device number for
a network card. The 3 other minor devices numbers which are defined immediately afterwards correspond to protocols which use the network card. Hence, writing
to the inet device with the minor number IP_DEV0 would mean one is sending an ip datagram through the network card referred to with minor device number
ETH_DEV0. Similarly, writing to the inet device with the minor number TCP_DEV0 would mean one is sending an tcp/ip datagram through the network card
referred to with minor device number ETH_DEV0. Similarly, writing to the inet device with the minor number UDP_DEV0 would mean one is sending an udp/ip
datagram through the network card referred to with minor device number ETH_DEV0.
该定义在inet/generic/sr.h,这首先联邦对应的以太网层即网络卡。例如ETH_DEV0是次设备号为网络卡。 3个其他轻微设备号码是指随即符合议定书使用的网路卡。因此,面向
Inet电子设备与未成年人的数量将意味着一个IP_DEV0发送一个IP数据通过网卡提到与次要号码是: ETH_DEV0 。同样的,书面向Inet电子设备与未成年人的数量TCP_DEV0将意味着
一个是发送的TCP / IP数据包通过网络卡提到与次要号码是: ETH_DEV0 。同样的,书面向Inet电子设备与未成年人的数量UDP_DEV0将意味着一个是发送的UDP / IP数据通过网卡
提到与次要号码是: ETH_DEV0 。
Similar comments are also true concerning the minor device number ETH_DEV1.
类似的评论,也真正的次要号码是: ETH_DEV1 。
The minor device number can therefore be understood as uniquely identifying an ordered pair:
次设备号因此,可以理解为唯一识别一个有序对:
(network interface, protocol).
(网络接口,议定)
PSIP_DEV0 is the minor device number for a pseudo-ip device. A pseudo-ip device can be understood in terms of another well known pseudo device in unix (and
minix) ie pseudo-terminals.
PSIP_DEV0是pseudo-ip 设备的次设备号。在unix和minix中,pseudo-ip 可以被理解为 pseudo终端设备。
In minix a terminal device can be called /dev/ttyp0 while the corresponding pseudo terminal device would be called /dev/ptyp0. The pseudo-terminal device and
the corresponding terminal device form a bi-directional (2 way) pipe. Hence when one writes to ttyp0, one can read what was just written by reading ptyp0.
Similarly if one were to write to ptyp0, one can read what was just written by reading ttyp0.
在minix中,终端设备被称作 /dev/ttyp0,一个pseudo终端设备被称作为/dev/ptyp0.
在minix终端设备可称为/ dev/ttyp0而相应的伪终端设备将被命名为/ dev/ptyp0 。伪终端设备和相应的终端设备组成的双向( 2路)管。因此,当一个写入ttyp0 ,人们可以阅
读刚才写的阅读ptyp0 。同样,如果一个人写信给ptyp0 ,人们可以阅读刚才写的阅读ttyp0 。
PSIP_DEV0, the pseudo-ip device, plays a similar role to the pseudo-terminal device while IP_DEV2 plays a similar role to the terminal device. When one
writes to IP_DEV2, one can read what was just written by reading PSIP_DEV0. Similarly if one were to write to PSIP_DEV0, one can read what was just written
by reading IP_DEV2.
PSIP_DEV0 ,伪IP设备,起着类似的作用的伪终端设备,同时IP_DEV2发挥类似作用的终端设备。当一个写入IP_DEV2 ,人们可以阅读刚才写的阅读PSIP_DEV0 。同样,如果一个人
写信给PSIP_DEV0 ,人们可以阅读刚才写的阅读IP_DEV2 。
The pseudo-ip devices however offer more options than the pseudo-terminal devices. If one wants to read from the ip device IP_DEV2 without reading the ip
header on can call ioctl(fd, NWIOSIPOPT, &struct nwio_ipopt) with the option NWIO_RWDATONLY set so that one can read to and write from the ip device IP_DEV2
without adding or retrieving the ip header. For details see the ip.4 man page.
伪IP设备提供更多的选择但是比伪终端设备。如果要读取IP设备IP_DEV2没有阅读上的IP报头,可调用ioctl(fd, NWIOSIPOPT, &struct nwio_ipopt)的选项NWIO_RWDATONLY设置,
使人们可以读出和写入的IP设备IP_DEV2不增加或检索IP报头。细节见ip.4人页面。
Using pseudo-ip devices one can easily write a user process program which would allow one to connect to the internet using a serial modem even though there
is no serial modem driver in the inet process. More generally, one can send ip messages using different network interfaces.
利用伪IP设备可以轻松地写出一个用户进程的计划将允许一个连接到Internet使用串行调制解调器即使没有串行调制解调器驱动程序在Inet电子交易系统的进程。更普遍的,人们
可以传送IP信息使用不同的网络接口。
The outline for using a modem on com1 and ppp as a network interface would be as follows.
大纲使用调制解调器的COM1连接和购买力平价作为一个网络接口将作如下安排。
int main
{
int fd;
char buffer[512];
pid_t pid;
fd= open ("/dev/psip", O_RDWR);
if ((pid = fork()) == -1) {
exit(0); /*handle error*/
}
if pid != 0 { /*parent process*/
while(1)
{
ReadCom1(buffer);
RemovePPPHeaders(buffer);
write(fd, buff, sizeof(buff));
}
} else { /*child process*/
while(1)
{
read(fd, buff, sizeof(buff));
AddPPPHeaders(buffer);
WriteCom1(buffer);
}
}
}
We make the assumption that the ppp protocol is being used as network interface.
我们作出的假设,即PPP协议是被用来作为网络接口。
The open statement returns a file descriptor to the psip (pseudo-ip) device. The program then executes the fork system command so that can be a pseudo-ip
reader (which shall write to the modem) and a pseudo-ip writer (which shall read from the modem).
公开声明返回一个文件描述符的psip (伪IP )的设备。然后执行该计划的交岔路口系统命令,这样可以是一个假的IP读者(其中应写入调制解调器)和一个假的IP作家(其中应
改为从调制解调器) 。
The parent process is the pseudo-ip reader (which shall write to the modem). The parent process goes in an endless loop. First it reads from the modem. Next
it removes the ppp protocol header. Finally it writes to the pseudo-ip device.
父进程是假的IP读者(其中应写入调制解调器) 。母公司的过程就会在一个无限循环。首先是内容的调制解调器。下一步它消除了PPP协议头。最后它写入伪IP设备。
The child process is the pseudo-ip writer (which shall read from the modem). The child process goes in an endless loop. First it reads from the pseudo-ip
device. Next it adds the ppp protocol header. Finally it writes to the modem.
子进程是假的IP作家(其中应改为从调制解调器) 。孩子的过程就会在一个无限循环。首先是内容的假的IP设备。下一步是增加了PPP协议头。最后它写入调制解调器。
fd tables
fd表
Every protocol (tcp,ip, udp) has a fd table. The fd table holds the protocol specific information for the file descriptor and also information specific to
the file descriptor.
每一个协议 (tcp,ip, udp)的fd表。该fd表持有该议定书的具体信息的文件描述符,并具体信息文件描述符。
port tables
port表
Every protocol (tcp,ip, udp) has a port table. The port table corresponds to the minor device numbers for the protocol. Theres a 1-1 correspondence between
the elements of the port table and the minor device numbers for the protocol and hence the minor device numbers for the network interfaces.
每一个协议( TCP ,知识产权, UDP连接)的港口就座。港口表对应次设备号议定书。 Theres 1-1之间的对应部分的港口表,次设备号议定书,因此,次设备号的网络接口。
How inet handles messages
inet是怎么处理消息的
Inet starts in inet/inet.c in the main function.
inet在inet/inet.c中的main函数开始.
When inet receives a message in the main function it puts the message in the message queue.
当inet在main函数中收到一个消息,他就将消息放到消息队列。
r= receive (ANY, &mq->mq_mess);
But first the message queue must be initialized.
但首先消息队列必须被初始化
As previously stated inet runs in an endless loop receiving messages and processing messages just like the file system process (fs) and the memory
management process (mm). But before it goes in to the endless loop, it first does initialization.
如前所述Inet运行在一个无限循环接收消息和处理消息一样,文件系统进程率( FS )和内存管理进程(mm) 。但它第一次被初始化后,就进入到无限循环
Inet calls nw_init() which does the initilization. nw_init() calls mq_init(). We shall discuss the other functions it calls later.
inet调用nw_init()完成初始化, nw_init()调用mq_init()完成初始化。我们迟些讨论这两个函数。
mq.c
//mq.c
mq_init is defined in inet/mq.c.
mq_init 在inet/mq.c中定义.
The message queue structure is defined in inet/mq.h.
消息队列在inet/mq.h中定义.
typedef struct mq
{
message mq_mess;
struct mq *mq_next;
int mq_allocated;
} mq_t;
and inet/mq.c.
#define MQ_SIZE 128
PRIVATE mq_t mq_list[MQ_SIZE];
mq_message is the message structure. The message queue is both an array and a linked list when it is first initialized.
mq_message是消息结构.消息队列既是一个数组,也是一个链表结构。
After mq_init() is called the mq_next field of every member of the mq_list array points to the preceding member in the array. Also mq_init() makes
mq_freelist point to the end of the array. mq_freelist points to the head of the list of free (unused) elements in the mq_list array.
经过mq_init(),被称为mq_list的每一个成员的 mq_next都指向数组的前驱。mq_init() 使mq_freelist指向数组尾部。 mq_freelist指向mq_list数组的空闲(未使用)列表的头。
mq_get returns an item from the mq_list array and in the mq_freelist linked list. Its marked as allocated by setting mq_allocated = 1 and removing it from
the mq_freelist linked list.
mq_get返回数组mq_list和mq_freelist链表中的一个元素. 他通过标识mq_allocated = 1来表示已分配,并将其从mq_freelist链表移出.
A message item is freed by calling mq_free(mq) where mq is the message item. The message item is marked as freed by setting mq_allocated = 0 and adding it
back to the mq_freelist linked list.
消息元素通过调用mq_free(mq)来释放.消息元素通过标识mq_allocated = 0来标识为未使用,并插入到mq_freelist链表中.
Back to main in inet.c
回到inet.c的main函数
The message loop for inet begins with while (TRUE) inet the main function.
消息获取的循环是在main函数的while(TRUE)开始的
inet gets a free message item from the message queue to place a new message in by calling
inet通过系统调用 mq_get()来从消息队列中获得一个空消息,作为发一个消息使用
mq= mq_get();
It then waits for the message by calling
然后通过系统调用receive (ANY, &mq->mq_mess)来获取一个消息
r= receive (ANY, &mq->mq_mess);
Typically the message comes from the file system which a user process calls in order to use inet. Such a message is processed by calling
典型的消息来自于文件系统,一个用户进程请求inet,这样一个信息处理的要求使用如下系统调用:
sr_rec(mq);
How minor devices relate to sr.c
次设备号的关联在sr.c中完成
The minor number of the device is an index in to the array sr_fd_table. An internet protocol (eg tcp, udp, ip) is started in inet by calling the
corresponding initialization routine (eg tcp_init(), udp_init(), ip_init()). All of the initialization routines are started in inet.c in nw_init(). The
corresponding initialization routine calls sr_add_minor in sr.c which passes the minor device number as a parameter in the the parameter minor. Minor is an
index in to the array sr_fd_table. It gets the element of the array with the index equal to minor and sets the various properties of the element with the
index. It then sets the flag of the element so that the element is marked as a element corresponding to a minor device (by setting the flag SFF_MINOR ) and
as being used (by setting the flag SFF_INUSE ).
次设备号是数组sr_fd_table的索引 。互联网协议(如TCP连接, UDP连接, IP )是在Inet通过调用相应的初始化例程(例如tcp_init() , udp_init() , ip_init())开始的 。
所有的初始化例程的开始inet.c在nw_init() 。相应的初始化例程调用sr_add_minor在sr.c途经次设备号作为参数传入。次设备号是数组sr_fd_table的索引 。它得到的数组元素
的索引,并根据元素的索引设置各种属性。然后它设置标志,使元素相应的一个小设备号(通过设置标志SFF_MINOR )和正在使用(通过设置标志SFF_INUSE ) 。
sr.c continued
The repl_queue is used to handle deadlocks
repl_queue队列用来处理死锁
本文详细介绍了Minix网络系统的运作原理,包括其进程结构、消息处理流程及如何通过不同的网络接口进行通信。此外,还深入探讨了设备文件、伪IP设备的概念及其应用场景。
2345

被折叠的 条评论
为什么被折叠?



