~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/boot/decompress.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Wrapper around the kernel's pre-boot decompression library.
  4  *
  5  * Copyright (C) IBM Corporation 2016.
  6  */
  7 
  8 #include "elf.h"
  9 #include "page.h"
 10 #include "string.h"
 11 #include "stdio.h"
 12 #include "ops.h"
 13 #include "reg.h"
 14 #include "types.h"
 15 
 16 /*
 17  * The decompressor_*.c files play #ifdef games so they can be used in both
 18  * pre-boot and regular kernel code. We need these definitions to make the
 19  * includes work.
 20  */
 21 
 22 #define STATIC static
 23 #define INIT
 24 
 25 /*
 26  * The build process will copy the required zlib source files and headers
 27  * out of lib/ and "fix" the includes so they do not pull in other kernel
 28  * headers.
 29  */
 30 
 31 #ifdef CONFIG_KERNEL_GZIP
 32 #       include "decompress_inflate.c"
 33 #endif
 34 
 35 #ifdef CONFIG_KERNEL_XZ
 36 #       include "xz_config.h"
 37 #       include "../../../lib/decompress_unxz.c"
 38 #endif
 39 
 40 /* globals for tracking the state of the decompression */
 41 static unsigned long decompressed_bytes;
 42 static unsigned long limit;
 43 static unsigned long skip;
 44 static char *output_buffer;
 45 
 46 /*
 47  * flush() is called by __decompress() when the decompressor's scratch buffer is
 48  * full.
 49  */
 50 static long flush(void *v, unsigned long buffer_size)
 51 {
 52         unsigned long end = decompressed_bytes + buffer_size;
 53         unsigned long size = buffer_size;
 54         unsigned long offset = 0;
 55         char *in = v;
 56         char *out;
 57 
 58         /*
 59          * if we hit our decompression limit, we need to fake an error to abort
 60          * the in-progress decompression.
 61          */
 62         if (decompressed_bytes >= limit)
 63                 return -1;
 64 
 65         /* skip this entire block */
 66         if (end <= skip) {
 67                 decompressed_bytes += buffer_size;
 68                 return buffer_size;
 69         }
 70 
 71         /* skip some data at the start, but keep the rest of the block */
 72         if (decompressed_bytes < skip && end > skip) {
 73                 offset = skip - decompressed_bytes;
 74 
 75                 in += offset;
 76                 size -= offset;
 77                 decompressed_bytes += offset;
 78         }
 79 
 80         out = &output_buffer[decompressed_bytes - skip];
 81         size = min(decompressed_bytes + size, limit) - decompressed_bytes;
 82 
 83         memcpy(out, in, size);
 84         decompressed_bytes += size;
 85 
 86         return buffer_size;
 87 }
 88 
 89 static void print_err(char *s)
 90 {
 91         /* suppress the "error" when we terminate the decompressor */
 92         if (decompressed_bytes >= limit)
 93                 return;
 94 
 95         printf("Decompression error: '%s'\n\r", s);
 96 }
 97 
 98 /**
 99  * partial_decompress - decompresses part or all of a compressed buffer
100  * @inbuf:       input buffer
101  * @input_size:  length of the input buffer
102  * @outbuf:      output buffer
103  * @output_size: length of the output buffer
104  * @_skip:       number of output bytes to ignore
105  *
106  * This function takes compressed data from inbuf, decompresses and write it to
107  * outbuf. Once output_size bytes are written to the output buffer, or the
108  * stream is exhausted the function will return the number of bytes that were
109  * decompressed. Otherwise it will return whatever error code the decompressor
110  * reported (NB: This is specific to each decompressor type).
111  *
112  * The skip functionality is mainly there so the program and discover
113  * the size of the compressed image so that it can ask firmware (if present)
114  * for an appropriately sized buffer.
115  */
116 long partial_decompress(void *inbuf, unsigned long input_size,
117         void *outbuf, unsigned long output_size, unsigned long _skip)
118 {
119         int ret;
120 
121         /*
122          * The skipped bytes needs to be included in the size of data we want
123          * to decompress.
124          */
125         output_size += _skip;
126 
127         decompressed_bytes = 0;
128         output_buffer = outbuf;
129         limit = output_size;
130         skip = _skip;
131 
132         ret = __decompress(inbuf, input_size, NULL, flush, outbuf,
133                 output_size, NULL, print_err);
134 
135         /*
136          * If decompression was aborted due to an actual error rather than
137          * a fake error that we used to abort, then we should report it.
138          */
139         if (decompressed_bytes < limit)
140                 return ret;
141 
142         return decompressed_bytes - skip;
143 }
144 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php