GNU Linux-libre 5.4.274-gnu1
[releases.git] / arch / powerpc / boot / wrapper
1 #!/bin/sh
2 # SPDX-License-Identifier: GPL-2.0-only
3
4 # Copyright (C) 2006 Paul Mackerras, IBM Corporation <paulus@samba.org>
5
6 # This script takes a kernel binary and optionally an initrd image
7 # and/or a device-tree blob, and creates a bootable zImage for a
8 # given platform.
9
10 # Options:
11 # -o zImage     specify output file
12 # -p platform   specify platform (links in $platform.o)
13 # -i initrd     specify initrd file
14 # -d devtree    specify device-tree blob
15 # -s tree.dts   specify device-tree source file (needs dtc installed)
16 # -e esm_blob   specify ESM blob for secure images
17 # -c            cache $kernel.strip.gz (use if present & newer, else make)
18 # -C prefix     specify command prefix for cross-building tools
19 #               (strip, objcopy, ld)
20 # -D dir        specify directory containing data files used by script
21 #               (default ./arch/powerpc/boot)
22 # -W dir        specify working directory for temporary files (default .)
23 # -z            use gzip (legacy)
24 # -Z zsuffix    compression to use (gz, xz or none)
25
26 # Stop execution if any command fails
27 set -e
28
29 # Allow for verbose output
30 if [ "$V" = 1 ]; then
31     set -x
32 fi
33
34 # defaults
35 kernel=
36 ofile=zImage
37 platform=of
38 initrd=
39 dtb=
40 dts=
41 esm_blob=
42 cacheit=
43 binary=
44 compression=.gz
45 uboot_comp=gzip
46 pie=
47 format=
48
49 # cross-compilation prefix
50 CROSS=
51
52 # mkimage wrapper script
53 MKIMAGE=$srctree/scripts/mkuboot.sh
54
55 # directory for object and other files used by this script
56 object=arch/powerpc/boot
57 objbin=$object
58 dtc=scripts/dtc/dtc
59
60 # directory for working files
61 tmpdir=.
62
63 usage() {
64     echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2
65     echo '       [-d devtree] [-s tree.dts] [-e esm_blob]' >&2
66     echo '       [-c] [-C cross-prefix] [-D datadir] [-W workingdir]' >&2
67     echo '       [-Z (gz|xz|none)] [--no-compression] [vmlinux]' >&2
68     exit 1
69 }
70
71 run_cmd() {
72     if [ "$V" = 1 ]; then
73         $* 2>&1
74     else
75         local msg
76
77         set +e
78         msg=$($* 2>&1)
79
80         if [ $? -ne "0" ]; then
81                 echo $msg
82                 exit 1
83         fi
84         set -e
85     fi
86 }
87
88 while [ "$#" -gt 0 ]; do
89     case "$1" in
90     -o)
91         shift
92         [ "$#" -gt 0 ] || usage
93         ofile="$1"
94         ;;
95     -p)
96         shift
97         [ "$#" -gt 0 ] || usage
98         platform="$1"
99         ;;
100     -i)
101         shift
102         [ "$#" -gt 0 ] || usage
103         initrd="$1"
104         ;;
105     -d)
106         shift
107         [ "$#" -gt 0 ] || usage
108         dtb="$1"
109         ;;
110     -e)
111         shift
112         [ "$#" -gt 0 ] || usage
113         esm_blob="$1"
114         ;;
115     -s)
116         shift
117         [ "$#" -gt 0 ] || usage
118         dts="$1"
119         ;;
120     -c)
121         cacheit=y
122         ;;
123     -C)
124         shift
125         [ "$#" -gt 0 ] || usage
126         CROSS="$1"
127         ;;
128     -D)
129         shift
130         [ "$#" -gt 0 ] || usage
131         object="$1"
132         objbin="$1"
133         ;;
134     -W)
135         shift
136         [ "$#" -gt 0 ] || usage
137         tmpdir="$1"
138         ;;
139     -z)
140         compression=.gz
141         uboot_comp=gzip
142         ;;
143     -Z)
144         shift
145         [ "$#" -gt 0 ] || usage
146         [ "$1" != "gz" -o "$1" != "xz" -o "$1" != "lzma" -o "$1" != "lzo" -o "$1" != "none" ] || usage
147
148         compression=".$1"
149         uboot_comp=$1
150
151         if [ $compression = ".none" ]; then
152                 compression=
153                 uboot_comp=none
154         fi
155         if [ $uboot_comp = "gz" ]; then
156                 uboot_comp=gzip
157         fi
158         ;;
159     --no-gzip)
160         # a "feature" of the the wrapper script is that it can be used outside
161         # the kernel tree. So keeping this around for backwards compatibility.
162         compression=
163         uboot_comp=none
164         ;;
165     -?)
166         usage
167         ;;
168     *)
169         [ -z "$kernel" ] || usage
170         kernel="$1"
171         ;;
172     esac
173     shift
174 done
175
176
177 if [ -n "$dts" ]; then
178     if [ ! -r "$dts" -a -r "$object/dts/$dts" ]; then
179         dts="$object/dts/$dts"
180     fi
181     if [ -z "$dtb" ]; then
182         dtb="$platform.dtb"
183     fi
184     $dtc -O dtb -o "$dtb" -b 0 "$dts"
185 fi
186
187 if [ -z "$kernel" ]; then
188     kernel=vmlinux
189 fi
190
191 LANG=C elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`"
192 case "$elfformat" in
193     elf64-powerpcle)    format=elf64lppc        ;;
194     elf64-powerpc)      format=elf32ppc ;;
195     elf32-powerpc)      format=elf32ppc ;;
196 esac
197
198 ld_version()
199 {
200     # Poached from scripts/ld-version.sh, but we don't want to call that because
201     # this script (wrapper) is distributed separately from the kernel source.
202     # Extract linker version number from stdin and turn into single number.
203     awk '{
204         gsub(".*\\)", "");
205         gsub(".*version ", "");
206         gsub("-.*", "");
207         split($1,a, ".");
208         print a[1]*100000000 + a[2]*1000000 + a[3]*10000;
209         exit
210     }'
211 }
212
213 # Do not include PT_INTERP segment when linking pie. Non-pie linking
214 # just ignores this option.
215 LD_VERSION=$(${CROSS}ld --version | ld_version)
216 LD_NO_DL_MIN_VERSION=$(echo 2.26 | ld_version)
217 if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VERSION" ] ; then
218         nodl="--no-dynamic-linker"
219 fi
220
221 platformo=$object/"$platform".o
222 lds=$object/zImage.lds
223 ext=strip
224 objflags=-S
225 tmp=$tmpdir/zImage.$$.o
226 ksection=.kernel:vmlinux.strip
227 isection=.kernel:initrd
228 esection=.kernel:esm_blob
229 link_address='0x400000'
230 make_space=y
231
232
233 if [ -n "$esm_blob" -a "$platform" != "pseries" ]; then
234     echo "ESM blob not support on non-pseries platforms" >&2
235     exit 1
236 fi
237
238 case "$platform" in
239 of)
240     platformo="$object/of.o $object/epapr.o"
241     make_space=n
242     ;;
243 pseries)
244     platformo="$object/pseries-head.o $object/of.o $object/epapr.o"
245     link_address='0x4000000'
246     if [ "$format" != "elf32ppc" ]; then
247         link_address=
248         pie=-pie
249     fi
250     make_space=n
251     ;;
252 maple)
253     platformo="$object/of.o $object/epapr.o"
254     link_address='0x400000'
255     make_space=n
256     ;;
257 pmac|chrp)
258     platformo="$object/of.o $object/epapr.o"
259     make_space=n
260     ;;
261 coff)
262     platformo="$object/crt0.o $object/of.o $object/epapr.o"
263     lds=$object/zImage.coff.lds
264     link_address='0x500000'
265     make_space=n
266     pie=
267     ;;
268 miboot|uboot*)
269     # miboot and U-boot want just the bare bits, not an ELF binary
270     ext=bin
271     objflags="-O binary"
272     tmp="$ofile"
273     ksection=image
274     isection=initrd
275     ;;
276 cuboot*)
277     binary=y
278     compression=
279     case "$platform" in
280     *-mpc866ads|*-mpc885ads|*-adder875*|*-ep88xc)
281         platformo=$object/cuboot-8xx.o
282         ;;
283     *5200*|*-motionpro)
284         platformo=$object/cuboot-52xx.o
285         ;;
286     *-pq2fads|*-ep8248e|*-mpc8272*|*-storcenter)
287         platformo=$object/cuboot-pq2.o
288         ;;
289     *-mpc824*)
290         platformo=$object/cuboot-824x.o
291         ;;
292     *-mpc83*|*-asp834x*)
293         platformo=$object/cuboot-83xx.o
294         ;;
295     *-tqm8541|*-mpc8560*|*-tqm8560|*-tqm8555|*-ksi8560*)
296         platformo=$object/cuboot-85xx-cpm2.o
297         ;;
298     *-mpc85*|*-tqm85*|*-sbc85*)
299         platformo=$object/cuboot-85xx.o
300         ;;
301     *-amigaone)
302         link_address='0x800000'
303         ;;
304     esac
305     ;;
306 ps3)
307     platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
308     lds=$object/zImage.ps3.lds
309     compression=
310     ext=bin
311     objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
312     ksection=.kernel:vmlinux.bin
313     isection=.kernel:initrd
314     link_address=''
315     make_space=n
316     pie=
317     ;;
318 ep88xc|ep405|ep8248e)
319     platformo="$object/fixed-head.o $object/$platform.o"
320     binary=y
321     ;;
322 adder875-redboot)
323     platformo="$object/fixed-head.o $object/redboot-8xx.o"
324     binary=y
325     ;;
326 simpleboot-virtex405-*)
327     platformo="$object/virtex405-head.o $object/simpleboot.o $object/virtex.o"
328     binary=y
329     ;;
330 simpleboot-virtex440-*)
331     platformo="$object/fixed-head.o $object/simpleboot.o $object/virtex.o"
332     binary=y
333     ;;
334 simpleboot-*)
335     platformo="$object/fixed-head.o $object/simpleboot.o"
336     binary=y
337     ;;
338 asp834x-redboot)
339     platformo="$object/fixed-head.o $object/redboot-83xx.o"
340     binary=y
341     ;;
342 xpedite52*)
343     link_address='0x1400000'
344     platformo=$object/cuboot-85xx.o
345     ;;
346 gamecube|wii)
347     link_address='0x600000'
348     platformo="$object/$platform-head.o $object/$platform.o"
349     ;;
350 treeboot-currituck)
351     link_address='0x1000000'
352     ;;
353 treeboot-akebono)
354     link_address='0x1000000'
355     ;;
356 treeboot-iss4xx-mpic)
357     platformo="$object/treeboot-iss4xx.o"
358     ;;
359 epapr)
360     platformo="$object/pseries-head.o $object/epapr.o $object/epapr-wrapper.o"
361     link_address='0x20000000'
362     pie=-pie
363     ;;
364 mvme5100)
365     platformo="$object/fixed-head.o $object/mvme5100.o"
366     binary=y
367     ;;
368 mvme7100)
369     platformo="$object/motload-head.o $object/mvme7100.o"
370     link_address='0x4000000'
371     binary=y
372     ;;
373 esac
374
375 vmz="$tmpdir/`basename \"$kernel\"`.$ext"
376
377 # Calculate the vmlinux.strip size
378 ${CROSS}objcopy $objflags "$kernel" "$vmz.$$"
379 strip_size=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" "$vmz.$$")
380
381 if [ -z "$cacheit" -o ! -f "$vmz$compression" -o "$vmz$compression" -ot "$kernel" ]; then
382     # recompress the image if we need to
383     case $compression in
384     .xz)
385         xz --check=crc32 -f -6 "$vmz.$$"
386         ;;
387     .gz)
388         gzip -n -f -9 "$vmz.$$"
389         ;;
390     .lzma)
391         xz --format=lzma -f -6 "$vmz.$$"
392         ;;
393     .lzo)
394         lzop -f -9 "$vmz.$$"
395         ;;
396     *)
397         # drop the compression suffix so the stripped vmlinux is used
398         compression=
399         uboot_comp=none
400         ;;
401     esac
402
403     if [ -n "$cacheit" ]; then
404         mv -f "$vmz.$$$compression" "$vmz$compression"
405     else
406         vmz="$vmz.$$"
407     fi
408 else
409     rm -f $vmz.$$
410 fi
411
412 vmz="$vmz$compression"
413
414 if [ "$make_space" = "y" ]; then
415         # Round the size to next higher MB limit
416         round_size=$(((strip_size + 0xfffff) & 0xfff00000))
417
418         round_size=0x$(printf "%x" $round_size)
419         link_addr=$(printf "%d" $link_address)
420
421         if [ $link_addr -lt $strip_size ]; then
422             echo "INFO: Uncompressed kernel (size 0x$(printf "%x\n" $strip_size))" \
423                         "overlaps the address of the wrapper($link_address)"
424             echo "INFO: Fixing the link_address of wrapper to ($round_size)"
425             link_address=$round_size
426         fi
427 fi
428
429 # Extract kernel version information, some platforms want to include
430 # it in the image header
431 version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \
432     cut -d' ' -f3`
433 if [ -n "$version" ]; then
434     uboot_version="-n Linux-$version"
435 fi
436
437 # physical offset of kernel image
438 membase=`${CROSS}objdump -p "$kernel" | grep -m 1 LOAD | awk '{print $7}'`
439
440 case "$platform" in
441 uboot)
442     rm -f "$ofile"
443     ${MKIMAGE} -A ppc -O linux -T kernel -C $uboot_comp -a $membase -e $membase \
444         $uboot_version -d "$vmz" "$ofile"
445     if [ -z "$cacheit" ]; then
446         rm -f "$vmz"
447     fi
448     exit 0
449     ;;
450 uboot-obs600)
451     rm -f "$ofile"
452     # obs600 wants a multi image with an initrd, so we need to put a fake
453     # one in even when building a "normal" image.
454     if [ -n "$initrd" ]; then
455         real_rd="$initrd"
456     else
457         real_rd=`mktemp`
458         echo "\0" >>"$real_rd"
459     fi
460     ${MKIMAGE} -A ppc -O linux -T multi -C gzip -a $membase -e $membase \
461         $uboot_version -d "$vmz":"$real_rd":"$dtb" "$ofile"
462     if [ -z "$initrd" ]; then
463         rm -f "$real_rd"
464     fi
465     if [ -z "$cacheit" ]; then
466         rm -f "$vmz"
467     fi
468     exit 0
469     ;;
470 esac
471
472 addsec() {
473     ${CROSS}objcopy $4 $1 \
474         --add-section=$3="$2" \
475         --set-section-flags=$3=contents,alloc,load,readonly,data
476 }
477
478 addsec $tmp "$vmz" $ksection $object/empty.o
479 if [ -z "$cacheit" ]; then
480     rm -f "$vmz"
481 fi
482
483 if [ -n "$initrd" ]; then
484     addsec $tmp "$initrd" $isection
485 fi
486
487 if [ -n "$dtb" ]; then
488     addsec $tmp "$dtb" .kernel:dtb
489     if [ -n "$dts" ]; then
490         rm $dtb
491     fi
492 fi
493
494 if [ -n "$esm_blob" ]; then
495     addsec $tmp "$esm_blob" $esection
496 fi
497
498 if [ "$platform" != "miboot" ]; then
499     if [ -n "$link_address" ] ; then
500         text_start="-Ttext $link_address"
501     fi
502 #link everything
503     ${CROSS}ld -m $format -T $lds $text_start $pie $nodl -o "$ofile" \
504         $platformo $tmp $object/wrapper.a
505     rm $tmp
506 fi
507
508 # Some platforms need the zImage's entry point and base address
509 base=0x`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1`
510 entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3`
511
512 if [ -n "$binary" ]; then
513     mv "$ofile" "$ofile".elf
514     ${CROSS}objcopy -O binary "$ofile".elf "$ofile"
515 fi
516
517 # post-processing needed for some platforms
518 case "$platform" in
519 pseries|chrp|maple)
520     $objbin/addnote "$ofile"
521     ;;
522 coff)
523     ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile"
524     $objbin/hack-coff "$ofile"
525     ;;
526 cuboot*)
527     gzip -n -f -9 "$ofile"
528     ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
529             $uboot_version -d "$ofile".gz "$ofile"
530     ;;
531 treeboot*)
532     mv "$ofile" "$ofile.elf"
533     $objbin/mktree "$ofile.elf" "$ofile" "$base" "$entry"
534     if [ -z "$cacheit" ]; then
535         rm -f "$ofile.elf"
536     fi
537     exit 0
538     ;;
539 ps3)
540     # The ps3's loader supports loading a gzipped binary image from flash
541     # rom to ram addr zero. The loader then enters the system reset
542     # vector at addr 0x100.  A bootwrapper overlay is used to arrange for
543     # a binary image of the kernel to be at addr zero, and yet have a
544     # suitable bootwrapper entry at 0x100.  To construct the final rom
545     # image 512 bytes from offset 0x100 is copied to the bootwrapper
546     # place holder at symbol __system_reset_kernel.  The 512 bytes of the
547     # bootwrapper entry code at symbol __system_reset_overlay is then
548     # copied to offset 0x100.  At runtime the bootwrapper program copies
549     # the data at __system_reset_kernel back to addr 0x100.
550
551     system_reset_overlay=0x`${CROSS}nm "$ofile" \
552         | grep ' __system_reset_overlay$'       \
553         | cut -d' ' -f1`
554     system_reset_overlay=`printf "%d" $system_reset_overlay`
555     system_reset_kernel=0x`${CROSS}nm "$ofile" \
556         | grep ' __system_reset_kernel$'       \
557         | cut -d' ' -f1`
558     system_reset_kernel=`printf "%d" $system_reset_kernel`
559     overlay_dest="256"
560     overlay_size="512"
561
562     ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
563
564     run_cmd dd if="$ofile.bin" of="$ofile.bin" conv=notrunc   \
565         skip=$overlay_dest seek=$system_reset_kernel          \
566         count=$overlay_size bs=1
567
568     run_cmd dd if="$ofile.bin" of="$ofile.bin" conv=notrunc   \
569         skip=$system_reset_overlay seek=$overlay_dest         \
570         count=$overlay_size bs=1
571
572     odir="$(dirname "$ofile.bin")"
573     rm -f "$odir/otheros.bld"
574     gzip -n --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld"
575     ;;
576 esac