From c6ae575e58da5c9788185722d073227519ab2b97 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 20 Jun 2014 19:07:23 +0100 Subject: ranchu: Create console and ADB ports automatically On startup, start listening on the console and ADB ports automatically, using the same "start at 5554 and work up until we find a pair of ports which we can listen on" algorithm as the classic emulator. Signed-off-by: Peter Maydell --- hw/arm/ranchu.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/hw/arm/ranchu.c b/hw/arm/ranchu.c index be2dbfcc5d..a79a69fb76 100644 --- a/hw/arm/ranchu.c +++ b/hw/arm/ranchu.c @@ -35,6 +35,17 @@ #include "exec/address-spaces.h" #include "qemu/bitops.h" #include "qemu/error-report.h" +#include "qemu/config-file.h" +#include "sysemu/char.h" +#include "monitor/monitor.h" +#include "hw/misc/android_pipe.h" + +/* Maximum number of emulators that can run at once (affects how + * far through the TCP port space from 5554 we will scan to find + * a pair of ports we can listen on) + */ +#define MAX_ANDROID_EMULATORS 64 +#define ANDROID_CONSOLE_BASEPORT 5554 #define NUM_VIRTIO_TRANSPORTS 32 @@ -392,6 +403,73 @@ static void *ranchu_dtb(const struct arm_boot_info *binfo, int *fdt_size) return board->fdt; } +static CharDriverState *try_to_create_console_chardev(int portno) +{ + /* Try to create the chardev for the Android console on the specified port. + * This is equivalent to the command line options + * -chardev socket,id=monitor,host=127.0.0.1,port=NNN,server,nowait,telnet + + * -mon chardev=monitor,mode=android-console + * Return true on success, false on failure (presumably port-in-use). + */ + Error *err = NULL; + CharDriverState *chr; + QemuOpts *opts; + const char *chardev_opts = + "socket,id=private-chardev-for-android-monitor," + "host=127.0.0.1,server,nowait,telnet"; + + opts = qemu_opts_parse(qemu_find_opts("chardev"), chardev_opts, 1); + assert(opts); + qemu_opt_set_number(opts, "port", portno); + chr = qemu_chr_new_from_opts(opts, NULL, &err); + if (err) { + /* Assume this was port-in-use */ + qemu_opts_del(opts); + error_free(err); + return NULL; + } + + qemu_chr_fe_claim_no_fail(chr); + return chr; +} + +static void initialize_console_and_adb(void) +{ + /* Initialize the console and ADB, which must listen on two + * consecutive TCP ports starting from 5555 and working up until + * we manage to open both connections. + */ + int baseport = ANDROID_CONSOLE_BASEPORT; + int tries = MAX_ANDROID_EMULATORS; + CharDriverState *chr; + + for (; tries > 0; tries--, baseport += 2) { + chr = try_to_create_console_chardev(baseport); + if (!chr) { + continue; + } + + if (!adb_server_init(baseport + 1)) { + qemu_chr_delete(chr); + chr = NULL; + continue; + } + + /* Confirmed we have both ports, now we can create the console itself. + * This is equivalent to + * "-mon chardev=private-chardev,mode=android-console" + */ + monitor_init(chr, MONITOR_ANDROID_CONSOLE | MONITOR_USE_READLINE); + + printf("console on port %d, ADB on port %d\n", baseport, baseport + 1); + return; + } + error_report("it seems too many emulator instances are running " + "on this machine. Aborting\n"); + exit(1); +} + static void ranchu_init(QEMUMachineInitArgs *args) { qemu_irq pic[NUM_IRQS]; @@ -470,6 +548,11 @@ static void ranchu_init(QEMUMachineInitArgs *args) */ create_virtio_devices(vbi, pic); + /* Initialize the Android console and adb connection + * (must be done after the pipe has been realized). + */ + initialize_console_and_adb(); + vbi->bootinfo.ram_size = args->ram_size; vbi->bootinfo.kernel_filename = args->kernel_filename; vbi->bootinfo.kernel_cmdline = args->kernel_cmdline; -- cgit v1.2.3