Move makerd to TOML-based manifest

Added the cpptoml library (and license), and moved to using that for
the initrd manifest. It's now possible to specify the `executable`
flag for files, and the kernel correctly only launches new processes
for the initrd files marked `executable`.
This commit is contained in:
Justin C. Miller
2018-09-08 12:54:35 -07:00
parent 3a39d9440a
commit e7a509176d
9 changed files with 3780 additions and 64 deletions

View File

@@ -2,7 +2,8 @@
Popcorn itself is released under the terms of the MIT license:
> Copyright © 2018 Justin C. Miller, http://devjustinian.com <justin@devjustinian.com>
> Copyright © 2018 Justin C. Miller, https://devjustinian.com
> <justin@devjustinian.com>
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the “Software”), to deal
@@ -19,8 +20,8 @@ Popcorn itself is released under the terms of the MIT license:
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
# Included works
@@ -28,7 +29,7 @@ Popcorn includes and/or is derived from a number of other works, listed here.
## Catch2
Popcorn uses [Catch2](http://github.com/catchorg/Catch2) for testing. Catch2 is
Popcorn uses [Catch2](https://github.com/catchorg/Catch2) for testing. Catch2 is
released under the terms of the Boost Software license:
> Boost Software License - Version 1.0 - August 17th, 2003
@@ -55,6 +56,67 @@ released under the terms of the Boost Software license:
> ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> DEALINGS IN THE SOFTWARE.
## cpptoml
Popcorn uses the [cpptoml](https://github.com/skystrife/cpptoml) library for
parsing TOML configuration files. cpptoml is released under the terms of the
MIT license:
> Copyright (c) 2014 Chase Geigle
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of
> this software and associated documentation files (the "Software"), to deal in
> the Software without restriction, including without limitation the rights to
> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
> the Software, and to permit persons to whom the Software is furnished to do so,
> subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## GNU-EFI
Popcorn's UEFI bootloader initially used
[GNU-EFI](https://gnu-efi.sourceforge.net), and still uses one file (the linker
script for the bootloader) from that project. GNU-EFI claims to be released
under the BSD license. Again, I could not find its specific license file, so I
am reproducing a generic 3-clause BSD license (the most restrictive, so as not
to assume any extra rights that may not actually be granted) for it here:
> Copyright © Nigel Croxon
>
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions are met:
>
> 1. Redistributions of source code must retain the above copyright notice, this
> list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright notice,
> this list of conditions and the following disclaimer in the documentation
> and/or other materials provided with the distribution.
>
> 3. Neither the name of the copyright holder nor the names of its contributors
> may be used to endorse or promote products derived from this software
> without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## Intel EFI Application Toolkit
Popcorn's UEFI loader uses code from Intel's EFI Application toolkit. Relevant
@@ -94,39 +156,3 @@ assume any extra rights that may not actually be granted) for it here:
> OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## GNU-EFI
Popcorn's UEFI bootloader initially used
[GNU-EFI](https://gnu-efi.sourceforge.net), and still uses one file (the linker
script for the bootloader) from that project. GNU-EFI claims to be released
under the BSD license. Again, I could not find its specific license file, so I
am reproducing a generic 3-clause BSD license (the most restrictive, so as not
to assume any extra rights that may not actually be granted) for it here:
> Copyright © Nigel Croxon
>
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions are met:
>
> 1. Redistributions of source code must retain the above copyright notice, this
> list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright notice,
> this list of conditions and the following disclaimer in the documentation
> and/or other materials provided with the distribution.
>
> 3. Neither the name of the copyright holder nor the names of its contributors
> may be used to endorse or promote products derived from this software
> without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,2 +0,0 @@
#assets/fonts/tamsyn8x16r.psf screenfont.psf
build/kernel/src/drivers/nulldrv/nulldrv nulldrv

18
assets/initrd.toml Normal file
View File

@@ -0,0 +1,18 @@
# This is the manifest for the initial ramdisk, read by the `makerd` tool.
# The contents should be a table array of files to add to the ramdistk:
#
# [[files]]
# dest = "foo.bar" # Name of the file in the ramdisk
# source = "build/foo/foo.bar" # Location of the file from the project root
# executable = true # Optional, default false. Whether this is an
# # initial application for the kernel to execute
# # on startup
[[files]]
dest = "screenfont.psf"
source = "assets/fonts/tamsyn8x16r.psf"
[[files]]
dest = "nulldrv"
source = "build/kernel/src/drivers/nulldrv/nulldrv"
executable = true

3658
src/include/cpptoml.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -83,7 +83,7 @@ kernel_main(popcorn_data *header)
initrd::disk ird(header->initrd);
log::info(logs::boot, "initrd loaded with %d files.", ird.files().count());
for (auto &f : ird.files())
log::info(logs::boot, " %s (%d bytes).", f.name(), f.size());
log::info(logs::boot, " %s%s (%d bytes).", f.executable() ? "*" : "", f.name(), f.size());
/*
pager->dump_pml4(nullptr, 0);
@@ -144,7 +144,7 @@ kernel_main(popcorn_data *header)
scheduler *sched = new (&scheduler::get()) scheduler(devices->get_lapic());
for (auto &f : ird.files()) {
//if (f.executable())
if (f.executable())
sched->create_process(f.name(), f.data(), f.size());
}

View File

@@ -1,7 +1,10 @@
#include "entry.h"
entry::entry(const std::string &in, const std::string &out) :
m_in(in), m_out(out), m_file(in, std::ios_base::binary)
entry::entry(const std::string &in, const std::string &out, bool executable) :
m_in(in),
m_out(out),
m_file(in, std::ios_base::binary),
m_exec(executable)
{
m_file.seekg(0, std::ios_base::end);
m_size = m_file.tellg();

View File

@@ -5,12 +5,13 @@
class entry
{
public:
entry(const std::string &in, const std::string &out);
entry(const std::string &in, const std::string &out, bool executable = false);
inline const std::string & in() const { return m_in; }
inline const std::string & out() const { return m_out; }
inline const std::ifstream & file() const { return m_file; }
inline bool executable() const { return m_exec; }
inline size_t size() const { return m_size; }
inline bool good() const { return m_file.good(); }
@@ -19,5 +20,6 @@ private:
std::string m_out;
std::ifstream m_file;
size_t m_size;
bool m_exec;
};

View File

@@ -3,6 +3,7 @@
#include <iostream>
#include <string>
#include <vector>
#include "cpptoml.h"
#include "initrd/headers.h"
#include "entry.h"
@@ -14,32 +15,37 @@ int main(int argc, char **argv)
}
std::vector<entry> entries;
std::ifstream manifest(argv[1]);
auto manifest = cpptoml::parse_file(argv[1]);
size_t files_size = 0;
size_t names_size = 0;
while (manifest.good()) {
std::string in, out;
auto files = manifest->get_table_array("files");
for (const auto &file : *files) {
auto dest = file->get_as<std::string>("dest");
if (!dest) {
std::cerr << "File has no destination!" << std::endl;
return 1;
}
manifest >> in;
if (in.length() < 1)
continue;
auto source = file->get_as<std::string>("source");
if (!source) {
std::cerr << "File " << *dest << " has no source!" << std::endl;
return 1;
}
manifest >> out;
if (in.front() == '#')
continue;
auto exec = file->get_as<bool>("executable").value_or(false);
entries.emplace_back(in, out);
entries.emplace_back(*source, *dest, exec);
const entry &e = entries.back();
if (!e.good()) {
std::cerr << "Error reading file: " << in << std::endl;
std::cerr << "Error reading file: " << *source << std::endl;
return 1;
}
files_size += e.size();
names_size += out.length() + 1;
names_size += dest->length() + 1;
}
std::fstream out(argv[2],
@@ -78,6 +84,9 @@ int main(int argc, char **argv)
fheader.length = e.size();
fheader.name_offset = name_offset;
if (e.executable())
fheader.flags |= initrd::file_flags::executable;
out.write(
reinterpret_cast<const char *>(&fheader),
sizeof(fheader));

12
wscript
View File

@@ -155,8 +155,6 @@ def configure(ctx):
ctx.env.append_value('CXXFLAGS', [
'-g',
'-std=c++14',
'-fno-exceptions',
'-fno-rtti',
])
ctx.env.append_value('ASFLAGS', ['-felf64'])
@@ -176,7 +174,11 @@ def configure(ctx):
ctx.setenv('kernel', env=base_bare)
ctx.env.append_value('CFLAGS', ['-mcmodel=large'])
ctx.env.append_value('CXXFLAGS', ['-mcmodel=large'])
ctx.env.append_value('CXXFLAGS', [
'-mcmodel=large',
'-fno-exceptions',
'-fno-rtti',
])
for mod_path in ctx.env.LIBRARIES:
ctx.recurse(mod_path)
@@ -195,7 +197,7 @@ def configure(ctx):
ctx.find_program("dd", var="dd")
common_configure(ctx)
ctx.env.CXXFLAGS = ['-g', '-std=c++14', '-fno-rtti']
ctx.env.CXXFLAGS = ['-g', '-std=c++14']
ctx.env.LINKFLAGS = ['-g']
for mod_path in ctx.env.LIBRARIES:
@@ -333,7 +335,7 @@ def build(bld):
make_rd = makerd(env = bld.env)
make_rd.set_inputs([
out['tools'].make_node(join("src", "tools", "makerd", "makerd")),
src.make_node(join("assets", "initrd.manifest")),
src.make_node(join("assets", "initrd.toml")),
])
make_rd.set_outputs([initrd])
bld.add_to_group(make_rd)