Skip to content

Commit 5c39604

Browse files
authored
bf-pldm-ver: initial version to retrieve image versions from PLDM file. RM# 4513650
bf-pldm-ver: initial version to retrieve image versions from PLDM file. RM# 4513650
1 parent 7f61204 commit 5c39604

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed

man/bf-pldm-ver.8

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.\" Manpage for pldm-ver.
2+
.TH man 8 "3 Jul 2025" "1.0" "pldm-ver man page"
3+
.SH NAME
4+
pldm-ver \- Get all version information of PLDM image
5+
6+
.SH SYNOPSIS
7+
.B pldm-ver
8+
Usage: ./pldm-ver <PLDM image file>
9+
10+
.SH DESCRIPTION
11+
12+
pldm-ver is a utility script to fetch all version information of packages inside a PLDM image.
13+
14+
.SH KNOWN ISSUES
15+
16+
This script only supports BF3 for now.

rhel/rshim.spec.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,17 @@ via the virtual console or network interface.
5252
%{_sbindir}/rshim
5353
%{_sbindir}/mlx-mkbfb
5454
%{_sbindir}/fwpkg_unpack.py
55+
%{_sbindir}/bfb-install
56+
%{_sbindir}/bfb-tool
57+
%{_sbindir}/bf-reg
58+
%{_sbindir}/bf-pldm-ver
5559
%{_mandir}/man1/mlx-mkbfb.1.gz
5660
%{_unitdir}/rshim.service
5761
%{_mandir}/man8/rshim.8.gz
62+
%{_mandir}/man8/bfb-install.8.gz
63+
%{_mandir}/man8/bfb-tool.8.gz
64+
%{_mandir}/man8/bf-reg.8.gz
65+
%{_mandir}/man8/bf-pldm-ver.8.gz
5866

5967
%changelog
6068
* Fri Jun 06 2025 Penghe Geng <[email protected]> - 2.4.2

rshim.spec.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ make
6060
%{__install} -m 0644 man/bfb-install.8 %{buildroot}%{_mandir}/man8
6161
%{__install} -m 0644 man/bfb-tool.8 %{buildroot}%{_mandir}/man8
6262
%{__install} -m 0644 man/bf-reg.8 %{buildroot}%{_mandir}/man8
63+
%{__install} -m 0644 man/bf-pldm-ver.8 %{buildroot}%{_mandir}/man8
6364
%{__install} -d %{buildroot}%{_sysconfdir}
6465
%{__install} -m 0644 etc/rshim.conf %{buildroot}%{_sysconfdir}
6566
%{__install} -m 0755 scripts/bfb-install %{buildroot}%{_sbindir}
@@ -69,6 +70,7 @@ make
6970
%{__install} -m 0755 scripts/bf-reg %{buildroot}%{_sbindir}
7071
%{__install} -d %{buildroot}%{_datadir}/selinux/packages
7172
%{__install} -m 0644 scripts/rshim-fix.te %{buildroot}%{_datadir}/selinux/packages/rshim-fix.te
73+
%{__install} -m 0755 scripts/bf-pldm-ver %{buildroot}%{_sbindir}
7274

7375
%pre
7476
%if "%{with_systemd}" == "1"
@@ -143,6 +145,7 @@ fi
143145
%{_mandir}/man8/bfb-install.8.gz
144146
%{_mandir}/man8/bfb-tool.8.gz
145147
%{_mandir}/man8/bf-reg.8.gz
148+
%{_mandir}/man8/bf-pldm-ver.8.gz
146149
%{_datadir}/selinux/packages/rshim-fix.te
147150

148151
%changelog

scripts/bf-pldm-ver

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/bin/bash
2+
3+
###############################################################################
4+
#
5+
# Copyright 2025 NVIDIA Corporation
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
8+
# this software and associated documentation files (the "Software"), to deal in
9+
# the Software without restriction, including without limitation the rights to
10+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11+
# the Software, and to permit persons to whom the Software is furnished to do so,
12+
# subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in all
15+
# copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+
#
24+
###############################################################################
25+
26+
usage() {
27+
cat << EOF
28+
Usage: $(basename $0) <pldm-image-file>
29+
EOF
30+
}
31+
#cleanup
32+
cleanup() {
33+
# Remove the temp directory.
34+
rm -rf $TMP_DIR
35+
}
36+
37+
if [ $# -lt 1 ]; then
38+
echo "Error: $(basename $0) requires 1 argument."
39+
exit 1
40+
fi
41+
42+
pldm_image_file=$1
43+
44+
if [ ! -e "$pldm_image_file" ]; then
45+
echo "Error: $pldm_image_file file not found."
46+
exit 1
47+
fi
48+
49+
TMP_DIR=$(mktemp -d)
50+
51+
if [ ! -d "${TMP_DIR}" ]; then
52+
echo "Error: TMP_DIR not found."
53+
exit 1
54+
fi
55+
56+
trap cleanup EXIT INT TERM
57+
58+
# NIC FW & BSP
59+
fwpkg_unpack.py --show_all_metadata --verbose $pldm_image_file | grep "ComponentVersionString\"" | awk 'BEGIN { product[1] = "BlueField NICFW version: "; product[2] = "BlueField BSP version: ";} {print product[NR] $2}' | tr -d '"'
60+
if [ $? -ne 0 ]; then
61+
echo "Error: failed to get NICFW version."
62+
fi
63+
64+
# Unpack
65+
fwpkg_unpack.py --unpack --outdir ${TMP_DIR} $pldm_image_file
66+
if [ $? -ne 0 ]; then
67+
echo "Error: failed to unpack $pldm_image_file."
68+
exit 1
69+
fi
70+
71+
# UEFI
72+
print_capsule_file_vers () {
73+
# Print versions stored in files.
74+
75+
# UEFI image header
76+
pattern="4266021321003005"
77+
uefi_image_file="$TMP_DIR/temp_uefi_image.bin"
78+
79+
atf_version=$(strings "$IMAGE_PATH" | grep -m 1 "(\(release\|debug\))")
80+
if [ -n "$atf_version" ]; then
81+
echo "BlueField ATF version: $atf_version"
82+
fi
83+
84+
# Search for the UEFI header pattern
85+
xxd -p "$IMAGE_PATH" | tr -d "\n" | grep -b -o "$pattern" | cut -d: -f1 | while read -r header_offset2; do
86+
header_offset=$(($header_offset2/2))
87+
image_offset=$((header_offset + 24))
88+
89+
header_string=$(xxd -p -s $header_offset -l 24 "$IMAGE_PATH")
90+
91+
if echo "$header_string" | grep -q "^$pattern"; then
92+
# Extract the image length (next 4 bytes after the header)
93+
image_len_hex=$(echo "$header_string" | cut -c 17-24)
94+
image_len=$(echo "$image_len_hex" | sed 's/\(..\)\(..\)\(..\)\(..\)/\4\3\2\1/')
95+
image_len_dec=$(printf "%d" "0x${image_len#0*}")
96+
97+
# Check the image offset and length against the input file length
98+
input_file_length=$(stat -c%s "$IMAGE_PATH")
99+
end_position=$((image_offset + image_len_dec))
100+
if [ "$end_position" -gt "$input_file_length" ]; then
101+
echo "Error: Image offset + length is greater than input file length"
102+
exit 1
103+
fi
104+
105+
# Extract the UEFI image
106+
tail -c +$((image_offset + 1)) "$IMAGE_PATH" | head -c $image_len_dec > "$uefi_image_file"
107+
108+
# Fetch the version from the UEFI image
109+
gzipped=$(file $uefi_image_file | grep gzip)
110+
if [ -n "$gzipped" ]; then
111+
mv $uefi_image_file $uefi_image_file.gz
112+
gunzip $uefi_image_file.gz
113+
uefi_version="$(strings -el $uefi_image_file | grep "BlueField" | cut -d':' -f 2)"
114+
else
115+
echo "Warning: UEFI image not compressed and no version info"
116+
fi
117+
118+
echo "BlueField UEFI version: $uefi_version"
119+
break
120+
fi
121+
done
122+
}
123+
124+
# ATF & UEFI
125+
pushd . > /dev/null
126+
cd ${TMP_DIR} > /dev/null
127+
for file in ${TMP_DIR}/*; do
128+
IMAGE_PATH="$file"
129+
print_capsule_file_vers
130+
# dump images if it contains them
131+
mlx-mkbfb -x $file &> /dev/null
132+
done
133+
134+
# BMC & CEC
135+
for file in ${TMP_DIR}/dump*; do
136+
fwpkg_unpack.py --show_all_metadata --verbose $file | grep "ComponentVersionString\"" | awk -v substrBMC="ApFw" -v substrCEC="Ecfw" '{ if (index($2, substrBMC)) {print "BlueField BMC version: " $2} else if (index($2, substrCEC)) { print "BlueField CEC version: " $2}}' | tr -d '"'
137+
138+
if [ $? -ne 0 ]; then
139+
echo "Error: failed to read $file."
140+
exit 1
141+
fi
142+
done
143+
144+
popd > /dev/null
145+
146+
exit 0

0 commit comments

Comments
 (0)