目錄

python 3.6 在 edk2 中的實現

最近,由在 Intel 工作的 Jayaprakash Nevara 主導的 Python 3.6 for UEFI 的開發到了一段落並釋出,而且沒有資助純粹是為了愛而做 ….

由於我已經沒有直接做 UEFI 的工作(間接還是有),研究 edk2 code 只是長久以來習慣的興趣與習慣,看到這種願意在沒有回報的情況下用自己的時間為移植 Python3 到 UEFI 環境,這麼大量的工作的人真是要給他按一個讚並幫忙推廣一下。

Python2 在幾年前已經不再被維護,但在 UEFI 裡一直都沒有人去把 Python 2.7 升級到 3.x,這個情況持續了許久,最近終於有了可以用的版本。在 Python.org 的下載區,最近增加了 UEFI 環境的實作移植,大家可以自己 build 出 Python3 的執行檔在 Shell 環境下執行 .py 程式,這對很多想要在 UEFI 下寫測試程式的人來說應該是一大福音吧。

下面就來介紹一下我們該怎麼 build 出 Python3 的執行檔吧。

Clone repository

由於原始的 build readme 寫得很複雜,我決定用我自己的 build 環境來簡化步驟,如果想查看原始作法的人可以查閱文章最後的參考連結。

前置作業為安裝好 VS2019, Python3, 還有 NASM2.15 接著按照下面步驟下載並建置你自己的 Python3.efi

1
2
3
4
set WORKSPACE=c:\myedk2

rem clone repository
git clone --recurse-submodule https://github.com/saqwed/myedk2 c:\myedk2
小記
本文寫作時間該 repository 是映射到 tag edk2-stable202302

Build BaseTools(只須執行一次)

從工作列開啟 “x86 Native Tools Command Prompt for VS 2019” 這個 command prompt,接著我們 build BaseTools,這個步驟只需要執行一次。

1
2
3
4
5
6
rem build BaseTools
set WORKSPACE=c:\myedk2
cd %WORKSPACE%\edk2\BaseTools
set EDK_TOOLS_PATH=%CD%
toolsetup.bat
nmake

打開在 AppPkg 中被封印的 Python3

預設 Python3 不會被 AppPkg.dsc 拉進來 build,所以需要手動修改 AppPkg/AppPkg.dsc,將下面 AppPkg/Applications/Python/Python-3.6.8/Python368.inf uncomment 就可以了。

1
2
#### Un-comment the following line to build Python 3.6.8.
# AppPkg/Applications/Python/Python-3.6.8/Python368.inf

開始 build UEFI Python 的前置作業

另外根據 Readme,我們還需要先做一些修改,其實就是要覆蓋掉一些檔案。

1
2
3
set WORKSPACE=c:\myedk2
cd %WORKSPACE%\edk2-libc\AppPkg\Applications\Python\Python-3.6.8
python srcprep.py

建置 AppPkg

修改好檔案後,我們接著繼續建置 AppPkg

1
2
3
4
5
6
REM open a new command prompt
set WORKSPACE=c:\myedk2
cd %WORKSPACE%
set PACKAGES_PATH=%WORKSPACE%/edk2;%WORKSPACE%/edk2-libc;%WORKSPACE%/edk2-test;%WORKSPACE%/edk2-platforms/Silicon/Intel;%WORKSPACE%/edk2-platforms
edk2\edksetup.bat VS2019
build -a X64 -t VS2019 -p AppPkg/AppPkg.dsc -b RELEASE

中間雖然還是會看到一些 warning,但預設情況下應該還是可以 build 成功,最後你應該可以在 c:\myedk2\Build\AppPkg\RELEASE_VS2019\X64\Python.efi 得到 Python3 efi 執行檔。

複製必要的檔案

但是只有這個檔案是不能用的,還需要複製一些檔案才可以,作者很貼心的提供了 create_python_pkg.bat 讓你可以方便的複製所需的檔案,但 batch 檔寫得太死,照著下面這樣做會因為路徑對不上而出錯。

1
2
3
4
set WORKSPACE=c:\myedk2
cd %WORKSPACE%\edk2-libc\AppPkg\Applications\Python\Python-3.6.8
# Assume target directory is C:\UEFI_Python
create_python_pkg.bat VS2019 RELEASE X64 C:\UEFI_Python

只好手動修改一下,以下是用我的目錄結構的版本,修改好後再執行一次就可以成功把所有需要的檔案都複製到 C:\UEFI_Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@echo off

set TOOL_CHAIN_TAG=%1
set TARGET=%2
set ARCH=%3
set OUT_FOLDER=%4
if "%TOOL_CHAIN_TAG%"=="" goto usage
if "%TARGET%"=="" goto usage
if "%ARCH%"=="" goto usage
if "%OUT_FOLDER%"=="" goto usage
goto continue

:usage
echo.
echo Batch Script to create Python EFI Package.
echo.
echo Invalid command line arguments passed, please see the below usage instructions
echo.
echo "Usage: %0 <ToolChain> <Target> <Architecture> <OutFolder>"
echo.
echo    ToolChain     = one of VS2013x86, VS2015x86, VS2017, VS2019
echo    Target        = one of RELEASE, DEBUG
echo    Architecture  = one of IA32, X64
echo    OutFolder     = Output directory for creating the package
echo.

goto :eof

:continue
cd ..\..\..\..\..\
if not exist Build\AppPkg\%TARGET%_%TOOL_CHAIN_TAG%\%ARCH%\Python.efi (
    goto error
)

if not exist %OUT_FOLDER%\EFI\Tools (
   mkdir %OUT_FOLDER%\EFI\Tools
)
xcopy Build\AppPkg\%TARGET%_%TOOL_CHAIN_TAG%\%ARCH%\Python.efi %OUT_FOLDER%\EFI\Tools\ /y

if not exist %OUT_FOLDER%\EFI\StdLib\lib\python36.8 (
    mkdir %OUT_FOLDER%\EFI\StdLib\lib\python36.8
)
if not exist %OUT_FOLDER%\EFI\StdLib\etc (
   mkdir %OUT_FOLDER%\EFI\StdLib\etc
)
xcopy edk2-libc\AppPkg\Applications\Python\Python-3.6.8\Lib\*  %OUT_FOLDER%\EFI\StdLib\lib\python36.8\    /Y /S /I
xcopy edk2-libc\StdLib\Efi\StdLib\etc\*  %OUT_FOLDER%\EFI\StdLib\etc\  /Y /S /I
echo.

if not x%OUT_FOLDER::=%==x%OUT_FOLDER% (
    echo Python EFI package available at %OUT_FOLDER%
) else (
    echo Python EFI package available at %CD%\%OUT_FOLDER%
)
goto all_done

:error
echo Failed to Create Python EFI Package
echo Python.efi is not available at Build\AppPkg\%TARGET%_%TOOL_CHAIN_TAG%\%ARCH%\
echo Follow the instructions in Py368ReadMe.txt to build Python interpreter
echo Then use this script to create a Python EFI package

:all_done
exit /b %ERRORLEVEL%

來試試看吧

都複製好後,可以將 C:\UEFI_Python 的內容全部複製到你的 UEFI boot 的隨身碟中,開機到 UEFI Shell 環境中就可以直接打 python 來使用它了。

另外,雖然 Readme 有說它有支援 GCC build,但實際上 GCC build 出來的檔案不能正常使用,而且在 EmulatorPkg 環境下或是 QEMU/OVMF 下也都是沒辦法正常使用的要注意喔。

提示
當然,如果你懶得自己建置,也可以從我這邊直接下載包好的版本 UEFI_Python.7z,這個 zip 檔中有一併附上 edk2-stable202302 中 build 出來的 efi shell。

參考