550.40.07

This commit is contained in:
Bernhard Stoeckner
2024-01-24 17:51:53 +01:00
parent bb2dac1f20
commit 91676d6628
1411 changed files with 261367 additions and 145959 deletions

View File

@@ -286,30 +286,186 @@ def scrubber(gpu, sigsize):
# And finally, the actual scrubber image
f.write(firmware)
# Extract the GSP-RM firmware from the .run file and copy the binaries
# to the target directory.
def gsp_firmware(filename):
global outputpath
global version
import subprocess
import tempfile
import shutil
import time
with tempfile.TemporaryDirectory() as temp:
os.chdir(temp)
try:
print(f"Extracting {os.path.basename(filename)} to {temp}")
# The -x parameter tells the installer to only extract the
# contents and then exit.
subprocess.run(['/bin/sh', filename, '-x'], shell=False,
check=True, timeout=60,
stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
except subprocess.CalledProcessError as error:
print(error.output.decode())
sys.exit(error.returncode)
except subprocess.TimeoutExpired as error:
print(error.output.decode())
sys.exit(error.returncode)
try:
# The .run file extracts its contents to a directory with the same
# name as the file itself, minus the .run. The GSP-RM firmware
# images are in the 'firmware' subdirectory.
directory = os.path.splitext(os.path.basename(filename))[0]
os.chdir(f"{directory}/firmware")
except:
print("Firmware failed to extract")
sys.exit(1)
if not os.path.exists('gsp_tu10x.bin') or not os.path.exists('gsp_ga10x.bin'):
print("Firmware files are missing")
sys.exit(1)
shutil.copyfile('gsp_tu10x.bin', f"{outputpath}/nvidia/tu102/gsp/gsp-{version}.bin")
print(f"Copied gsp_tu10x.bin to tu102/gsp/gsp-{version}.bin")
shutil.copyfile('gsp_ga10x.bin', f"{outputpath}/nvidia/ga102/gsp/gsp-{version}.bin")
print(f"Copied gsp_ga10x.bin to ga102/gsp/gsp-{version}.bin")
# Create a symlink, deleting the existing file/link if necessary
def symlink(src, dst, target_is_directory = False):
import errno
try:
os.symlink(src, dst, target_is_directory = target_is_directory)
except OSError as e:
if e.errno == errno.EEXIST:
os.remove(dst)
os.symlink(src, dst, target_is_directory = target_is_directory)
else:
raise e
# Create symlinks in the target directory for the other GPUs. This mirrors
# what the WHENCE file in linux-firmware does.
def symlinks():
global outputpath
global version
print(f"Creating symlinks in {outputpath}/nvidia")
os.chdir(f"{outputpath}/nvidia")
for d in ['tu104', 'tu106', 'tu117']:
os.makedirs(d, exist_ok = True)
symlink('../tu102/gsp', f"{d}/gsp", target_is_directory = True)
for d in ['ad103', 'ad104', 'ad106', 'ad107']:
os.makedirs(d, exist_ok = True)
symlink('../ad102/gsp', f"{d}/gsp", target_is_directory = True)
for d in ['ga103', 'ga104', 'ga106', 'ga107']:
os.makedirs(d, exist_ok = True)
symlink('../ga102/gsp', f"{d}/gsp", target_is_directory = True)
symlink(f"../../tu102/gsp/bootloader-{version}.bin", f"tu116/gsp/bootloader-{version}.bin")
symlink(f"../../tu102/gsp/gsp-{version}.bin", f"tu116/gsp/gsp-{version}.bin")
symlink(f"../../tu102/gsp/gsp-{version}.bin", f"ga100/gsp/gsp-{version}.bin")
symlink(f"../../ga102/gsp/gsp-{version}.bin", f"ad102/gsp/gsp-{version}.bin")
# Create a text file that can be inserted as-is to the WHENCE file of the
# linux-firmware git repository.
def whence():
global outputpath
global version
whence = f"""
File: nvidia/tu102/gsp/bootloader-{version}.bin
File: nvidia/tu102/gsp/booter_load-{version}.bin
File: nvidia/tu102/gsp/booter_unload-{version}.bin
Link: nvidia/tu104/gsp -> ../tu102/gsp
Link: nvidia/tu106/gsp -> ../tu102/gsp
File: nvidia/tu116/gsp/booter_load-{version}.bin
File: nvidia/tu116/gsp/booter_unload-{version}.bin
Link: nvidia/tu116/gsp/bootloader-{version}.bin -> ../../tu102/gsp/bootloader-{version}.bin
Link: nvidia/tu117/gsp -> ../tu116/gsp
File: nvidia/ga100/gsp/bootloader-{version}.bin
File: nvidia/ga100/gsp/booter_load-{version}.bin
File: nvidia/ga100/gsp/booter_unload-{version}.bin
File: nvidia/ad102/gsp/bootloader-{version}.bin
File: nvidia/ad102/gsp/booter_load-{version}.bin
File: nvidia/ad102/gsp/booter_unload-{version}.bin
Link: nvidia/ad103/gsp -> ../ad102/gsp
Link: nvidia/ad104/gsp -> ../ad102/gsp
Link: nvidia/ad106/gsp -> ../ad102/gsp
Link: nvidia/ad107/gsp -> ../ad102/gsp
File: nvidia/ga102/gsp/bootloader-{version}.bin
File: nvidia/ga102/gsp/booter_load-{version}.bin
File: nvidia/ga102/gsp/booter_unload-{version}.bin
Link: nvidia/ga103/gsp -> ../ga102/gsp
Link: nvidia/ga104/gsp -> ../ga102/gsp
Link: nvidia/ga106/gsp -> ../ga102/gsp
Link: nvidia/ga107/gsp -> ../ga102/gsp
File: nvidia/tu102/gsp/gsp-{version}.bin
Origin: gsp_tu10x.bin from NVIDIA-Linux-x86_64-{version}.run
Link: nvidia/tu116/gsp/gsp-{version}.bin -> ../../tu102/gsp/gsp-{version}.bin
Link: nvidia/ga100/gsp/gsp-{version}.bin -> ../../tu102/gsp/gsp-{version}.bin
File: nvidia/ga102/gsp/gsp-{version}.bin
Origin: gsp_ga10x.bin from NVIDIA-Linux-x86_64-{version}.run
Link: nvidia/ad102/gsp/gsp-{version}.bin -> ../../ga102/gsp/gsp-{version}.bin
"""
with open(f"{outputpath}/WHENCE.txt", 'w') as f:
f.writelines(whence)
print(f"Created {outputpath}/WHENCE.txt")
def main():
global outputpath
global version
parser = argparse.ArgumentParser(
description = 'Extract firmware binaries from the OpenRM git repository'
' in a format expected by the Nouveau device driver.')
' in a format expected by the Nouveau device driver.',
epilog = 'Running as root and specifying -o /lib/firmware will install'
' the firmware files directly where Nouveau expects them.'
' The --revision option is useful for testing new firmware'
' versions without changing Nouveau source code.'
' The --driver option lets you specify the path to the .run file,'
' and this script also will extract and copy the GSP-RM firmware images.')
parser.add_argument('-i', '--input', default = os.getcwd(),
help = 'Path to source directory (where version.mk exists)')
parser.add_argument('-o', '--output', default = os.path.abspath(os.getcwd() + '/_out'),
help = 'Path to target directory (where files will be written)')
parser.add_argument('-r', '--revision',
help = 'Files will be named with this version number')
parser.add_argument('-d', '--driver',
help = 'Path to Nvidia driver .run package, for also extracting the GSP-RM firmware')
parser.add_argument('-s', '--symlink', action='store_true',
help = 'Also create symlinks for all supported GPUs')
parser.add_argument('-w', '--whence', action='store_true',
help = 'Also generate a WHENCE file')
args = parser.parse_args()
os.chdir(args.input)
with open("version.mk") as f:
version = re.search(r'^NVIDIA_VERSION = ([^\s]+)', f.read(), re.MULTILINE).group(1)
print(f"Generating files for version {version}")
if args.driver:
if not os.path.exists(args.driver):
print(f"File {args.driver} does not exist.")
sys.exit(1)
# Normal version strings are of the format xxx.yy.zz, which are all
# numbers. If it's a normal version string, convert it to a single number,
# as Nouveau currently expects. Otherwise, leave it alone.
if set(version) <= set('0123456789.'):
version = version.replace(".", "")
version = args.revision
if not version:
with open("version.mk") as f:
version = re.search(r'^NVIDIA_VERSION = ([^\s]+)', f.read(), re.MULTILINE).group(1)
print(f"Generating files for version {version}")
outputpath = args.output;
print(f"Writing files to {outputpath}")
@@ -337,6 +493,15 @@ def main():
bootloader("ad102", "_prod_")
# scrubber("ad102", 384) # Not currently used by Nouveau
if args.driver:
gsp_firmware(os.path.abspath(args.driver))
if args.symlink:
symlinks()
if args.whence:
whence()
if __name__ == "__main__":
main()