何故かホストが凍るようになった
ちょっとINT 13h AH=02h(Disk Read)のリクエストをダンプして眺めてみたいって思って、こんなStubを作って試してみたら…
static int int13_handler(struct vmctx *ctx, int vcpu, int intno) { uint64_t rax, rbx, rcx, rdx, es_base, rflags; uint32_t es_limit, es_access; uint16_t bx; uint8_t al, ah, cl, ch, dl, dh; int error; if ((error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &rax)) != 0) goto done; if ((error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBX, &rbx)) != 0) goto done; if ((error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RCX, &rcx)) != 0) goto done; if ((error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDX, &rdx)) != 0) goto done; if ((error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, &rflags)) != 0) goto done; if ((error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_ES, &es_base, &es_limit, &es_access)) != 0) goto done; al = (uint8_t)rax; ah = (uint8_t)(rax >> 8); bx = (uint16_t)rbx; cl = (uint8_t)rcx; ch = (uint8_t)(rcx >> 8); printf("%s rax=%lx ah=%x al=%x rbx=%lx bx=%x rcx=%lx ch=%x cl=%x rdx=%lx dh=%x dl=%x es_base=%lx es_limit=%x es_access=%x\n", __func__, rax, ah, al, rbx, bx, rcx, ch, cl, rdx, dh, dl, es_base, es_limit, es_access); switch (ah) { case 0x02: break; case 0x41: rflags |= 0x1; error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, rflags); break; default: fprintf(stderr, "Not implemented BIOS call int=%x ah=%x\n", intno, ah); } done: return (error); }
こんな、MBRからのエラーメッセージを画面に表示した直後に凍りつくホストOS。
Error loading operating system
何故に…。
確かに、MBRはエラーを起こした事をコンソールに表示した後、リセット待ちのループに入っているのだが、ゲストがそういう挙動をしていても問題なくホスト側は動けるような仕組みになっているし、このループがフリーズの原因ではないと思うのだが…
# # Output an ASCIZ string to the console via the BIOS. # putstr.0: movw $0x7,%bx # Page:attribute movb $0xe,%ah # BIOS: Display int $0x10 # character putstr: lodsb # Get character testb %al,%al # End of string? jnz putstr.0 # No putstr.1: jmp putstr.1 # Await reset
じゃ、何で固まってるんだろ。
試しにこのループの間にint $0x10とか挟んでみても変化なくて一層首を傾げてる。
俺、何間違えたんだろ…。
今日はこの辺のお話でした:
svn diff -rr238930:r238974 https://socsvn.freebsd.org/socsvn/soc2012/syuu/bhyve-bios