标签:
看了一天第二章,感觉有些东西还是不太懂,在源码中有很多实现不太明白,我要一一的解开,希望懂的人看到
给点帮助,或者你也在学习中,可以留言交流一下。
先从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