예제 #1
0
  /**
   * Transfer data from the specified array to this process's virtual memory. This method handles
   * address translation details. This method must <i>not</i> destroy the current process if an
   * error occurs, but instead should return the number of bytes successfully copied (or zero if no
   * data could be copied).
   *
   * @param vaddr the first byte of virtual memory to write.
   * @param data the array containing the data to transfer.
   * @param offset the first byte to transfer from the array.
   * @param length the number of bytes to transfer from the array to virtual memory.
   * @return the number of bytes successfully transferred.
   */
  public int writeVirtualMemory(int vaddr, byte[] data, int offset, int length) {
    Lib.assertTrue(offset >= 0 && length >= 0 && offset + length <= data.length);

    byte[] memory = Machine.processor().getMemory();

    int transferred = 0;
    while (length > 0 && offset < data.length) {
      int addrOffset = vaddr % 1024;
      int virtualPage = vaddr / 1024;

      if (virtualPage >= pageTable.length || virtualPage < 0) {
        break;
      }

      TranslationEntry pte = pageTable[virtualPage];
      if (!pte.valid || pte.readOnly) {
        break;
      }
      pte.used = true;
      pte.dirty = true;

      int physPage = pte.ppn;
      int physAddr = physPage * 1024 + addrOffset;

      int transferLength = Math.min(data.length - offset, Math.min(length, 1024 - addrOffset));
      System.arraycopy(data, offset, memory, physAddr, transferLength);
      vaddr += transferLength;
      offset += transferLength;
      length -= transferLength;
      transferred += transferLength;
    }

    return transferred;
  }