【正文】
Can?t cross a ?pageboundary? ? In order for the NIC to fetch the user?s data using its BusMaster DMA capability, it is necessary for the buffer needs to reside in a physically contiguous memoryregion ? But we can?t be sure Linux will have setup the CPU?s pagetables that way – unless the ?buf? is confined to a single pageframe buf Truncate ?len? if necessary ssize_t my_write( struct file *file, const char *buf, size_t len, loff_t *pos ) { if ( offset + len PAGE_SIZE ) len = PAGE_SIZE – offset。mem_map[ pfn_pgtbl ]。 pfn_frame = (pgtbl[ pindex ] 12)。 pgtbl = (unsigned int *)kmap( amp。 ~0xFFF )。 // frameoffset (12bits) // then walk the CPU?s pagingtables to get buf?s physicaladdress asm(“ mov %%cr3, %%eax \n mov %%eax, %0 “ : “=m”(_cr3) : : “ax” )。 // pgtblindex (10bits) offset = ((int)buf 0) amp。 // pgdirindex (10bits) pindex = ((int)buf 12) amp。 // take apart the virtualaddress of the user?s ?buf? variable dindex = ((int)buf 22) amp。 } Transmit operation application program user databuffer runtime library write() Linux OS kernel nic devicedriver my_write() file subsystem hardware packet buffer copy_from_user() DMA user space kernel space We want to eliminate this copyingoperation Our driver?s packetlayout packetbuffer in kernelspace destnaddress sourceaddress TYPE/ LENGTH count data data data – baseaddress (64bits) status Packet length special CSS 16 bytes cmd CSO Format for Legacy TransmitDescriptor Can zerocopy be transparent? ? We would like to implement the zerocopy concept in