Browse Source

[romprefix] If we hook INT 19, prompt before attempting boot

On non-BBS systems we hook INT 19, since there is no other way we can
guarantee gaining control of the flow of execution.  If we end up
doing this, prompt the user before attempting boot, since forcibly
capturing INT 19 is rather antisocial.
tags/v0.9.4
Michael Brown 15 years ago
parent
commit
9d44a06188
1 changed files with 107 additions and 44 deletions
  1. 107
    44
      src/arch/i386/prefix/romprefix.S

+ 107
- 44
src/arch/i386/prefix/romprefix.S View File

145
 	cld
145
 	cld
146
 	pushw	%cs
146
 	pushw	%cs
147
 	popw	%ds
147
 	popw	%ds
148
-	pushw	$0x40
149
-	popw	%fs
150
 
148
 
151
 	/* Shuffle some registers around.  We need %di available for
149
 	/* Shuffle some registers around.  We need %di available for
152
 	 * the print_xxx functions, and in a register that's
150
 	 * the print_xxx functions, and in a register that's
317
 	movw	$init_message_prompt, %si
315
 	movw	$init_message_prompt, %si
318
 	xorw	%di, %di
316
 	xorw	%di, %di
319
 	call	print_message
317
 	call	print_message
320
-	/* Empty the keyboard buffer before waiting for input */
321
-empty_keyboard_buffer:
322
-	movb	$0x01, %ah
323
-	int	$0x16
324
-	jz	1f
325
-	xorw	%ax, %ax
326
-	int	$0x16
327
-	jmp	empty_keyboard_buffer
328
-1:	/* Wait for up to 3s for a key press */
329
-	movw	$(18 * 3), %cx	/* Approx 3s worth of timer ticks */
330
-wait_for_key:
331
-	decw	%cx
332
-	jz	no_key_pressed
333
-	/* Wait for timer tick to be updated */
334
-	movl	%fs:(0x6c), %eax
335
-1:	pushf
336
-	sti
337
-	hlt
338
-	popf
339
-	cmpl	%fs:(0x6c), %eax
340
-	je	1b
341
-	/* Check to see if a key was pressed */
342
-	movb	$0x01, %ah
343
-	int	$0x16
344
-	jz	wait_for_key
345
-	/* Check to see if key was Ctrl-B */
346
-	cmpb	$0x02, %al
347
-	je	1f
348
-	/* Key was not Ctrl-B: remove from buffer and stop waiting */
349
-	xorw	%ax, %ax
350
-	int	$0x16
351
-	jmp	no_key_pressed
352
-1:	/* Key was Ctrl-B: leave in keyboard buffer and invoke gPXE.
353
-	 * The keypress will be picked up by the initial shell
354
-	 * prompt, and we will drop into a shell.
318
+	/* Wait for Ctrl-B */
319
+	movw	$0xff02, %bx
320
+	call	wait_for_key
321
+	jnz	1f
322
+	/* Ctrl-B was pressed: invoke gPXE.  The keypress will be
323
+	 * picked up by the initial shell prompt, and we will drop
324
+	 * into a shell.
355
 	 */
325
 	 */
356
 	pushw	%cs
326
 	pushw	%cs
357
 	call	exec
327
 	call	exec
358
-no_key_pressed:
359
-
328
+1:
360
 	/* Print blank lines to terminate messages */
329
 	/* Print blank lines to terminate messages */
361
 	movw	$init_message_end, %si
330
 	movw	$init_message_end, %si
362
 	xorw	%di, %di
331
 	xorw	%di, %di
436
 /* INT19 entry point
405
 /* INT19 entry point
437
  *
406
  *
438
  * Called via the hooked INT 19 if we detected a non-PnP BIOS.  We
407
  * Called via the hooked INT 19 if we detected a non-PnP BIOS.  We
439
- * attempt to return via the original INT 19 vector (if we were able to
440
- * store it).
408
+ * attempt to return via the original INT 19 vector (if we were able
409
+ * to store it).
441
  */
410
  */
442
 int19_entry:
411
 int19_entry:
443
 	pushw	%cs
412
 	pushw	%cs
413
+	popw	%ds
414
+	/* Prompt user to press B to boot */
415
+	movw	$int19_message_prompt, %si
416
+	xorw	%di, %di
417
+	call	print_message
418
+	movw	$prodstr, %si
419
+	call	print_message
420
+	movw	$int19_message_dots, %si
421
+	call	print_message
422
+	movw	$0xdf42, %bx
423
+	call	wait_for_key
424
+	jnz	1f
425
+	/* Leave keypress in buffer and start gPXE.  The keypress will
426
+	 * cause the usual initial Ctrl-B prompt to be skipped.
427
+	 */
428
+	pushw	%cs
444
 	call	exec
429
 	call	exec
430
+1:	/* Print blank lines to terminate messages */
431
+	movw	$int19_message_end, %si
432
+	xorw	%di, %di
433
+	call	print_message
434
+	/* Try to call original INT 19 vector */
445
 	movl	%cs:orig_int19, %eax
435
 	movl	%cs:orig_int19, %eax
446
 	testl	%eax, %eax
436
 	testl	%eax, %eax
447
-	je	1f
448
-	/* Chain to original INT 19 vector */
437
+	je	2f
449
 	ljmp	*%cs:orig_int19
438
 	ljmp	*%cs:orig_int19
450
-1:	/* No chained vector: issue INT 18 as a last resort */
439
+2:	/* No chained vector: issue INT 18 as a last resort */
451
 	int	$0x18
440
 	int	$0x18
452
 	.size	int19_entry, . - int19_entry
441
 	.size	int19_entry, . - int19_entry
453
 orig_int19:
442
 orig_int19:
454
 	.long	0
443
 	.long	0
455
 	.size	orig_int19, . - orig_int19
444
 	.size	orig_int19, . - orig_int19
456
 
445
 
446
+int19_message_prompt:
447
+	.asciz	"Press B to boot from "
448
+	.size	int19_message_prompt, . - int19_message_prompt
449
+int19_message_dots:
450
+	.asciz	"..."
451
+	.size	int19_message_dots, . - int19_message_dots
452
+int19_message_end:
453
+	.asciz	"\n\n\n"
454
+	.size	int19_message_end, . - int19_message_end
455
+	
457
 /* Execute as a boot device
456
 /* Execute as a boot device
458
  *
457
  *
459
  */
458
  */
560
 	popl	%esi
559
 	popl	%esi
561
 	lret
560
 	lret
562
 	.size undiloader, . - undiloader
561
 	.size undiloader, . - undiloader
562
+
563
+/* Wait for key press specified by %bl (masked by %bh)
564
+ *
565
+ * Used by init and INT19 code when prompting user.  If the specified
566
+ * key is pressed, it is left in the keyboard buffer.
567
+ *
568
+ * Returns with ZF set iff specified key is pressed.
569
+ */
570
+wait_for_key:
571
+	/* Preserve registers */
572
+	pushw	%cx
573
+	pushw	%ax
574
+1:	/* Empty the keyboard buffer before waiting for input */
575
+	movb	$0x01, %ah
576
+	int	$0x16
577
+	jz	2f
578
+	xorw	%ax, %ax
579
+	int	$0x16
580
+	jmp	1b
581
+2:	/* Wait for up to 5s for a key press */
582
+	movw	$(18 * 5), %cx	/* Approx 5s worth of timer ticks */
583
+3:	decw	%cx
584
+	js	99f		/* Exit with ZF clear */
585
+	/* Wait for timer tick to be updated */
586
+	call	wait_for_tick
587
+	/* Check to see if a key was pressed */
588
+	movb	$0x01, %ah
589
+	int	$0x16
590
+	jz	3b
591
+	/* Check to see if key was the specified key */
592
+	andb	%bh, %al
593
+	cmpb	%al, %bl
594
+	je	99f		/* Exit with ZF set */
595
+	/* Not the specified key: remove from buffer and stop waiting */
596
+	pushfw
597
+	xorw	%ax, %ax
598
+	int	$0x16
599
+	popfw			/* Exit with ZF clear */
600
+99:	/* Restore registers and return */
601
+	popw	%ax
602
+	popw	%cx
603
+	ret
604
+	.size wait_for_key, . - wait_for_key
605
+
606
+/* Wait for timer tick
607
+ *
608
+ * Used by wait_for_key
609
+ */
610
+wait_for_tick:
611
+	pushl	%eax
612
+	pushw	%fs
613
+	movw	$0x40, %ax
614
+	movw	%ax, %fs
615
+	movl	%fs:(0x6c), %eax
616
+1:	pushf
617
+	sti
618
+	hlt
619
+	popf
620
+	cmpl	%fs:(0x6c), %eax
621
+	je	1b
622
+	popw	%fs
623
+	popl	%eax
624
+	ret
625
+	.size wait_for_tick, . - wait_for_tick

Loading…
Cancel
Save