《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
6.5 KiB

  1. #! /usr/bin/env python
  2. import sys
  3. from optparse import OptionParser
  4. import random
  5. import math
  6. def convert(size):
  7. length = len(size)
  8. lastchar = size[length-1]
  9. if (lastchar == 'k') or (lastchar == 'K'):
  10. m = 1024
  11. nsize = int(size[0:length-1]) * m
  12. elif (lastchar == 'm') or (lastchar == 'M'):
  13. m = 1024*1024
  14. nsize = int(size[0:length-1]) * m
  15. elif (lastchar == 'g') or (lastchar == 'G'):
  16. m = 1024*1024*1024
  17. nsize = int(size[0:length-1]) * m
  18. else:
  19. nsize = int(size)
  20. return nsize
  21. #
  22. # main program
  23. #
  24. parser = OptionParser()
  25. parser.add_option("-s", "--seed", default=0, help="the random seed",
  26. action="store", type="int", dest="seed")
  27. parser.add_option("-A", "--addresses", default="-1",
  28. help="a set of comma-separated pages to access; -1 means randomly generate",
  29. action="store", type="string", dest="addresses")
  30. parser.add_option("-a", "--asize", default="1k",
  31. help="address space size (e.g., 16, 64k, 32m, 1g)",
  32. action="store", type="string", dest="asize")
  33. parser.add_option("-p", "--physmem", default="16k",
  34. help="physical memory size (e.g., 16, 64k, 32m, 1g)",
  35. action="store", type="string", dest="psize")
  36. parser.add_option("-n", "--numaddrs", default=5,
  37. help="number of virtual addresses to generate",
  38. action="store", type="int", dest="num")
  39. parser.add_option("-b", "--b0", default="-1",
  40. help="value of segment 0 base register",
  41. action="store", type="string", dest="base0")
  42. parser.add_option("-l", "--l0", default="-1",
  43. help="value of segment 0 limit register",
  44. action="store", type="string", dest="len0")
  45. parser.add_option("-B", "--b1", default="-1",
  46. help="value of segment 1 base register",
  47. action="store", type="string", dest="base1")
  48. parser.add_option("-L", "--l1", default="-1",
  49. help="value of segment 1 limit register",
  50. action="store", type="string", dest="len1")
  51. parser.add_option("-c", help="compute answers for me",
  52. action="store_true", default=False, dest="solve")
  53. (options, args) = parser.parse_args()
  54. print "ARG seed", options.seed
  55. print "ARG address space size", options.asize
  56. print "ARG phys mem size", options.psize
  57. print ""
  58. random.seed(options.seed)
  59. asize = convert(options.asize)
  60. psize = convert(options.psize)
  61. addresses = str(options.addresses)
  62. if psize <= 1:
  63. print 'Error: must specify a non-zero physical memory size.'
  64. exit(1)
  65. if asize == 0:
  66. print 'Error: must specify a non-zero address-space size.'
  67. exit(1)
  68. if psize <= asize:
  69. print 'Error: physical memory size must be GREATER than address space size (for this simulation)'
  70. exit(1)
  71. #
  72. # need to generate base, bounds for segment registers
  73. #
  74. len0 = convert(options.len0)
  75. len1 = convert(options.len1)
  76. base0 = convert(options.base0)
  77. base1 = convert(options.base1)
  78. if len0 == -1:
  79. len0 = int(asize/4.0 + (asize/4.0 * random.random()))
  80. if len1 == -1:
  81. len1 = int(asize/4.0 + (asize/4.0 * random.random()))
  82. # now have to find room for them
  83. if base0 == -1:
  84. done = 0
  85. while done == 0:
  86. base0 = int(psize * random.random())
  87. if (base0 + len0) < psize:
  88. done = 1
  89. # internally, base1 points to the lower address, and base1+len1 the higher address
  90. # (this differs from what the user would pass in, for example)
  91. if base1 == -1:
  92. done = 0
  93. while done == 0:
  94. base1 = int(psize * random.random())
  95. if (base1 + len1) < psize:
  96. if (base1 > (base0 + len0)) or ((base1 + len1) < base0):
  97. done = 1
  98. else:
  99. base1 = base1 - len1
  100. if len0 > asize/2.0 or len1 > asize/2.0:
  101. print 'Error: length register is too large for this address space'
  102. exit(1)
  103. print 'Segment register information:'
  104. print ''
  105. print ' Segment 0 base (grows positive) : 0x%08x (decimal %d)' % (base0, base0)
  106. print ' Segment 0 limit : %d' % (len0)
  107. print ''
  108. print ' Segment 1 base (grows negative) : 0x%08x (decimal %d)' % (base1+len1, base1+len1)
  109. print ' Segment 1 limit : %d' % (len1)
  110. print ''
  111. nbase1 = base1 + len1
  112. if (len0 + base0) > (base1) and (base1 > base0):
  113. print 'Error: segments overlap in physical memory'
  114. exit(1)
  115. addrList = []
  116. if addresses == '-1':
  117. # need to generate addresses
  118. for i in range(0, options.num):
  119. n = int(asize * random.random())
  120. addrList.append(n)
  121. else:
  122. addrList = addresses.split(',')
  123. #
  124. # now, need to generate virtual address trace
  125. #
  126. print 'Virtual Address Trace'
  127. i = 0
  128. for vStr in addrList:
  129. # vaddr = int(asize * random.random())
  130. vaddr = int(vStr)
  131. if vaddr < 0 or vaddr >= asize:
  132. print 'Error: virtual address %d cannot be generated in an address space of size %d' % (vaddr, asize)
  133. exit(1)
  134. if options.solve == False:
  135. print ' VA %2d: 0x%08x (decimal: %4d) --> PA or segmentation violation?' % (i, vaddr, vaddr)
  136. else:
  137. paddr = 0
  138. if (vaddr >= (asize / 2)):
  139. # seg 1
  140. paddr = nbase1 + (vaddr - asize)
  141. if paddr < base1:
  142. print ' VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION (SEG1)' % (i, vaddr, vaddr)
  143. else:
  144. print ' VA %2d: 0x%08x (decimal: %4d) --> VALID in SEG1: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr)
  145. else:
  146. # seg 0
  147. if (vaddr >= len0):
  148. print ' VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION (SEG0)' % (i, vaddr, vaddr)
  149. else:
  150. paddr = vaddr + base0
  151. print ' VA %2d: 0x%08x (decimal: %4d) --> VALID in SEG0: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr)
  152. i += 1
  153. print ''
  154. if options.solve == False:
  155. print 'For each virtual address, either write down the physical address it translates to'
  156. print 'OR write down that it is an out-of-bounds address (a segmentation violation). For'
  157. print 'this problem, you should assume a simple address space with two segments: the top'
  158. print 'bit of the virtual address can thus be used to check whether the virtual address'
  159. print 'is in segment 0 (topbit=0) or segment 1 (topbit=1). Note that the base/limit pairs'
  160. print 'given to you grow in different directions, depending on the segment, i.e., segment 0'
  161. print 'grows in the positive direction, whereas segment 1 in the negative. '
  162. print ''