zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    JPA、Hibernate、Spring data jpa之间的关系
    MySQL8.0的安装、配置、启动服务和登录及配置环境变量
    jdbc和odbc
    Win10下 Java环境变量配置
    SpringMVC框架理解
    看看资深程序员是如何教你破解图形验证码!这不很简单嘛!
    破解极验(geetest)滑动验证码
    java做图片点击文字验证码
    java实现点击图片文字验证码
    什么是HttpOnly
  • 原文地址:https://www.cnblogs.com/luo-he/p/14082528.html
Copyright © 2011-2022 走看看