标签:
看了一天第二章,感觉有些东西还是不太懂,在源码中有很多实现不太明白,我要一一的解开,希望懂的人看到
给点帮助,或者你也在学习中,可以留言交流一下。
先从m_devget这个函数开始:
/*
* Routine to copy from device local memory into mbufs.
*/
/* 这个函数就是来数据了,分配mbuf来存这数据,
* 一个存不下就两个,不行就分配簇 */
参数说明:
buf应该就是数据源的首地址,totlen是数据的总大小,off0就是数据偏移与首地址相较,
copy就是自己提供复制的函数。 那个ifp就先不管了,是一个结构,我看了还挺多东西。
struct mbuf *
m_devget(buf, totlen, off0, ifp, copy)
char *buf;
int totlen, off0;
struct ifnet *ifp;
void (*copy)();
{
register struct mbuf *m;
struct mbuf *top = 0, **mp = ⊤ // 这里是为了用*mp和操作top
register int off = off0, len;
register char *cp;
char *epkt;
cp = buf;
/* packet end的意思吧?
* 反正就是指向buf中有效数据的最后 */
epkt = cp + totlen;
/* 这个off非0要2*u_int16_t其实没懂?
* 那两个u_int16_t是type和length,但是谁的呢?*/
/* 下面英文说是尾部封装,就要跳过,但跳过的是谁的? */
if (off) {
/*
* If ‘off‘ is non-zero, packet is trailer-encapsulated,
* so we have to skip the type and length fields.
*/
cp += off + 2 * sizeof(u_int16_t);
totlen -= 2 * sizeof(u_int16_t);
}
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == 0)
return (0);
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = totlen;
/* 这个应该是100,MHLEN=MLEN-sizeof(struct pkthdr):108-8,
* MLEN=MSIZE-sizoef(struct m_hdr):128-20*/
m->m_len = MHLEN; //这里带pkthdr所以是100
while (totlen > 0) {
if (top) {
/* 这里的意思就是top已经指向一个mbuf了,并且还循环回来了,
说明还有元素没存下,再分配个mbuf,但这个不用带pkthdr了*/
MGET(m, M_DONTWAIT, MT_DATA);
if (m == 0) {
m_freem(top);
return (0);
}
m->m_len = MLEN;//不带pkthdr所以这里就成MLEN了,108
}
/* 这里为什么呢,不是就是相等的吗? */
len = min(totlen, epkt - cp);
/* MINCLSIZE=MHLEN+MLEN:100+108,最小簇大小,
* 这里应该就是书里说的那处问题,其实是两个mbuf是可以
* 存208个数据的100+108,但是这里用了>=所以就不行了*/
if (len >= MINCLSIZE) {
/* MCLGET这是分配一块簇给m */
MCLGET(m, M_DONTWAIT);
if (m->m_flags & M_EXT)
/* MCLBYTES应该是那个1024或者2048那个值 */
m->m_len = len = min(len, MCLBYTES);
else
len = m->m_len;
} else {
/*
* Place initial small packet/header at end of mbuf.
*/
if (len < m->m_len) {
/* max_linkhdr是全局变量在mbuf.h中 */
if (top == 0 && len + max_linkhdr <= m->m_len)
m->m_data += max_linkhdr;
m->m_len = len;
} else
len = m->m_len;
}
if (copy)
/* 说实话,就这些复制函数真是乱,这都是源在前,目标在后,
* 现在用的memcpy都是目标在前,源在后,其实真应该有
* 好好规范,虽然现在都在规范着,乱*/
copy(cp, mtod(m, caddr_t), (unsigned)len);
else
bcopy(cp, mtod(m, caddr_t), (unsigned)len);
cp += len;
*mp = m;
mp = &m->m_next;
totlen -= len;
/* 这里是干什么? */
if (cp == epkt)
cp = buf;
}
/* 这是我第一次看,但是我不明白这返回top是干什么,
* 明明没有给top赋值的操作? */
/* 哦,看到了,是在mp = &top,这时候*mp的操作已经
* 是对top的操作了 */
return (top);
}
标签:
原文地址:http://my.oschina.net/bxxfighting/blog/378522