console: make awesome

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2018-10-31 22:00:02 +00:00
parent 65a103d6c1
commit e042a1b2ad
4 changed files with 74 additions and 25 deletions

View File

@@ -1832,34 +1832,68 @@ It is useless with QEMU since we already have full system visibility with `-gdb`
Cheaper than JTAG (free) and easier to setup (all you need is serial), but with less visibility as it depends on the kernel working, so e.g.: dies on panic, does not see boot sequence.
Usage:
First run the kernel with:
....
./run --kgdb
./run-gdb --kgdb
....
In GDB:
this passes the following options on the kernel CLI:
....
c
kgdbwait kgdboc=ttyS1,115200
....
In QEMU:
`kgdbwait` tells the kernel to wait for KGDB to connect.
So the kernel sets things up enough for KGDB to start working, and then boot pauses waiting for connection:
....
<6>[ 4.866050] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
<6>[ 4.893205] 00:05: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
<6>[ 4.916271] 00:06: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A
<6>[ 4.987771] KGDB: Registered I/O driver kgdboc
<2>[ 4.996053] KGDB: Waiting for connection from remote gdb...
Entering kdb (current=0x(____ptrval____), pid 1) on processor 0 due to Keyboard Entry
[0]kdb>
....
KGDB expects the connection at `ttyS1`, our second serial port after `ttyS0` which contains the terminal.
So now we can connect to the serial port with GDB:
....
./run-gdb --kgdb --no-continue
....
Once GDB connects, it is left inside the function `kgdb_breakpoint`.
So now we can set breakpoints and continue as usual.
For example, in GDB:
....
continue
....
Then in QEMU:
....
/count.sh &
/kgdb.sh
....
In GDB:
link:rootfs_overlay:kgdb.sh[] pauses the kernel for KGDB, and gives control back to GDB.
And now in GDB we do the usual:
....
b __x64_sys_write
c
c
c
c
break __x64_sys_write
continue
continue
continue
continue
....
And now you can count from GDB!
@@ -1873,9 +1907,11 @@ See also:
=== KGDB ARM
GDB not connecting to KGDB in ARM. Possibly linked to `-serial stdio`. See also: https://stackoverflow.com/questions/14155577/how-to-use-kgdb-on-arm
GDB not connecting to KGDB in `arm` and `aarch64`.
Main shell just falls on:
Main question: https://stackoverflow.com/questions/14155577/how-to-use-kgdb-on-arm
The main console just hangs on:
....
Entering kdb (current=0xf8ce07d3, pid 1) due to Keyboard Entry
@@ -1893,6 +1929,8 @@ Ignoring packet error, continuing...
Remote replied unexpectedly to 'vMustReplyEmpty': timeout
....
I wanted to try to and run run KGDB on a second serial to see if it makes a difference, but QEMU `-M virt` does not seem to support it: https://stackoverflow.com/questions/53080745/can-qemu-m-virt-on-arm-aarch64-have-multiple-serial-ttys-like-such-as-pl011-t
=== KGDB kernel modules
In QEMU:

View File

@@ -670,6 +670,7 @@ def setup(parser):
args.gem5_build_id = args.gem5_worktree
this_module.machine = args.machine
this_module.setup_dry_run_arguments(args)
this_module.is_arm = False
if args.arch == 'arm':
this_module.armv = 7
this_module.gem5_arch = 'ARM'
@@ -683,6 +684,7 @@ def setup(parser):
else:
if this_module.machine is None:
this_module.machine = 'virt'
this_module.is_arm = True
elif args.arch == 'aarch64':
this_module.armv = 8
this_module.gem5_arch = 'ARM'
@@ -696,6 +698,7 @@ def setup(parser):
else:
if this_module.machine is None:
this_module.machine = 'virt'
this_module.is_arm = True
elif args.arch == 'x86_64':
this_module.crosstool_ng_toolchain_prefix = 'x86_64-unknown-elf'
this_module.gem5_arch = 'X86'

View File

@@ -117,6 +117,7 @@ scons \
if "$baremetal"; then
pkgs="${pkgs} \
docbook2x \
libtool-bin \
"
fi
command -v apt-get >/dev/null 2>&1 || {

31
run
View File

@@ -81,11 +81,22 @@ def main(args, extra_args=None):
kernel_cli += ' {}=/eval_base64.sh'.format(initarg)
kernel_cli_after_dash += ' lkmc_eval="{}"'.format(common.base64_encode(args.eval))
if not args.graphic:
if args.arch == 'x86_64':
kernel_cli += ' console=ttyS0'
else:
kernel_cli += ' console=ttyAMA0'
extra_qemu_args.append('-nographic')
console = None
console_type = None
console_count = 0
if args.arch == 'x86_64':
console_type = 'ttyS'
elif common.is_arm:
console_type = 'ttyAMA'
console = '{}{}'.format(console_type, console_count)
if not (args.arch == 'x86_64' and args.graphic):
console_count += 1
kernel_cli += ' console={}'.format(console)
extra_console = '{}{}'.format(console_type, console_count)
console_count += 1
if args.kgdb:
kernel_cli += ' kgdboc={},115200'.format(console)
if kernel_cli_after_dash:
kernel_cli += " -{}".format(kernel_cli_after_dash)
extra_env = {}
@@ -161,12 +172,12 @@ def main(args, extra_args=None):
if args.arch == 'x86_64':
if args.kvm:
cmd.extend(['--cpu-type', 'X86KvmCPU'])
cmd.extend(['--command-line', 'earlyprintk=ttyS0 lpj=7999923 root=/dev/sda {}'.format(kernel_cli)])
elif args.arch == 'arm' or args.arch == 'aarch64':
cmd.extend(['--command-line', 'earlyprintk={} lpj=7999923 root=/dev/sda {}'.format(console, kernel_cli)])
elif common.is_arm:
# TODO why is it mandatory to pass mem= here? Not true for QEMU.
# Anything smaller than physical blows up as expected, but why can't it auto-detect the right value?
cmd.extend([
'--command-line', 'earlyprintk=pl011,0x1c090000 console=ttyAMA0 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli),
'--command-line', 'earlyprintk=pl011,0x1c090000 lpj=19988480 rw loglevel=8 mem={} root=/dev/sda {}'.format(memory, kernel_cli),
'--dtb-filename', os.path.join(common.gem5_system_dir, 'arm', 'dt', 'armv{}_gem5_v1_{}cpu.dtb'.format(common.armv, args.cpus)),
'--machine-type', common.machine,
'--param', 'system.panic_on_panic = True',
@@ -295,17 +306,13 @@ def main(args, extra_args=None):
else:
virtio_gpu_pci = ['-device', 'virtio-gpu-pci']
if args.arch == 'x86_64':
if args.kgdb:
kernel_cli += ' kgdboc=ttyS1,115200'
append = ['-append', '{} nopat {}'.format(root, kernel_cli)]
cmd.extend([
'-M', common.machine,
'-device', 'edu',
])
elif args.arch == 'arm' or args.arch == 'aarch64':
elif common.is_arm:
extra_emulator_args.append('-semihosting')
if args.kgdb:
kernel_cli += ' kgdboc=ttyAMA0,115200'
if args.arch == 'arm':
cpu = 'cortex-a15'
else: