Bug #141
GRUB payload hangs in HP Elitebooks
Status: | New | Start date: | 09/19/2017 | |
---|---|---|---|---|
Priority: | Normal | Due date: | ||
Assignee: | Iru Cai | % Done: | 0% | |
Category: | - | |||
Target version: | - |
Description
There may be some problem when initializing the keyboard controller, but SeaBIOS payload works fine. Using GRUB payload directly or chainload GRUB payload with SeaBIOS will both hang the system.
I modified GRUB and find it hangs in set_scancodes(void), when calling the first write_mode. After grub_outb (mode, KEYBOARD_REG_DATA);
, the keyboard_controller_wait_until_ready()
function goes to an infinite loop.
write_mode (int mode) { unsigned i; for (i = 0; i < GRUB_AT_TRIES; i++) { grub_uint8_t ack; keyboard_controller_wait_until_ready (); grub_outb (0xf0, KEYBOARD_REG_DATA); keyboard_controller_wait_until_ready (); grub_outb (mode, KEYBOARD_REG_DATA); keyboard_controller_wait_until_ready (); ack = wait_ack (); if (ack == GRUB_AT_NACK) continue; if (ack == GRUB_AT_ACK) break; return 0; } return (i != GRUB_AT_TRIES); }
History
#1 Updated by Paul Menzel 10 months ago
I guess Linux works fine too. What about libpayload based payloads?
Can you please attach the debug logs of SeaBIOS (yes not GRUB) with debug log level.
#2 Updated by Iru Cai 10 months ago
- File seabios.log
added
I've just made a SeaBIOS log (verbosity 7).
#3 Updated by Paul Menzel 10 months ago
Thank you. SeaBIOS does:
$ grep 7fee4000 seabios.log
/7fee4000\ Start thread
|7fee4000| i8042_flush
|7fee4000| i8042_command cmd=ad
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=a7
|7fee4000| i8042_wait_write
|7fee4000| i8042_flush
|7fee4000| i8042_command cmd=1aa
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_read
|7fee4000| i8042 param=55
|7fee4000| i8042_command cmd=1ab
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_read
|7fee4000| i8042 param=0
|7fee4000| ps2_command aux=0 cmd=1ff
|7fee4000| i8042 ctr old=30 new=30
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_sendbyte aux=0 cmd=ff
|7fee4000| i8042_kbd_write c=255
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| ps2 read aa
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_command aux=0 cmd=f5
|7fee4000| i8042 ctr old=30 new=30
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_sendbyte aux=0 cmd=f5
|7fee4000| i8042_kbd_write c=245
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_command aux=0 cmd=10f0
|7fee4000| i8042 ctr old=30 new=30
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_sendbyte aux=0 cmd=f0
|7fee4000| i8042_kbd_write c=240
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| ps2_sendbyte aux=0 cmd=2
|7fee4000| i8042_kbd_write c=2
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_command aux=0 cmd=f4
|7fee4000| i8042 ctr old=61 new=70
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_sendbyte aux=0 cmd=f4
|7fee4000| i8042_kbd_write c=244
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| PS2 keyboard initialized
\7fee4000/ End thread
Now, one has to find out, what GRUB is doing.
As you found out, that it’s hanging below
static void
keyboard_controller_wait_until_ready (void)
{
/* 50 us would be enough but our current time resolution is 1ms. */
grub_millisleep (1);
while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)));
}
What about adding a timeout there too?
#define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02)