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. 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 --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 & /count.sh &
/kgdb.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 break __x64_sys_write
c continue
c continue
c continue
c continue
.... ....
And now you can count from GDB! And now you can count from GDB!
@@ -1873,9 +1907,11 @@ See also:
=== KGDB ARM === 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 Entering kdb (current=0xf8ce07d3, pid 1) due to Keyboard Entry
@@ -1893,6 +1929,8 @@ Ignoring packet error, continuing...
Remote replied unexpectedly to 'vMustReplyEmpty': timeout 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 === KGDB kernel modules
In QEMU: In QEMU:

View File

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

View File

@@ -117,6 +117,7 @@ scons \
if "$baremetal"; then if "$baremetal"; then
pkgs="${pkgs} \ pkgs="${pkgs} \
docbook2x \ docbook2x \
libtool-bin \
" "
fi fi
command -v apt-get >/dev/null 2>&1 || { 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 += ' {}=/eval_base64.sh'.format(initarg)
kernel_cli_after_dash += ' lkmc_eval="{}"'.format(common.base64_encode(args.eval)) kernel_cli_after_dash += ' lkmc_eval="{}"'.format(common.base64_encode(args.eval))
if not args.graphic: if not args.graphic:
if args.arch == 'x86_64':
kernel_cli += ' console=ttyS0'
else:
kernel_cli += ' console=ttyAMA0'
extra_qemu_args.append('-nographic') 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: if kernel_cli_after_dash:
kernel_cli += " -{}".format(kernel_cli_after_dash) kernel_cli += " -{}".format(kernel_cli_after_dash)
extra_env = {} extra_env = {}
@@ -161,12 +172,12 @@ def main(args, extra_args=None):
if args.arch == 'x86_64': if args.arch == 'x86_64':
if args.kvm: if args.kvm:
cmd.extend(['--cpu-type', 'X86KvmCPU']) cmd.extend(['--cpu-type', 'X86KvmCPU'])
cmd.extend(['--command-line', 'earlyprintk=ttyS0 lpj=7999923 root=/dev/sda {}'.format(kernel_cli)]) cmd.extend(['--command-line', 'earlyprintk={} lpj=7999923 root=/dev/sda {}'.format(console, kernel_cli)])
elif args.arch == 'arm' or args.arch == 'aarch64': elif common.is_arm:
# TODO why is it mandatory to pass mem= here? Not true for QEMU. # 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? # Anything smaller than physical blows up as expected, but why can't it auto-detect the right value?
cmd.extend([ 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)), '--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, '--machine-type', common.machine,
'--param', 'system.panic_on_panic = True', '--param', 'system.panic_on_panic = True',
@@ -295,17 +306,13 @@ def main(args, extra_args=None):
else: else:
virtio_gpu_pci = ['-device', 'virtio-gpu-pci'] virtio_gpu_pci = ['-device', 'virtio-gpu-pci']
if args.arch == 'x86_64': if args.arch == 'x86_64':
if args.kgdb:
kernel_cli += ' kgdboc=ttyS1,115200'
append = ['-append', '{} nopat {}'.format(root, kernel_cli)] append = ['-append', '{} nopat {}'.format(root, kernel_cli)]
cmd.extend([ cmd.extend([
'-M', common.machine, '-M', common.machine,
'-device', 'edu', '-device', 'edu',
]) ])
elif args.arch == 'arm' or args.arch == 'aarch64': elif common.is_arm:
extra_emulator_args.append('-semihosting') extra_emulator_args.append('-semihosting')
if args.kgdb:
kernel_cli += ' kgdboc=ttyAMA0,115200'
if args.arch == 'arm': if args.arch == 'arm':
cpu = 'cortex-a15' cpu = 'cortex-a15'
else: else: