import fcntl
import os
import struct
import termios

addrtoname = {
    0x3f8: '/dev/ttyS0',
    0x2f8: '/dev/ttyS1',
    0x3e8: '/dev/ttyS2',
    0x2e8: '/dev/ttyS3',
}
speedmap = {
    0: None,
    3: 9600,
    4: 19200,
    6: 57600,
    7: 115200,
}

termiobaud = {
    9600: termios.B9600,
    19200: termios.B19200,
    57600: termios.B57600,
    115200: termios.B115200,
}

def do_serial_config():
    if 'console=ttyS' in open('/proc/cmdline').read():
        return None # Do not do autoconsole if manually configured
    spcr = open("/sys/firmware/acpi/tables/SPCR", "rb")
    spcr = bytearray(spcr.read())
    if spcr[8] != 2 or spcr[36] != 0 or spcr[40] != 1:
        return None
    address = struct.unpack('<Q', spcr[44:52])[0]
    tty = None
    try:
        tty = addrtoname[address]
    except KeyError:
        return None
    retval = { 'tty': tty }
    try:
        retval['speed'] = speedmap[spcr[58]]
    except KeyError:
        return None
    if retval['speed']:
        ttyf = os.open(tty, os.O_RDWR | os.O_NOCTTY)
        currattr = termios.tcgetattr(ttyf)
        currattr[4:6] = [0, termiobaud[retval['speed']]]
        termios.tcsetattr(ttyf, termios.TCSANOW, currattr)
    retval['connected'] = bool(struct.unpack('<I', fcntl.ioctl(
        ttyf, termios.TIOCMGET, '\x00\x00\x00\x00'))[0] & termios.TIOCM_CAR)
    return retval


if __name__ == '__main__':
    serialinfo = do_serial_config()
    if serialinfo:
        os.execl(
            '/bin/setsid', 'setsid', 'sh', '-c',
            'exec screen -x console <> {0} >&0 2>&1'.format(serialinfo['tty']))

@@ -24,21 +24,53 @@
 import s
-truct
+ignal%0Aimport struct%0Aimport subprocess
 %0Aimport 
@@ -76,16 +76,28 @@
  termios
+%0Aimport time
 %0A%0Aaddrto
@@ -1386,183 +1386,1221 @@
     
-return retval%0A%0A%0Aif __name__ == '__main__':%0A    serialinfo = do_serial_config()%0A    if serialinfo:%0A        os.execl(%0A            '/bin/setsid', 'setsid', 'sh', '-c',%0A          
+os.close(ttyf)%0A    return retval%0A%0Adef is_connected(tty):%0A    ttyf = os.open(tty, os.O_RDWR %7C os.O_NOCTTY)%0A    retval = bool(struct.unpack('%3CI', fcntl.ioctl(%0A        ttyf, termios.TIOCMGET, '%5Cx00%5Cx00%5Cx00%5Cx00'))%5B0%5D & termios.TIOCM_CAR)%0A    os.close(ttyf)%0A    return retval%0A%0A%0Aif __name__ == '__main__':%0A    serialinfo = do_serial_config()%0A    if serialinfo:%0A        running = False%0A        while True:%0A            if running and running.poll() is not None:%0A                running = False%0A            if running and not is_connected(serialinfo%5B'tty'%5D):%0A                try:%0A                    running.terminate()%0A                    running.wait()%0A                except Exception:%0A                    pass%0A                time.sleep(0.5)%0A                running = subprocess.Popen(%5B'/bin/sh', '-c',  'exec screen -x console %3C%3E %7B0%7D %3E&0 2%3E&1'.format(serialinfo%5B'tty'%5D)%5D)%0A                time.sleep(0.5)%0A                try:%0A                    running.terminate()%0A                    running.wait()%0A                except Exception:%0A                    pass%0A                running = False%0A            elif not running and is_connected(serialinfo%5B'tty'%5D):%0A                running = subprocess.Popen(%5B'/bin/sh', '-c',
   'e
@@ -2663,10 +2663,39 @@
 %5B'tty'%5D)
+%5D)%0A            time.sleep(0.5
 )%0A

Update to follow DCD