learningOS开源操作系统社区
  • 首页
  • 训练营
  • 明星学员
  • 共建单位
  • 项目实习
  • 问答论坛
登录
    Copyright © 2024 opencamp.ai All rights reserved.
    2020春 lec5 课后习题讨论
    匿名2023/07/31 19:50:14提问
      lecture5student
    399

    随机抽取部分同学题解。

    Nature

     

    Python


    ```python
    import sys
    from memory import *

    # 判断是否为合法数据
    def ifvalid(bitstring):
        isvalid = bitstring >> 7
        return_number = bitstring & 0b01111111
        if isvalid == 1:
            return True,return_number
        else:
            return False,return_number
        
    # 读入要求访问的虚拟地址
    virtual_address = int(sys.argv[1][2:],16)
    print("virtual virtual_address is " + hex(virtual_address))
    page_directory_base_registor = 0x220
    base_index = 0x220 >> 5
    pde_index_mask = 0b0111110000000000
    pte_index_mask = 0b0000001111100000
    offset_mask = 0b0000000000011111
    pde_index = (virtual_address & pde_index_mask) >> 10
    pte_index = (virtual_address & pte_index_mask) >> 5
    offset = virtual_address & offset_mask
    # mem[page_index][entry_index] 为已处理好的二维数组
    first_level_number = mem[base_index][pde_index]
    flag, pte_base = ifvalid(first_level_number)
    # 说明不合法
    if not flag:
        print("   --> pde index : "+ str(hex(pde_index))+  " pde contents : (valid = 0 pfn = " + str(hex(pte_base))+")")
        print("         --> Fault (page directory entry not valid)")
    else:
        print("   --> pde index : "+ str(hex(pde_index))+  " pde contents : (valid = 1 pfn = " + str(hex(pte_base))+")")
        second_level_number = mem[pte_base][pte_index]
        flag_2, ppn_base = ifvalid(second_level_number)
        if not flag_2:
            print("     --> pte index : "+ str(hex(pte_index))+  " pde contents : (valid = 0 pfn = " + str(hex(ppn_base))+")")
            print("       --> Fault (page table entry not valid)")
        else:
            print("     --> pte index : "+ str(hex(pte_index))+  " pde contents : (valid = 1 pfn = " + str(hex(ppn_base))+")")
            number = mem[ppn_base][offset]
            print("       --> Translates to physical address : " + str(hex((ppn_base<<5)+offset)) + " --> value : " + str(hex(number))+")")
    ```

    不是问题的问题:信任了题目数据,注意虚拟地址可能非法(有冗余)。具体可参考如下函数。


    ```python
    def read_storage(page,offset):
        if page<0 or page>int('7f',16):
            return -1
        if offset<0 or offset>31:
            return -1
        return storage[page][offset]
    ```

    C++


    ```C++
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>

    uint16_t BASE_ADD = 0x220;

    void vir_to_phy(uint16_t base_add, int* phy_mem, uint16_t vir_addr){
        printf("Virtual Address %04x :\n", vir_addr);
        uint8_t pde_shift = vir_addr >> 10;
        uint8_t pte_shift = (vir_addr >> 5) % 32;
        uint8_t pde_contents = phy_mem[base_add + pde_shift];
        printf("  --> pde index: %02x, pte contents: (valid: %01d, pfn %02x) \n",
                pde_shift, pde_contents >> 7 ,pde_contents % 128);
        if(pde_contents >> 7 == 0){
            printf("    --> Fault (page ditectory entry not valid) \n");
            return;
        }
        else {
            uint8_t pte_contents = phy_mem[(pde_contents % 128)*32 + pte_shift];
            printf("    --> pte index: %02x, pte contents: (valid: %01d, pfn %02x) \n",
                pte_shift, pte_contents >> 7 ,pte_contents % 128);
            if(pte_contents >> 7 == 0){
                printf("      --> Fault (page table entry not valid) \n");
                return;
            }
            else{
                uint16_t value_addr = (uint16_t)((pte_contents % 128) << 5) + vir_addr % 32;
                int value = phy_mem[value_addr];
                printf("      --> Translates to physical address %02x --> Value: %02x \n", value_addr, value);
            }
        }
    }

    int main(){
        int phy_mem[4096];
        int i = 0;
        FILE *fp;
        fp = fopen("phymem.txt", "r");
        while(fscanf(fp, "%2x", &(phy_mem[i])) !=EOF) i++;

        uint16_t vir_addrs[10] = {0x6c74, 0x6b22, 0x03df, 0x69dc, 0x317a, 0x4546, 0x2c03, 0x7fd7, 0x390e, 0x748b};
        for(auto va: vir_addrs){
            vir_to_phy(BASE_ADD, phy_mem, va);
        }
        return 0;
    }
    ```

    RUST


    ```rust
    use std::fs;

    fn main() {
        let mut pde_index : u8;
        let mut pte_index : u8;
        let mut page_offset : u8;

        let mut pde_content : u8;
        let mut pde_valid : u8;
        let mut pde_addr : u8;

        let mut pte_content : u8;
        let mut pte_valid : u8;
        let mut pte_addr : u8;

        let mut paddr : u16;
        let mut value : u8;

        // load memory information
        let contents = fs::read_to_string("memory.txt")
                    .expect("Something went wrong reading the file");
        let mut mem = Vec::new();
        let split = contents.as_str().split("\n");
        for s in split {
            mem.push(s.split(" ").collect::<Vec<&str>>());
        }

        let vec : Vec<u16> = vec![0x6c74, 0x6b22, 0x03df, 0x69dc, 0x317a, 0x4546, 0x2c03, 0x7fd7, 0x390e, 0x748b];

        for addr in vec.into_iter() {
            print!("\nthe virtual addr is {:#x} \n    ", addr);

            //parse the virtual addr
            pde_index  = (addr >> 10) as u8;
            pte_index  = ((addr << 6) >> 11) as u8;
            page_offset  = (addr % 32) as u8;

            //get pde
            pde_content = parse_str(mem[0x11][2 + pde_index as usize]);
            pde_valid = pde_content >> 7;
            pde_addr = pde_content - (pde_valid << 7);

            //get pte
            pte_content = parse_str(mem[pde_addr as usize][2+ pte_index as usize]);
            pte_valid = pte_content >> 7;
            pte_addr = pte_content - (pte_valid << 7);

            //get physical address and value stored in it
            paddr = ((pte_addr as u16) << 5) + page_offset as u16;
            value = parse_str(mem[(paddr >> 5) as usize][2 + (paddr % 32) as usize]);

            print!("the pde index is : {:#x}, pde content is {:#x} (valid {}, pfn {:#x})\n      ", pde_index, pde_content, pde_valid, pde_addr);
            if pde_valid != 0 {
                print!("the pte index is : {:#x}, content is {:#x} (valid {}, pfn {:#x}) \n         ", pte_index, pte_content, pte_valid, pte_addr);
            }else{
                println!("Fault (page directory entry not valid)");
                continue;
            }
            if pte_valid != 0 {
                print!("the page offset is : {:#x}, the paddr is {:#x}, value is {:#x} \n       ", page_offset, paddr, value);
            }else{
                println!("Fault (page directory entry not valid)");
                continue;
            }
        }
    }

    // convert str to number, such as '1b' => 27_u8
    fn parse_str(s : &str) -> u8 {
        let mut res : u8 = 0;
        for ch in s.bytes() {
            res = (res << 4) + parse_char(ch);
        }
        res
    }
        
    // convert char to number
    fn parse_char(ch : u8) -> u8 {
        match ch {
            b'0'=> 0,
            b'1'=> 1,
            b'2'=> 2,
            b'3'=> 3,
            b'4'=> 4,
            b'5'=> 5,
            b'6'=> 6,
            b'7'=> 7,
            b'8'=> 8,
            b'9'=> 9,
            b'a'=> 10,
            b'b'=> 11,
            b'c'=> 12,
            b'd'=> 13,
            b'e'=> 14,
            b'f'=> 15,
            _ => 0
        }
    }
    ```

    回答(1)
    即可发布评论
      推荐问答
        Simple Empty
        暂无数据