1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "zbi.h" 6 7#include <libzbi/zbi-zx.h> 8#include <stdio.h> 9#include <zircon/status.h> 10 11zx_status_t netboot_prepare_zbi(zx_handle_t nbkernel_vmo, 12 zx_handle_t nbbootdata_vmo, 13 const uint8_t* cmdline, uint32_t cmdline_size, 14 dmctl_mexec_args_t* args) { 15 zbi::ZbiVMO kernel, data; 16 17 if (nbkernel_vmo == ZX_HANDLE_INVALID) { 18 printf("netbootloader: no kernel!\n"); 19 return ZX_ERR_INVALID_ARGS; 20 } 21 22 if (nbbootdata_vmo == ZX_HANDLE_INVALID) { 23 // Split the complete ZBI into its kernel and data parts. 24 zbi::ZbiVMO zbi; 25 auto status = zbi.Init(zx::vmo{nbkernel_vmo}); 26 if (status != ZX_OK) { 27 printf("netbootloader: can't map complete ZBI: %d (%s)\n", 28 status, zx_status_get_string(status)); 29 return status; 30 } 31 auto result = zbi.SplitComplete(&kernel, &data); 32 if (result != ZBI_RESULT_OK) { 33 printf("netbootloader: invalid complete ZBI: %d\n", result); 34 return ZX_ERR_INTERNAL; 35 } 36 } else { 37 // Old-style boot with separate kernel and data ZBIs. 38 printf("netbootloader: old-style boot is deprecated;" 39 " switch to complete ZBI!\n"); 40 auto status = kernel.Init(zx::vmo{nbkernel_vmo}); 41 if (status != ZX_OK) { 42 printf("netbootloader: can't map kernel ZBI: %d (%s)\n", 43 status, zx_status_get_string(status)); 44 return status; 45 } 46 status = data.Init(zx::vmo{nbbootdata_vmo}); 47 if (status != ZX_OK) { 48 printf("netbootloader: can't map kernel ZBI: %d (%s)\n", 49 status, zx_status_get_string(status)); 50 return status; 51 } 52 } 53 54 if (cmdline_size > 0) { 55 auto result = data.AppendSection(cmdline_size, ZBI_TYPE_CMDLINE, 0, 0, 56 cmdline); 57 if (result != ZBI_RESULT_OK) { 58 printf("netbootloader: failed to append command line: %d\n", 59 result); 60 return ZX_ERR_INTERNAL; 61 } 62 } 63 64 printf("netbootloader: kernel ZBI %#x bytes data ZBI %#x bytes\n", 65 kernel.Length(), data.Length()); 66 67 args->kernel = kernel.Release().release(); 68 args->bootdata = data.Release().release(); 69 return ZX_OK; 70} 71