blob: 42d3a9056467dc0ed34d52cda31bccd8b302af71 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/bin/guest/vmm/kernel.h"
#include <fbl/unique_fd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
static inline bool is_within(uintptr_t x, uintptr_t addr, uintptr_t size) {
return x >= addr && x < addr + size;
}
zx_status_t load_kernel(const std::string& kernel_path,
const machina::PhysMem& phys_mem,
const uintptr_t kernel_off) {
fbl::unique_fd fd(open(kernel_path.c_str(), O_RDONLY));
if (!fd) {
FXL_LOG(ERROR) << "Failed to open kernel image " << kernel_path;
return ZX_ERR_IO;
}
struct stat stat;
ssize_t ret = fstat(fd.get(), &stat);
if (ret < 0) {
FXL_LOG(ERROR) << "Failed to stat kernel image";
return ZX_ERR_IO;
}
if (kernel_off + stat.st_size >= phys_mem.size()) {
FXL_LOG(ERROR) << "Kernel location is outside of guest physical memory";
return ZX_ERR_OUT_OF_RANGE;
}
if (is_within(kRamdiskOffset, kernel_off, stat.st_size)) {
FXL_LOG(ERROR) << "Kernel location overlaps RAM disk location";
return ZX_ERR_OUT_OF_RANGE;
}
ret =
read(fd.get(), phys_mem.as<void>(kernel_off, stat.st_size), stat.st_size);
if (ret != stat.st_size) {
FXL_LOG(ERROR) << "Failed to read kernel image";
return ZX_ERR_IO;
}
return ZX_OK;
}