run 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #!/usr/bin/env bash
  2. set -eu
  3. . common
  4. set -- ${cli_run:-} "$@"
  5. # CLI handling.
  6. cpus=1
  7. debug_vm=
  8. debug=false
  9. kgdb=false
  10. kvm=false
  11. # norandmaps: Don't use address space randomization. Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space.
  12. # nokaslr:
  13. # - https://unix.stackexchange.com/questions/397939/turning-off-kaslr-to-debug-linux-kernel-using-qemu-and-gdb
  14. # - https://stackoverflow.com/questions/44612822/unable-to-debug-kernel-with-qemu-gdb/49840927#49840927
  15. # Turned on by default since v4.12
  16. extra_append='console_msg_format=syslog nokaslr norandmaps printk.devkmsg=on printk.time=y'
  17. extra_append_after_dash=
  18. extra_flags=
  19. extra_flags_qemu=
  20. gem5=false
  21. gem5opts=
  22. lkmc_eval=
  23. initrd=false
  24. initramfs=false
  25. memory=256M
  26. nographic=true
  27. root=
  28. tmux=false
  29. tmux_args=
  30. # A dummy value that is already turned on by default and does not produce large output,
  31. # just to prevent QEMU from emitting a warning that '' is not valid.
  32. trace_enable=pr_manager_run
  33. vnc=
  34. while getopts a:c:DdE:e:F:f:G:ghIiKkm:T:U:uVx OPT; do
  35. case "$OPT" in
  36. a)
  37. arch="$OPTARG"
  38. ;;
  39. c)
  40. cpus="$OPTARG"
  41. ;;
  42. D)
  43. debug_vm="gdb -q -ex start --args \\
  44. "
  45. ;;
  46. d)
  47. debug=true
  48. extra_flags_qemu="$extra_flags_qemu -S \\
  49. "
  50. ;;
  51. E)
  52. lkmc_eval="$OPTARG"
  53. ;;
  54. e)
  55. extra_append="${extra_append} ${OPTARG}"
  56. ;;
  57. F)
  58. extra_append_after_dash="${extra_append_after_dash} lkmc_eval_base64=\"$(printf "${OPTARG}" | base64)\""
  59. ;;
  60. f)
  61. extra_append_after_dash="${extra_append_after_dash} ${OPTARG}"
  62. ;;
  63. G)
  64. gem5opts="$OPTARG \\
  65. "
  66. ;;
  67. g)
  68. gem5=true
  69. ;;
  70. h)
  71. cat build-usage.adoc 1>&2
  72. exit
  73. ;;
  74. I)
  75. initramfs=true
  76. ;;
  77. i)
  78. initrd=true
  79. ;;
  80. K)
  81. kvm=true
  82. ;;
  83. k)
  84. extra_append="$extra_append kgdbwait"
  85. # For those who want to try KDB.
  86. #extra_append="$extra_append kgdbwait kgdboc=kbd"
  87. extra_flags_qemu="$extra_flags_qemu -serial tcp::1234,server,nowait \\
  88. "
  89. kgdb=true
  90. ;;
  91. m)
  92. memory="$OPTARG"
  93. ;;
  94. T)
  95. trace_enable="$OPTARG"
  96. ;;
  97. U)
  98. tmux_args="$OPTARG"
  99. ;;
  100. u)
  101. tmux=true
  102. ;;
  103. x)
  104. nographic=false
  105. ;;
  106. V)
  107. vnc="-vnc :0 \\
  108. "
  109. ;;
  110. ?)
  111. exit 2
  112. ;;
  113. esac
  114. done
  115. shift "$(($OPTIND - 1))"
  116. extra_flags="$extra_flags $@"
  117. set_common_vars "$arch" "$gem5"
  118. images_dir="${buildroot_out_dir}/images"
  119. if "$debug" && "$kvm"; then
  120. echo 'error: -d and -K are incompatible' 1>&2
  121. exit 1
  122. fi
  123. if "$initrd" || "$initramfs"; then
  124. ramfs=true
  125. else
  126. ramfs=false
  127. fi
  128. if [ -n "$lkmc_eval" ]; then
  129. if "$ramfs"; then
  130. initarg="rdinit"
  131. else
  132. initarg="init"
  133. fi
  134. extra_append="${extra_append} ${initarg}=/eval_base64.sh"
  135. extra_append_after_dash="${extra_append_after_dash} lkmc_eval=\"$(printf "$lkmc_eval" | base64)\""
  136. fi
  137. if "$nographic"; then
  138. if [ "$arch" = x86_64 ]; then
  139. extra_append="${extra_append} console=ttyS0"
  140. fi
  141. extra_flags_qemu="${extra_flags_qemu} -nographic \\
  142. "
  143. fi
  144. if [ -n "$extra_append_after_dash" ]; then
  145. extra_append="${extra_append} - ${extra_append_after_dash}"
  146. fi
  147. if "$gem5"; then
  148. gem5_build_dir="${buildroot_out_dir}/build/gem5-1.0"
  149. gem5_src_dir="${gem5_build_dir}/gem5"
  150. memory="${memory}B"
  151. if [ "$arch" = x86_64 ]; then
  152. gem5_arch=X86
  153. else
  154. gem5_arch=ARM
  155. fi
  156. gem5_common="\
  157. M5_PATH='${gem5_build_dir}/system' \\
  158. ${debug_vm} \
  159. '${gem5_src_dir}/build/${gem5_arch}/gem5.opt' \\
  160. --debug-file=trace.txt \\
  161. ${gem5opts} \
  162. -d '${m5out_dir}' \\
  163. '${gem5_src_dir}/configs/example/fs.py' \\
  164. --disk-image='${images_dir}/rootfs.ext2' \\
  165. --kernel='${buildroot_out_dir}/build/linux-custom/vmlinux' \\
  166. --mem-size='${memory}' \\
  167. --num-cpus='${cpus}' \\
  168. --script='${readfile_file}' \\
  169. "
  170. if [ "$arch" = x86_64 ]; then
  171. if "$kvm"; then
  172. extra_flags="$extra_flags --cpu-type=X86KvmCPU"
  173. fi
  174. cmd="\
  175. ${gem5_common} \
  176. --command-line='earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/sda ${extra_append}' \\
  177. ${extra_flags} \
  178. "
  179. elif [ "$arch" = arm ] || [ "$arch" = aarch64 ]; then
  180. # TODO why is it mandatory to pass mem= here? Not true for QEMU.
  181. # Anything smaller than physical blows up as expected, but why can't it auto-detect the right value?
  182. cmd="${gem5_common} \
  183. --command-line='earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem=${memory} root=/dev/sda ${extra_append}' \\
  184. --dtb-file='${gem5_src_dir}/system/arm/dt/$([ "$arch" = arm ] && echo "armv7_gem5_v1_${cpus}cpu" || echo "armv8_gem5_v1_${cpus}cpu").dtb' \\
  185. --machine-type=VExpress_GEM5_V1 \\
  186. ${extra_flags} \
  187. "
  188. fi
  189. else
  190. if "$kvm"; then
  191. extra_flags="${extra_flags} -enable-kvm"
  192. fi
  193. extra_flags="${extra_flags_qemu} ${extra_flags}"
  194. qemu_common="\
  195. ${debug_vm} \
  196. '${buildroot_out_dir}/host/usr/bin/qemu-system-${arch}' \\
  197. -device rtl8139,netdev=net0 \\
  198. -gdb tcp::1234 \\
  199. -m '${memory}' \\
  200. -serial mon:stdio \\
  201. -monitor telnet::45454,server,nowait \\
  202. -netdev user,hostfwd=tcp::45455-:45455,hostfwd=tcp::45456-:22,id=net0 \\
  203. -smp '${cpus}' \\
  204. -trace 'enable=${trace_enable},file=${qemu_out_dir}/trace.bin' \\
  205. -virtfs 'local,path=${p9_dir},mount_tag=host_scratch,security_model=mapped,id=host_scratch' \\
  206. -virtfs 'local,path=${buildroot_out_dir}/build,mount_tag=host_out,security_model=mapped,id=host_out' \\
  207. ${vnc}"
  208. if "$initrd"; then
  209. extra_flags="${extra_flags} -initrd '${images_dir}/rootfs.cpio' \\
  210. "
  211. fi
  212. if "$ramfs"; then
  213. # TODO why is this needed, and why any string works.
  214. root='root=/dev/anything'
  215. else
  216. if [ ! "$arch" = mips64 ]; then
  217. extra_flags="${extra_flags} -drive file='${images_dir}/rootfs.ext2.qcow2,if=virtio,format=qcow2' \\
  218. "
  219. root='root=/dev/vda'
  220. fi
  221. fi
  222. # The base QEMU commands are found under board/qemu/*/readme.tx
  223. case "$arch" in
  224. x86_64)
  225. if "$kgdb"; then
  226. extra_append="${extra_append} kgdboc=ttyS0,115200"
  227. fi
  228. cmd="\
  229. ${qemu_common} \
  230. -M pc \\
  231. -append '${root} nopat ${extra_append}' \\
  232. -device edu \\
  233. -device lkmc_pci_min \\
  234. -kernel '${images_dir}/bzImage' \\
  235. ${extra_flags} \
  236. "
  237. ;;
  238. arm)
  239. if "$kgdb"; then
  240. extra_append="${extra_append} kgdboc=ttyAMA0,115200"
  241. fi
  242. cmd="\
  243. ${qemu_common} \
  244. -M virt \\
  245. -append '${root} ${extra_append}' \\
  246. -cpu cortex-a15 \\
  247. -kernel '${images_dir}/zImage' \\
  248. ${extra_flags} \
  249. "
  250. ;;
  251. aarch64)
  252. if "$kgdb"; then
  253. extra_append="${extra_append} kgdboc=ttyAMA0,115200"
  254. fi
  255. cmd="\
  256. ${qemu_common} \
  257. -M virt \\
  258. -append '${root} ${extra_append}' \\
  259. -cpu cortex-a57 \\
  260. -kernel '${images_dir}/Image' \\
  261. ${extra_flags} \
  262. "
  263. ;;
  264. mips64)
  265. if ! "$ramfs"; then
  266. root='root=/dev/hda'
  267. extra_flags="${extra_flags} -drive file='${images_dir}/rootfs.ext2.qcow2,format=qcow2' \\
  268. "
  269. fi
  270. cmd="\
  271. ${qemu_common} \
  272. -M malta \\
  273. -append '${root} ${extra_append}' \\
  274. -cpu I6400 \\
  275. -kernel '${images_dir}/vmlinux' \\
  276. ${extra_flags} \
  277. "
  278. ;;
  279. esac
  280. fi
  281. if "$tmux"; then
  282. if "$gem5"; then
  283. eval "./tmu 'sleep 2;./gem5-shell'"
  284. elif "$debug"; then
  285. eval "./tmu ./rungdb -a '${arch}' ${tmux_args}"
  286. fi
  287. fi
  288. "${root_dir}/eeval" "$cmd" "${common_out_run_dir}/run.sh"