python 串口修改bios

#python2

import sys,platform
from serial import Serial
import time,re

if str(platform.python_version().split('.')(0)) == '3':
    print "Error:can not support python3"
    sys.exit(1)

class BIOSCMD(object):
    # BIOS MENU UI

    BIOS_SETUP_MENU_ENTRY_PAT = r'Press[\w\W]+\[F2\]'
    BIOS_BOOTOPTON_SELECT_PAT= r'Press[\w\W]+\[F7\]'

    BIOS_CMD_KEY_ENTER = '\r'
    BIOS_CMD_KEY_ESC = '\33'+' '
    BIOS_CMD_KEY_UP = '\33'+'[A'
    BIOS_CMD_KEY_DOWN = '\33'+'[B'
    BIOS_CMD_KEY_RIGHT = '\33'+'[C'
    BIOS_CMD_KEY_LEFT = '\33'+'[D'
    BIOS_CMD_KEY_PAGEUP = '\33'+'?'
    BIOS_CMD_KEY_PAGEDOWN = '\33'+'/'
    BIOS_CMD_KEY_F1 = '\33'+'1'
    BIOS_CMD_KEY_F2 = '\33'+'2'
    BIOS_CMD_KEY_F3 = '\33'+'3'
    BIOS_CMD_KEY_F4 = '\33'+'4'
    BIOS_CMD_KEY_F5 = '\33'+'5'
    BIOS_CMD_KEY_F6 = '\33'+'6'
    BIOS_CMD_KEY_F7 = '\33'+'7'
    BIOS_CMD_KEY_F8 = '\33'+'8'
    BIOS_CMD_KEY_F9 = '\33'+'9'
    BIOS_CMD_KEY_F10 = '\33'+'0'
    BIOS_CMD_KEY_F11 = '\33'+'!'
    BIOS_CMD_KEY_F12 = '\33'+'@'
    BIOS_CMD_KEY_Y = 'y'
    BIOS_CMD_KEY_N = 'n'
    BIOS_CMD_KEY_DELETE = '\33'+'-'
    BIOS_CMD_KEY_HOME = '\33'+'h'
    BIOS_CMD_KEY_END = '\33' + 'k'
    BIOS_CMD_KEY_INSERT = '\33' + '+'
    BIOS_CMD_KEY_SPACE = ' '
    BIOS_CMD_KEY_BACKSPACE = '\10'
    BIOS_CMD_KEY_CTRL_ALT_DELETE = '\33R\33r\33R'
    BIOS_CMD_KEY_CTRL = '\21'
    BIOS_CMD_KEY_ALT = '\22'
    BIOS_CMD_KEY_SHIFT = '\20'
    BIOS_CMD_KEY_PLUS = '\20' + '+'
    BIOS_CMD_KEY_MINUS = '\20' + '-'

class Test():
    def __init__(self,Port,Bps,Timeout=None):
        self.Port = Port
        self.Bps = Bps
        self.Timeout = Timeout
        self.depth = 1
        try:
            self.con=Serial(self.Port,self.Bps,timeout=self.Timeout)
        except:
            print('Open Serial Port Error')
            sys.exit(1)

    def read(self):
        #read form in_waiting
        try:
            lenth = self.con.in_waiting
            if lenth > 0:
                data = self.con.read(lenth)
                return data

        except Exception as e:
            print('read error:{}'.format(e))

    def write(self,cmd):
        self.con.flushOutput()
        try:
            self.con.write(cmd)
        except Exception as e:
            print("write error:{}".format(e))

    def enter_into_UEFI(self,timeout=100):
        """
        :param timeout:
        :return: True or False
        """
        serial_data = ''
        s_time=time.time()
        is_PressF7 = False
        is_IntoUEFI = False
        pattern_f7=re.compile(BIOSCMD.BIOS_BOOTOPTON_SELECT_PAT)
        while True:
            if time.time() - s_time > timeout:
                print ('into F7 Timeout')
                return False

            data = self.read()
            if not data:
                continue
            serial_data += data
            if is_PressF7:
                if not is_IntoUEFI:
                    if serial_data.find(r'Please select boot device:') != -1:
                        if self.select_bios_option(option=r'UEFI Internal Shell'):
                            self.write(BIOSCMD.BIOS_CMD_KEY_ENTER)
                            is_IntoUEFI = True
                        else:
                            print ('Select UEFI Internal Shell Failed')
                            return False
                else:
                    if serial_data.find(r'Shell>') != -1:
                        return True

            else:
                for serial_data_line in serial_data.split('\n'):
                    if pattern_f7.search(serial_data_line):
                        self.write(BIOSCMD.BIOS_CMD_KEY_F7)
                        is_PressF7 = True

    def enter_into_f2(self,timeout=100):
        """
        :param timeout:
        :return: True or False
        """
        serial_data = ''
        s_time = time.time()
        is_PressF2 = False
        pattern_f2 = re.compile(BIOSCMD.BIOS_SETUP_MENU_ENTRY_PAT)
        while True:
            if time.time() - s_time > timeout:
                print ('into F2 Timeout')
                return False

            data = self.read()
            if not data:
                continue
            serial_data += data
            if is_PressF2:
                if serial_data.find(r'EDKII Menu') != -1:
                    self.depth = 1
                    return True
            else:
                for serial_data_line in serial_data.split('\n'):
                    if pattern_f2.search(serial_data_line):
                        self.write(BIOSCMD.BIOS_CMD_KEY_F2)
                        is_PressF2 = True

    def load_default_setup(self):
        if self.select_bios_option(optionpath=[r'EDKII Menu',r'Socket Configuration',r'Processor Configuration'],option=r'Hardware Prefetcher'):
            print "Wait a few seconds to load default BIOS setup"
            self.write(BIOSCMD.BIOS_CMD_KEY_F9)
            time.sleep(3)
            self.write(BIOSCMD.BIOS_CMD_KEY_Y)
            time.sleep(30)
            if self.back_to_setup_toppage():
                return True
        return False

    def reset_from_bios_setup(self):
        self.write(BIOSCMD.BIOS_CMD_KEY_CTRL_ALT_DELETE)

    def save_bios_setup(self):
        print 'Wait a few seconds to save setup'
        self.write(BIOSCMD.BIOS_CMD_KEY_F10)
        time.sleep(3)
        self.write(BIOSCMD.BIOS_CMD_KEY_Y)
        time.sleep(30)
        return True

    def back_to_setup_toppage(self):
        if self.depth == 1:
            return True

        for i in range(1,self.depth):
            self.write(BIOSCMD.BIOS_CMD_KEY_ESC)
            time.sleep(3)
        return True

    def set_highlight_option(self,option=None,timeout=180):
        """
        :param option:
        :return: True or False
        """
        if option is None:
            return False

        #pat1 is to findout F2 setup highlight line
        #pat2 is to findout F7 highlight line
        pat1 = re.compile('\33\[0m\33\[37m\33\[40m\33\[(\d+);\d+H[\w\s\d<>\[\]&-]+\33\[0m')
        pat2 = re.compile('\33\[1m\33\[37m\33\[40m\33\[\d+;\d+H([\w\s\d<>\[\]&-]+)\33\[1m')

        #flush serial buffer in 5 sec
        for i in range(0,5):
            self.read()
            time.sleep(1)

        s_time = time.time() #set timeout flag
        while True:
            serial_data = ''
            if time.time() - s_time > timeout:
                print "set highlight option timeout"
                return False

            self.write(BIOSCMD.BIOS_CMD_KEY_DOWN)

            #read serial log in 2 sec
            for i in range(0,2):
                data = self.read()
                if data:
                    serial_data += data
                time.sleep(1)

            #get F2 or F7 highlignt number
            pat1_res = pat1.findall(serial_data)
            pat2_res = pat2.findall(serial_data)
            if not pat1_res and not pat2_res:
                continue

            if pat1_res and pat2_res:
                print 'Error'
                return None

            if pat1_res:
                for n in pat1_res:
                    #according to current highlight line number to findout all words in this line
                    pat3 = re.compile('{};\d+H([\w\s\d\[\]\(\)\?\*\.\-<>&/]+)'.format(n))
                    pat3_res = pat3.findall(serial_data)
                    print(''.join(pat3_res))
                    if ''.join(pat3_res).find(option) != -1:
                        return True
                    else:
                        continue

            if pat2_res:
                if ''.join(pat2_res).find(option) != -1:
                    return True
                else:
                    continue
        return False

    def select_bios_option(self, optionpath, option=None):
        """
        this func is help to goto Bios Setup Option which you want
        ex.dirpath=[r'EDKII Menu',r'Socket Configuration',r'Processor Configuration']
           option = r'Hardware Prefetcher'
        return value : True or False
        """

        #goto option dir
        for path in optionpath:
            if self.set_highlight_option(path):
                print "==>Enter into",path
                self.write(BIOSCMD.BIOS_CMD_KEY_ENTER)
                self.depth += 1
            else:
                return False

        #just goto optionpath
        if not option:
            return True

        #set hihglight option
        return self.set_highlight_option(option)

    def set_option_value(self,optionpath,option,value=None,type='select'):
        #ex: value = enable
        #type:
        #     select: select a value
        #     write: write a value

        if not self.select_bios_option(optionpath,option):
            print "select bios option failed"
            return False

        if value is None:
            print ('set option value is None')
            return False

        if not type is 'select' and not type is 'write':
            print ('type should be select or write,that means select a value or write a value')
            return False

        #flush buffer in 5 sec
        for i in range(0,5):
            self.read()
            time.sleep(1)

        #enter into option
        self.write(BIOSCMD.BIOS_CMD_KEY_ENTER)

        if type is 'write':
            if not isinstance(value,str):
                value = str(value)

            self.write(value+'\r')
            if self.save_bios_setup():
                self.back_to_setup_toppage()
                return True
            else:
                return False

        #read buffer
        serial_data = ''
        for i in range(0,2):
                data = self.read()
                if data:
                    serial_data += data
                time.sleep(1)

        #cut out the part of serial data which only include option value
        pat1 = re.compile('\33\[0m\33\[37m\33\[44m([\w\W]+)')
        pat1_res = pat1.findall(serial_data)

        #findout option values
        pat2 = re.compile('\33\[\d+;\d+H([\w][\w\s]+)')
        option_values = pat2.findall(''.join(pat1_res))
        option_values_length = len(option_values)
        #print option,'option_values=',option_values

        for i in range(0,option_values_length-1):
            serial_data = ''
            self.write(BIOSCMD.BIOS_CMD_KEY_DOWN)
            #read buffer in 2 sec
            for i in range(0,2):
                data = self.read()
                if data:
                    serial_data += data
                time.sleep(1)

            if serial_data == '':
                continue

            pat3 = re.compile('\33\[1m\33\[37m\33\[46m\33\[\d+;\d+H([\w][\w\s]+)')
            get_highlight_value = pat3.findall(serial_data)

            if value in get_highlight_value:
                self.write(BIOSCMD.BIOS_CMD_KEY_ENTER)
                if self.save_bios_setup():
                    self.back_to_setup_toppage()
                    return True
                else:
                    return False

        for j in range(0,option_values_length-1):
            serial_data = ''
            self.write(BIOSCMD.BIOS_CMD_KEY_UP)
            #read buffer in 2 sec
            for i in range(0,2):
                data = self.read()
                if data:
                    serial_data += data
                time.sleep(1)

            if serial_data == '':
                continue

            pat3 = re.compile('\33\[1m\33\[37m\33\[46m\33\[\d+;\d+H([\w][\w\s]+)')
            get_highlight_value = pat3.findall(serial_data)

            if value in get_highlight_value:
                self.write(BIOSCMD.BIOS_CMD_KEY_ENTER)
                if self.save_bios_setup():
                    self.back_to_setup_toppage()
                    return True
                else:
                    return False

        return False


if __name__ == '__main__':
    T = Test(Port='COM4',Bps='115200')
    if T.enter_into_f2(timeout=200):
        print "Enter into F2 Setup successfully"

    #change bios option value
    if T.set_option_value(optionpath=[r'EDKII Menu',r'Socket Configuration',r'Processor Configuration'],option=r'Hardware Prefetcher',value=r'Disable',type='select'):
       print "Set BIOS Option value successfully"

    #T.reset_from_bios_setup()

 

posted on 2020-04-30 13:38  骑着蜗牛追太阳  阅读(1250)  评论(1编辑  收藏  举报

导航