mit 6.828学习笔记不知道几--lab6PartB

part B

exercise 9:

阅读手册3.2节

exercise 10:

在kern/e1000.c中添加函数

void
e1000_receive_init()
{
    for(int i=0; i<RX_MAX; i++){
        memset(&rx_list[i], 0, sizeof(struct rx_desc));
        memset(&rx_buf[i], 0, sizeof(struct packets));
        rx_list[i].addr = PADDR(rx_buf[i].buffer); 
        //rx_list[i].status &= ~E1000_TXD_STAT_DD; 
    }
    pci_e1000[E1000_MTA>>2] = 0;
    pci_e1000[E1000_RDBAL>>2] = PADDR(rx_list);
    pci_e1000[E1000_RDBAH>>2] = 0;
    pci_e1000[E1000_RDLEN>>2] = RX_MAX*sizeof(struct rx_desc);
    pci_e1000[E1000_RDH>>2] = 0;
    pci_e1000[E1000_RDT>>2] = RX_MAX -1;
    pci_e1000[E1000_RCTL>>2] = (E1000_RCTL_EN | E1000_RCTL_BAM |
                    E1000_RCTL_LBM_NO | E1000_RCTL_SZ_2048 |
                     E1000_RCTL_SECRC);
    pci_e1000[E1000_RA>>2] = 0x52 | (0x54<<8) | (0x00<<16) | (0x12<<24);
    pci_e1000[(E1000_RA>>2) + 1] = (0x34) | (0x56<<8) | E1000_RAH_AV;
}

并且不要忘记把这个函数加入kern/e1000.c中e1000_init()函数中:

int
e1000_init(struct pci_func* pcif)
{
    pci_func_enable(pcif);
    //pci_e1000 是1个指针,指向映射地址, uint32_t* pci_e1000;
    //他创建了一个虚拟内存映射
    pci_e1000 = mmio_map_region(pcif->reg_base[0], pcif->reg_size[0]);
    e1000_print_status(E1000_STATUS);
    
    e1000_transmit_init();
    e1000_receive_init();

    return 1;
}

在kern/e1000.h中加入函数声明:

void e1000_receive_init();

现在可以对receive功能进行基本测试:

运行

make E1000_DEBUG=TX,TXERR,RX,RXERR,RXFILTER Run -net_testinput

testinput将传输一个ARP(Address Resolution Protocol地址解析协议)通知包(使用您的包传输系统调用),QEMU将自动应答该通知包。即使您的驱动程序还不能接收到此回复,应该看到一条“e1000: unicast match[0]: 52:54:00:12:34:56”消息,指示e1000接收了一个数据包,并且匹配了配置的receive filter。

如果看到"e1000: unicast mismatch: 52:54:00:12:34:56" 消息,则e1000过滤掉了数据包,这意味着可能没有正确配置RAL和RAH。确保字节顺序正确,不要忘记在RAH中设置“Address Valid”位。

如果没有收到任何“e1000”消息,可能没有正确地启用receive。

 

 exercise 11:

int
e1000_receive(void* addr) {

    //int head = pci_e1000[E1000_RDH >> 2];
    int tail = (pci_e1000[E1000_RDT >> 2]+1)%RX_MAX;
    // 有效描述符指的是可供E1000存放接收到数据的描述符或者是说数据已经被读取过了
    struct rx_desc* rx_valid = &rx_list[tail];
    if ((rx_valid->status & E1000_TXD_STAT_DD) == E1000_TXD_STAT_DD) {
        int len = rx_valid->length;
        memcpy(addr, rx_buf[tail].buffer, len);
        rx_valid->status &= ~E1000_TXD_STAT_DD;
        pci_e1000[E1000_RDT >> 2] = tail;
        return len;

    }
    return -1;
}

系统调用部分类似与transmit,这里就不写了

exercise 12:

void
input(envid_t ns_envid)
{
    binaryname = "ns_input";

    // LAB 6: Your code here:
    //     - read a packet from the device driver
    //    - send it to the network server
    // Hint: When you IPC a page to the network server, it will be
    // reading from it for a while, so don't immediately receive
    // another packet in to the same physical page.

    char buf[2048];
    int length;
    while(1){
        while((length = sys_packet_try_receive(buf))<0)//尝试接收网卡输入
            sys_yield();
        nsipcbuf.pkt.jp_len=length;
        memcpy(nsipcbuf.pkt.jp_data, buf, length);
        ipc_send(ns_envid, NSREQ_INPUT, &nsipcbuf, PTE_U | PTE_P);
        for(int i=0; i<50000; i++)
            if(i%1000==0)
                sys_yield();
    }




}

运行

 make E1000_DEBUG=TX,TXERR,RX,RXERR,RXFILTER run-net_testinput

出现:

input: 0000   5254 0012 3456 5255  0a00 0202 0806 0001
input: 0010   0800 0604 0002 5255  0a00 0202 0a00 0202
input: 0020   5254 0012 3456 0a00  020f 0000 0000 0000
input: 0030   0000 0000 0000 0000  0000 0000 0000 0000

make grade:

testoutput [5 packets]: OK (2.0s) 
testoutput [100 packets]: OK (2.1s) 
Part A score: 35/35

testinput [5 packets]: OK (1.9s) 
testinput [100 packets]: OK (1.4s) 
tcp echo server [echosrv]: OK (1.5s) 

exercise 13:

static int
send_data(struct http_request* req, int fd)
{
    // LAB 6: Your code here.
    //panic("send_data not implemented");
    char buf[128];
    int r;

    while (1) {
        r = read(fd, buf, 128);
        if (r <= 0)
            return r;
        if (write(req->sock, buf, r) != r)
            return -1;
    }
}
// LAB 6: Your code here.
    //panic("send_file not implemented");
    struct Stat st;
    if ((fd = open(req->url, O_RDONLY)) < 0)
        return send_error(req, 404);

    if ((r = fstat(fd, &st)) < 0)
        return send_error(req, 404);

    if (st.st_isdir)
        return send_error(req, 404);

 

 make grade

 

 

 

 

posted @ 2020-12-03 20:17  落鹤  阅读(101)  评论(0编辑  收藏  举报