目錄

python 3.6 在 edk2 中的實現

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


小記

2024/07/12 update

由於同業來信詢問本文,加上近期原作者 Jayaprakash Nevara 跑來在下面留言說他已經做好了 Github action CI 設定,所以大家可以不用自己 build UEFI Python 了!

因為 UEFI Python 已經有在 release 了,所以大家可以去下面連結下載

Github UEFI Python release page

在其文中也有直接提供包好的下載連結

Download Links

The release binaries are available at the below links for downloading:

後面舊文就留著但不一定會動喔

後面舊文就留著但不一定會動喔

後面舊文就留著但不一定會動喔


由於我已經沒有直接做 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。

參考