• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2018 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "update_engine/payload_generator/boot_img_filesystem.h"
18 
19 #include <base/logging.h>
20 #include <brillo/secure_blob.h>
21 #include <puffin/utils.h>
22 
23 #include "update_engine/common/utils.h"
24 #include "update_engine/payload_generator/delta_diff_generator.h"
25 #include "update_engine/payload_generator/extent_ranges.h"
26 
27 using std::string;
28 using std::unique_ptr;
29 using std::vector;
30 
31 namespace chromeos_update_engine {
32 
CreateFromFile(const string & filename)33 unique_ptr<BootImgFilesystem> BootImgFilesystem::CreateFromFile(
34     const string& filename) {
35   if (filename.empty())
36     return nullptr;
37 
38   brillo::Blob header;
39   if (!utils::ReadFileChunk(filename, 0, sizeof(boot_img_hdr), &header) ||
40       header.size() != sizeof(boot_img_hdr) ||
41       memcmp(header.data(), BOOT_MAGIC, BOOT_MAGIC_SIZE) != 0) {
42     return nullptr;
43   }
44 
45   unique_ptr<BootImgFilesystem> result(new BootImgFilesystem());
46   result->filename_ = filename;
47   memcpy(&result->hdr_, header.data(), header.size());
48   return result;
49 }
50 
GetBlockSize() const51 size_t BootImgFilesystem::GetBlockSize() const {
52   // Page size may not be 4K, but we currently only support 4K block size.
53   return kBlockSize;
54 }
55 
GetBlockCount() const56 size_t BootImgFilesystem::GetBlockCount() const {
57   return utils::DivRoundUp(utils::FileSize(filename_), kBlockSize);
58 }
59 
GetFile(const string & name,uint64_t offset,uint64_t size) const60 FilesystemInterface::File BootImgFilesystem::GetFile(const string& name,
61                                                      uint64_t offset,
62                                                      uint64_t size) const {
63   File file;
64   file.name = name;
65   file.extents = {ExtentForBytes(kBlockSize, offset, size)};
66 
67   brillo::Blob data;
68   if (utils::ReadFileChunk(filename_, offset, size, &data)) {
69     constexpr size_t kGZipHeaderSize = 10;
70     // Check GZip header magic.
71     if (data.size() > kGZipHeaderSize && data[0] == 0x1F && data[1] == 0x8B) {
72       if (!puffin::LocateDeflatesInGzip(data, &file.deflates)) {
73         LOG(ERROR) << "Error occurred parsing gzip " << name << " at offset "
74                    << offset << " of " << filename_ << ", found "
75                    << file.deflates.size() << " deflates.";
76         return file;
77       }
78       for (auto& deflate : file.deflates) {
79         deflate.offset += offset * 8;
80       }
81     }
82   }
83   return file;
84 }
85 
GetFiles(vector<File> * files) const86 bool BootImgFilesystem::GetFiles(vector<File>* files) const {
87   files->clear();
88   const uint64_t file_size = utils::FileSize(filename_);
89   // The first page is header.
90   uint64_t offset = hdr_.page_size;
91   if (hdr_.kernel_size > 0 && offset + hdr_.kernel_size <= file_size) {
92     files->emplace_back(GetFile("<kernel>", offset, hdr_.kernel_size));
93   }
94   offset += utils::RoundUp(hdr_.kernel_size, hdr_.page_size);
95   if (hdr_.ramdisk_size > 0 && offset + hdr_.ramdisk_size <= file_size) {
96     files->emplace_back(GetFile("<ramdisk>", offset, hdr_.ramdisk_size));
97   }
98   return true;
99 }
100 
LoadSettings(brillo::KeyValueStore * store) const101 bool BootImgFilesystem::LoadSettings(brillo::KeyValueStore* store) const {
102   return false;
103 }
104 
105 }  // namespace chromeos_update_engine
106