OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. |
| 6 |
| 7 """Makes changes to mounted Chromium OS image to allow it to run with VMs |
| 8 |
| 9 This script changes two files within the Chromium OS image to let the image |
| 10 work with VMs, particularly QEMU |
| 11 |
| 12 Currently this script does the following, |
| 13 1.) Modify the post install script to remove EFI fixup section; the VM's we |
| 14 support don't have EFI support anyway and this section of the script needs |
| 15 access to the actual device drives |
| 16 |
| 17 2.) For QEMU/KVM, we change the xorg.conf to remove mouse support and instead |
| 18 change it to complete tablet support. This is done to provide better mouse |
| 19 response in the VM since tablets work of absolute coordinates while the mouse |
| 20 works of relative. In a screen that doesn't support a mouse grab (e.g., VNC), |
| 21 relative coordinates can cause the mouse to be flaky |
| 22 |
| 23 """ |
| 24 |
| 25 from optparse import OptionParser |
| 26 import os |
| 27 import stat |
| 28 import sys |
| 29 |
| 30 USAGE = "usage: %prog --mounted_dir=directory --for_qemu=[true]" |
| 31 |
| 32 POST_INST_IN_FILENAME = 'usr/sbin/chromeos-postinst' |
| 33 POST_INST_OUT_FILENAME = 'postinst_vm' |
| 34 XORG_CONF_FILENAME = os.path.join('etc', 'X11', 'xorg.conf') |
| 35 |
| 36 EFI_CODE_MARKER_START = r'echo "Updating grub target for EFI BIOS"' |
| 37 EFI_CODE_MARKER_END = \ |
| 38 r"""gpt -S boot -i $NEW_PART_NUM -b /tmp/oldpmbr.bin ${ROOT_DEV} 2>&1 |
| 39 fi |
| 40 else""" |
| 41 |
| 42 INPUT_SECTION_MARKER = r'Section "InputDevice"' |
| 43 SECTION_END_MARKER = r'EndSection' |
| 44 |
| 45 MOUSE_SECTION_IDENTIFIERS = [] |
| 46 MOUSE_SECTION_IDENTIFIERS += ['Identifier "Mouse'] |
| 47 MOUSE_SECTION_IDENTIFIERS += ['Identifier "USBMouse'] |
| 48 |
| 49 REPLACE_USB_MOUSE_PAIR = ('InputDevice "USBMouse" "AlwaysCore"', |
| 50 '') |
| 51 |
| 52 |
| 53 TABLET_DEVICE_CONFIG = """ |
| 54 Section "InputDevice" |
| 55 Identifier "Mouse1" |
| 56 Driver "evdev" |
| 57 Option "Device" "/dev/input/event2" |
| 58 Option "CorePointer" "true" |
| 59 EndSection |
| 60 """ |
| 61 |
| 62 |
| 63 # Modify the xorg.conf file to remove all mouse sections and replace it |
| 64 # with ours containing the tablet - note: when running under QEMU, you |
| 65 # *need* to specify the -usbdevice tablet option to get the mouse to work |
| 66 def FixXorgConf(mount_point): |
| 67 xorg_conf_filename = os.path.join(mount_point, XORG_CONF_FILENAME) |
| 68 f = open(xorg_conf_filename, 'r') |
| 69 xorg_conf = f.read() |
| 70 f.close() |
| 71 |
| 72 more_sections = 1 |
| 73 last_found = 0 |
| 74 while (more_sections): |
| 75 # Find the input section. |
| 76 m1 = xorg_conf.find(INPUT_SECTION_MARKER, last_found) |
| 77 if m1 > -1: |
| 78 m2 = xorg_conf.find(SECTION_END_MARKER, m1) |
| 79 m2 += len(SECTION_END_MARKER) |
| 80 # Make sure the next iteration doesn't rinse/repeat. |
| 81 last_found = m2 |
| 82 # Check if this is a mouse section. |
| 83 for ident in MOUSE_SECTION_IDENTIFIERS: |
| 84 if xorg_conf.find(ident, m1, m2) != -1: |
| 85 xorg_conf = xorg_conf[0:m1] + xorg_conf[m2:] |
| 86 last_found -= (m2-m1) |
| 87 break |
| 88 else: |
| 89 more_sections = 0 |
| 90 |
| 91 xorg_conf = xorg_conf[0:last_found] + TABLET_DEVICE_CONFIG + \ |
| 92 xorg_conf[last_found:] |
| 93 |
| 94 # Replace UsbMouse with Tablet. |
| 95 xorg_conf = xorg_conf.replace(REPLACE_USB_MOUSE_PAIR[0], |
| 96 REPLACE_USB_MOUSE_PAIR[1]) |
| 97 |
| 98 # Write the file back out. |
| 99 f = open(xorg_conf_filename, 'w') |
| 100 f.write(xorg_conf) |
| 101 f.close() |
| 102 |
| 103 |
| 104 # Remove the code that does EFI processing from the postinst script |
| 105 def FixPostInst(mount_point): |
| 106 postinst_in = os.path.join(mount_point, POST_INST_IN_FILENAME) |
| 107 f = open(postinst_in, 'r') |
| 108 postinst = f.read() |
| 109 f.close() |
| 110 m1 = postinst.find(EFI_CODE_MARKER_START) |
| 111 m2 = postinst.find(EFI_CODE_MARKER_END) |
| 112 if (m1 == -1) or (m2 == -1) or (m1 > m2): |
| 113 # basic sanity check |
| 114 return |
| 115 m2 += len(EFI_CODE_MARKER_END) |
| 116 postinst = postinst[0:m1] + postinst[m2:] |
| 117 |
| 118 # Write the file back out. |
| 119 postinst_out = os.path.join(mount_point, POST_INST_OUT_FILENAME) |
| 120 f = open(postinst_out, 'w') |
| 121 f.write(postinst) |
| 122 f.close() |
| 123 |
| 124 # Mark the file read/execute. |
| 125 os.chmod(postinst_out, stat.S_IEXEC | stat.S_IREAD) |
| 126 |
| 127 |
| 128 def main(): |
| 129 parser = OptionParser(USAGE) |
| 130 parser.add_option('--mounted_dir', dest='mounted_dir', |
| 131 help='directory where the Chromium OS image is mounted') |
| 132 parser.add_option('--for_qemu', dest='for_qemu', |
| 133 default="true", |
| 134 help='fixup image for qemu') |
| 135 (options, args) = parser.parse_args() |
| 136 |
| 137 if not options.mounted_dir: |
| 138 parser.error("Please specify the mount point for the Chromium OS image"); |
| 139 if options.for_qemu not in ('true', 'false'): |
| 140 parser.error("Please specify either true or false for --for_qemu") |
| 141 |
| 142 FixPostInst(options.mounted_dir) |
| 143 if (options.for_qemu == 'true'): |
| 144 FixXorgConf(options.mounted_dir) |
| 145 |
| 146 |
| 147 if __name__ == '__main__': |
| 148 main() |
OLD | NEW |