iPXE
Functions
lkrn.c File Reference

Linux kernel image format. More...

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/image.h>
#include <ipxe/memmap.h>
#include <ipxe/uaccess.h>
#include <ipxe/segment.h>
#include <ipxe/initrd.h>
#include <ipxe/io.h>
#include <ipxe/fdt.h>
#include <ipxe/init.h>
#include <ipxe/lkrn.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int lkrn_parse (struct image *image, struct lkrn_context *ctx)
 Parse kernel image. More...
 
static int lkrn_ram (struct image *image, struct lkrn_context *ctx)
 Locate start of RAM. More...
 
static int lkrn_exec (struct image *image)
 Execute kernel image. More...
 
static int lkrn_probe (struct image *image)
 Probe kernel image. More...
 
struct image_type lkrn_image_type __image_type (PROBE_NORMAL)
 Linux kernel image type. More...
 
static int zimg_parse (struct image *image, struct zimg_context *zctx)
 Parse compressed kernel image. More...
 
static int zimg_extract (struct image *image, struct image *extracted)
 Extract compresed kernel image. More...
 
static int zimg_probe (struct image *image)
 Probe compressed kernel image. More...
 

Detailed Description

Linux kernel image format.

Definition in file lkrn.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ lkrn_parse()

static int lkrn_parse ( struct image image,
struct lkrn_context ctx 
)
static

Parse kernel image.

Parameters
imageKernel image
ctxKernel image context
Return values
rcReturn status code

Definition at line 53 of file lkrn.c.

53  {
54  const struct lkrn_header *hdr;
55 
56  /* Initialise context */
57  memset ( ctx, 0, sizeof ( *ctx ) );
58 
59  /* Read image header */
60  if ( image->len < sizeof ( *hdr ) ) {
61  DBGC ( image, "LKRN %s too short for header\n", image->name );
62  return -ENOEXEC;
63  }
64  hdr = image->data;
65 
66  /* Check magic value */
67  if ( hdr->magic != cpu_to_le32 ( LKRN_MAGIC_ARCH ) ) {
68  DBGC ( image, "LKRN %s bad magic value %#08x\n",
69  image->name, le32_to_cpu ( hdr->magic ) );
70  return -ENOEXEC;
71  }
72 
73  /* Record load offset */
74  ctx->offset = le64_to_cpu ( hdr->text_offset );
75  if ( ctx->offset & ( ctx->offset - 1 ) ) {
76  DBGC ( image, "LKRN %s offset %#zx is not a power of two\n",
77  image->name, ctx->offset );
78  return -ENOEXEC;
79  }
80 
81  /* Record and check image size */
82  ctx->filesz = image->len;
83  ctx->memsz = le64_to_cpu ( hdr->image_size );
84  if ( ctx->filesz > ctx->memsz ) {
85  DBGC ( image, "LKRN %s invalid image size %#zx/%#zx\n",
86  image->name, ctx->filesz, ctx->memsz );
87  return -ENOEXEC;
88  }
89 
90  return 0;
91 }
#define le32_to_cpu(value)
Definition: byteswap.h:113
const void * data
Read-only data.
Definition: image.h:50
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define cpu_to_le32(value)
Definition: byteswap.h:107
size_t len
Length of raw file image.
Definition: image.h:55
Kernel image header.
Definition: lkrn.h:15
#define LKRN_MAGIC_ARCH
Definition: lkrn.h:15
#define le64_to_cpu(value)
Definition: byteswap.h:114
char * name
Name.
Definition: image.h:37
void * memset(void *dest, int character, size_t len) __nonnull

References cpu_to_le32, ctx, image::data, DBGC, ENOEXEC, hdr, le32_to_cpu, le64_to_cpu, image::len, LKRN_MAGIC_ARCH, memset(), and image::name.

Referenced by lkrn_exec(), and lkrn_probe().

◆ lkrn_ram()

static int lkrn_ram ( struct image image,
struct lkrn_context ctx 
)
static

Locate start of RAM.

Parameters
imageKernel image
ctxKernel image context
Return values
rcReturn status code

Definition at line 100 of file lkrn.c.

100  {
101  struct memmap_region region;
102 
103  /* Locate start of RAM */
104  for_each_memmap ( &region, 0 ) {
105  DBGC_MEMMAP ( image, &region );
106  if ( ! ( region.flags & MEMMAP_FL_MEMORY ) )
107  continue;
108  ctx->ram = region.min;
109  DBGC ( image, "LKRN %s RAM starts at %#08lx\n",
110  image->name, ctx->ram );
111  return 0;
112  }
113 
114  DBGC ( image, "LKRN %s found no RAM\n", image->name );
115  return -ENOTSUP;
116 }
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define DBGC_MEMMAP(...)
Definition: memmap.h:206
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define for_each_memmap(region, hide)
Iterate over memory regions.
Definition: memmap.h:183
#define MEMMAP_FL_MEMORY
Contains memory.
Definition: memmap.h:59
A memory region descriptor.
Definition: memmap.h:48
char * name
Name.
Definition: image.h:37

References ctx, DBGC, DBGC_MEMMAP, ENOTSUP, memmap_region::flags, for_each_memmap, MEMMAP_FL_MEMORY, memmap_region::min, and image::name.

Referenced by lkrn_exec().

◆ lkrn_exec()

static int lkrn_exec ( struct image image)
static

Execute kernel image.

Parameters
imageKernel image
Return values
rcReturn status code

Definition at line 124 of file lkrn.c.

124  {
125  static struct image fdtimg = {
126  .refcnt = REF_INIT ( free_image ),
127  .name = "<FDT>",
128  .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ),
129  };
130  struct lkrn_context ctx;
131  struct memmap_region region;
132  struct fdt_header *fdt;
133  size_t initrdsz;
134  size_t totalsz;
135  void *dest;
136  int rc;
137 
138  /* Parse header */
139  if ( ( rc = lkrn_parse ( image, &ctx ) ) != 0 )
140  goto err_parse;
141 
142  /* Locate start of RAM */
143  if ( ( rc = lkrn_ram ( image, &ctx ) ) != 0 )
144  goto err_ram;
145 
146  /* Place kernel at specified address from start of RAM */
147  ctx.entry = ( ctx.ram + ctx.offset );
148  DBGC ( image, "LKRN %s loading to [%#08lx,%#08lx,%#08lx)\n",
149  image->name, ctx.entry, ( ctx.entry + ctx.filesz ),
150  ( ctx.entry + ctx.memsz ) );
151 
152  /* Place initrd after kernel, aligned to the kernel's image offset */
153  ctx.initrd = ( ctx.ram + initrd_align ( ctx.offset + ctx.memsz ) );
154  ctx.initrd = ( ( ctx.initrd + ctx.offset - 1 ) & ~( ctx.offset - 1 ) );
155  initrdsz = initrd_len();
156  if ( initrdsz ) {
157  DBGC ( image, "LKRN %s initrd at [%#08lx,%#08lx)\n",
158  image->name, ctx.initrd, ( ctx.initrd + initrdsz ) );
159  }
160 
161  /* Place device tree after initrd */
162  ctx.fdt = ( ctx.initrd + initrd_align ( initrdsz ) );
163 
164  /* Construct device tree and post-initrd image */
165  if ( ( rc = fdt_create ( &fdt, image->cmdline, ctx.initrd,
166  initrdsz ) ) != 0 ) {
167  goto err_fdt;
168  }
169  fdtimg.data = fdt;
170  fdtimg.len = be32_to_cpu ( fdt->totalsize );
171  list_add_tail ( &fdtimg.list, &images );
172  DBGC ( image, "LKRN %s FDT at [%08lx,%08lx)\n",
173  image->name, ctx.fdt, ( ctx.fdt + fdtimg.len ) );
174 
175  /* Find post-reshuffle region */
176  if ( ( rc = initrd_region ( initrdsz, &region ) ) != 0 ) {
177  DBGC ( image, "LKRN %s no available region: %s\n",
178  image->name, strerror ( rc ) );
179  goto err_region;
180  }
181 
182  /* Check that everything can be placed at its target addresses */
183  totalsz = ( ctx.fdt + fdtimg.len - ctx.ram );
184  if ( ( ctx.entry >= region.min ) &&
185  ( ( ctx.offset + totalsz ) <= memmap_size ( &region ) ) ) {
186  /* Target addresses are within the reshuffle region */
187  DBGC ( image, "LKRN %s fits within reshuffle region\n",
188  image->name );
189  } else {
190  /* Target addresses are outside the reshuffle region */
191  if ( ( rc = prep_segment ( phys_to_virt ( ctx.entry ),
192  totalsz, totalsz ) ) != 0 ) {
193  DBGC ( image, "LKRN %s could not prepare segment: "
194  "%s\n", image->name, strerror ( rc ) );
195  goto err_segment;
196  }
197  }
198 
199  /* This is the point of no return: we are about to reshuffle
200  * and thereby destroy the external heap. No errors are
201  * allowed to occur after this point.
202  */
203 
204  /* Shut down ready for boot */
205  shutdown_boot();
206 
207  /* Prepend kernel to reshuffle list, reshuffle, and remove kernel */
208  list_add ( &image->list, &images );
210  list_del ( &image->list );
211 
212  /* Load kernel to entry point and zero bss */
213  dest = phys_to_virt ( ctx.entry );
214  memmove ( dest, image->data, ctx.filesz );
215  memset ( ( dest + ctx.filesz ), 0, ( ctx.memsz - ctx.filesz ) );
216 
217  /* Load initrds and device tree */
218  dest = phys_to_virt ( ctx.initrd );
219  initrd_load_all ( dest );
220 
221  /* Jump to kernel entry point */
222  DBGC ( image, "LKRN %s jumping to kernel at %#08lx\n",
223  image->name, ctx.entry );
224  lkrn_jump ( ctx.entry, ctx.fdt );
225 
226  /* There is no way for the image to return, since we provide
227  * no return address.
228  */
229  assert ( 0 );
230 
231  return -ECANCELED; /* -EIMPOSSIBLE */
232 
233  err_segment:
234  err_region:
235  list_del ( &fdtimg.list );
236  fdt_remove ( fdt );
237  err_fdt:
238  err_ram:
239  err_parse:
240  return rc;
241 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
const void * data
Read-only data.
Definition: image.h:50
Device tree header.
Definition: fdt.h:18
Kernel image context.
Definition: lkrn.h:43
#define DBGC(...)
Definition: compiler.h:505
int initrd_region(size_t len, struct memmap_region *region)
Calculate post-reshuffle initrd load region.
Definition: initrd.c:354
An executable image.
Definition: image.h:23
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static size_t initrd_align(size_t len)
Align initrd length.
Definition: initrd.h:29
void initrd_reshuffle(void)
Reshuffle initrds into desired order at top of memory.
Definition: initrd.c:229
#define ECANCELED
Operation canceled.
Definition: errno.h:343
char * cmdline
Command line to pass to image.
Definition: image.h:42
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void free_image(struct refcnt *refcnt)
Free executable image.
Definition: image.c:85
static int lkrn_ram(struct image *image, struct lkrn_context *ctx)
Locate start of RAM.
Definition: lkrn.c:100
#define IMAGE_STATIC
Image is statically allocated.
Definition: image.h:88
#define be32_to_cpu(value)
Definition: byteswap.h:116
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
size_t initrd_load_all(void *address)
Load all initrds.
Definition: initrd.c:317
void fdt_remove(struct fdt_header *hdr)
Remove device tree.
Definition: fdt.c:1458
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void lkrn_jump(physaddr_t entry, physaddr_t fdt)
Jump to kernel entry point.
size_t len
Length of raw file image.
Definition: image.h:55
struct list_head images
List of registered images.
Definition: image.c:58
void * memmove(void *dest, const void *src, size_t len) __nonnull
A device tree.
Definition: fdt.h:88
static int lkrn_parse(struct image *image, struct lkrn_context *ctx)
Parse kernel image.
Definition: lkrn.c:53
static uint64_t memmap_size(const struct memmap_region *region)
Get remaining size of memory region (from the described address upwards)
Definition: memmap.h:98
#define IMAGE_STATIC_NAME
Image name is statically allocated.
Definition: image.h:91
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
Definition: string.h:150
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:77
int prep_segment(void *segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition: segment.c:61
A memory region descriptor.
Definition: memmap.h:48
struct list_head list
List of registered images.
Definition: image.h:28
static void shutdown_boot(void)
Shut down system for OS boot.
Definition: init.h:77
int fdt_create(struct fdt_header **hdr, const char *cmdline, physaddr_t initrd, size_t initrd_len)
Create device tree.
Definition: fdt.c:1407
char * name
Name.
Definition: image.h:37
void * memset(void *dest, int character, size_t len) __nonnull
#define initrd_len
Definition: runtime.c:63
struct refcnt refcnt
Reference count.
Definition: image.h:25

References assert(), be32_to_cpu, image::cmdline, ctx, image::data, DBGC, dest, ECANCELED, fdt_create(), fdt_remove(), free_image(), IMAGE_STATIC, IMAGE_STATIC_NAME, images, initrd_align(), initrd_len, initrd_load_all(), initrd_region(), initrd_reshuffle(), image::len, image::list, list_add, list_add_tail, list_del, lkrn_jump(), lkrn_parse(), lkrn_ram(), memmap_size(), memmove(), memset(), memmap_region::min, image::name, prep_segment(), rc, REF_INIT, image::refcnt, shutdown_boot(), and strerror().

◆ lkrn_probe()

static int lkrn_probe ( struct image image)
static

Probe kernel image.

Parameters
imageKernel image
Return values
rcReturn status code

Definition at line 249 of file lkrn.c.

249  {
250  struct lkrn_context ctx;
251  int rc;
252 
253  /* Parse header */
254  if ( ( rc = lkrn_parse ( image, &ctx ) ) != 0 )
255  return rc;
256 
257  DBGC ( image, "LKRN %s is a Linux kernel\n", image->name );
258  return 0;
259 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Kernel image context.
Definition: lkrn.h:43
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static int lkrn_parse(struct image *image, struct lkrn_context *ctx)
Parse kernel image.
Definition: lkrn.c:53
char * name
Name.
Definition: image.h:37

References ctx, DBGC, lkrn_parse(), image::name, and rc.

◆ __image_type()

struct image_type lkrn_image_type __image_type ( PROBE_NORMAL  )

Linux kernel image type.

Linux kernel compressed image type.

◆ zimg_parse()

static int zimg_parse ( struct image image,
struct zimg_context zctx 
)
static

Parse compressed kernel image.

Parameters
imageCompressed kernel image
zctxCompressed kernel image context
Return values
rcReturn status code

Definition at line 275 of file lkrn.c.

275  {
276  const struct zimg_header *zhdr;
277 
278  /* Initialise context */
279  memset ( zctx, 0, sizeof ( *zctx ) );
280 
281  /* Parse header */
282  if ( image->len < sizeof ( *zhdr ) ) {
283  DBGC ( image, "ZIMG %s too short for header\n",
284  image->name );
285  return -ENOEXEC;
286  }
287  zhdr = image->data;
288 
289  /* Check magic value */
290  if ( zhdr->magic != cpu_to_le32 ( ZIMG_MAGIC ) ) {
291  DBGC ( image, "ZIMG %s bad magic value %#08x\n",
292  image->name, le32_to_cpu ( zhdr->magic ) );
293  return -ENOEXEC;
294  }
295 
296  /* Record and check offset and length */
297  zctx->offset = le32_to_cpu ( zhdr->offset );
298  zctx->len = le32_to_cpu ( zhdr->len );
299  if ( ( zctx->offset > image->len ) ||
300  ( zctx->len > ( image->len - zctx->offset ) ) ) {
301  DBGC ( image, "ZIMG %s bad range [+%#zx,+%#zx)/%#zx\n",
302  image->name, zctx->offset,
303  (zctx->offset + zctx->len ), image->len );
304  return -ENOEXEC;
305  }
306 
307  /* Record compression type */
308  zctx->type.raw = zhdr->type;
309 
310  return 0;
311 }
size_t offset
Offset to compressed data.
Definition: lkrn.h:83
uint32_t offset
Offset to payload.
Definition: lkrn.h:68
#define le32_to_cpu(value)
Definition: byteswap.h:113
const void * data
Read-only data.
Definition: image.h:50
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
uint32_t magic
Magic.
Definition: lkrn.h:66
Compressed kernel image header.
Definition: lkrn.h:62
uint32_t type
Compression type.
Definition: lkrn.h:74
#define cpu_to_le32(value)
Definition: byteswap.h:107
union zimg_context::@637 type
Compression type.
size_t len
Length of raw file image.
Definition: image.h:55
uint32_t len
Length of payload.
Definition: lkrn.h:70
#define ZIMG_MAGIC
Compressed kernel image magic value.
Definition: lkrn.h:78
size_t len
Length of compressed data.
Definition: lkrn.h:85
uint32_t raw
Raw type.
Definition: lkrn.h:89
char * name
Name.
Definition: image.h:37
void * memset(void *dest, int character, size_t len) __nonnull

References cpu_to_le32, image::data, DBGC, ENOEXEC, le32_to_cpu, image::len, zimg_header::len, zimg_context::len, zimg_header::magic, memset(), image::name, zimg_header::offset, zimg_context::offset, zimg_context::raw, zimg_header::type, zimg_context::type, and ZIMG_MAGIC.

Referenced by zimg_extract(), and zimg_probe().

◆ zimg_extract()

static int zimg_extract ( struct image image,
struct image extracted 
)
static

Extract compresed kernel image.

Parameters
imageCompressed kernel image
extractedExtracted image
Return values
rcReturn status code

Definition at line 320 of file lkrn.c.

320  {
321  struct zimg_context zctx;
322  const void *payload;
323  int rc;
324 
325  /* Parse header */
326  if ( ( rc = zimg_parse ( image, &zctx ) ) != 0 )
327  return rc;
328  DBGC ( image, "ZIMG %s has %s-compressed payload at [+%#zx,+%#zx)\n",
329  image->name, zctx.type.string, zctx.offset,
330  ( zctx.offset + zctx.len ) );
331 
332  /* Extract compressed payload */
333  payload = ( image->data + zctx.offset );
334  if ( ( rc = image_set_data ( extracted, payload, zctx.len ) ) != 0 ) {
335  DBGC ( image, "ZIMG %s could not extract: %s\n",
336  image->name, strerror ( rc ) );
337  return rc;
338  }
339 
340  return 0;
341 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const void * data
Read-only data.
Definition: image.h:50
#define DBGC(...)
Definition: compiler.h:505
Compressed kernel image context.
Definition: lkrn.h:81
An executable image.
Definition: image.h:23
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int image_set_data(struct image *image, const void *data, size_t len)
Set image data.
Definition: image.c:269
char * name
Name.
Definition: image.h:37
static int zimg_parse(struct image *image, struct zimg_context *zctx)
Parse compressed kernel image.
Definition: lkrn.c:275

References image::data, DBGC, image_set_data(), zimg_context::len, image::name, zimg_context::offset, rc, strerror(), zimg_context::string, zimg_context::type, and zimg_parse().

◆ zimg_probe()

static int zimg_probe ( struct image image)
static

Probe compressed kernel image.

Parameters
imageCompressed kernel image
Return values
rcReturn status code

Definition at line 349 of file lkrn.c.

349  {
350  struct zimg_context zctx;
351  int rc;
352 
353  /* Parse header */
354  if ( ( rc = zimg_parse ( image, &zctx ) ) != 0 )
355  return rc;
356 
357  DBGC ( image, "ZIMG %s is a %s-compressed Linux kernel\n",
358  image->name, zctx.type.string );
359  return 0;
360 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
Compressed kernel image context.
Definition: lkrn.h:81
An executable image.
Definition: image.h:23
char * name
Name.
Definition: image.h:37
static int zimg_parse(struct image *image, struct zimg_context *zctx)
Parse compressed kernel image.
Definition: lkrn.c:275

References DBGC, image::name, rc, zimg_context::string, zimg_context::type, and zimg_parse().