[bootproto] Create new bootproto lib

This is a rather large commit that is widely focused on cleaning things
out of the 'junk drawer' that is src/include. Most notably, several
things that were put in there because they needed somewhere where both
the kernel, boot, and init could read them have been moved to a new lib,
'bootproto'.

- Moved kernel_args.h and init_args.h to bootproto as kernel.h and
  init.h, respectively.

- Moved counted.h and pointer_manipulation.h into util, renaming the
  latter to util/pointers.h.

- Created a new src/include/arch for very arch-dependent definitions,
  and moved some kernel_memory.h constants like frame size, page table
  entry count, etc to arch/amd64/memory.h. Also created arch/memory.h
  which detects platform and includes the former.

- Got rid of kernel_memory.h entirely in favor of a new, cog-based
  approach. The new definitions/memory_layout.csv lists memory regions
  in descending order from the top of memory, their sizes, and whether
  they are shared outside the kernel (ie, boot needs to know them). The
  new header bootproto/memory.h exposes the addresses of the shared
  regions, while the kernel's memory.h gains the start and size of all
  the regions. Also renamed the badly-named page-offset area the linear
  area.

- The python build scripts got a few new features: the ability to parse
  the csv mentioned above in a new memory.py module; the ability to add
  dependencies to existing source files (The list of files that I had to
  pull out of the main list just to add them with the dependency on
  memory.h was getting too large. So I put them back into the sources
  list, and added the dependency post-hoc.); and the ability to
  reference 'source_root', 'build_root', and 'module_root' variables in
  .module files.

- Some utility functions that were in the kernel's memory.h got moved to
  util/pointers.h and util/misc.h, and misc.h's byteswap was renamed
  byteswap32 to be more specific.
This commit is contained in:
Justin C. Miller
2022-01-03 17:44:13 -08:00
parent cd9b85b555
commit c1d9b35e7c
71 changed files with 623 additions and 496 deletions

View File

@@ -0,0 +1,50 @@
#pragma once
/// \file counted.h
/// Definition of the `counted` template class
#include <util/pointers.h>
namespace util {
/// A pointer and an associated count. Memory pointed to is not managed.
/// Depending on the usage, the count may be size or number of elements.
/// Helper methods provide the ability to treat the pointer like an array.
template <typename T>
struct counted
{
T *pointer;
size_t count;
/// Index this object as an array of type T
inline T & operator [] (int i) { return pointer[i]; }
/// Index this object as a const array of type T
inline const T & operator [] (int i) const { return pointer[i]; }
using iterator = offset_iterator<T>;
using const_iterator = const_offset_iterator<T>;
/// Return an iterator to the beginning of the array
inline iterator begin() { return iterator(pointer, sizeof(T)); }
/// Return an iterator to the end of the array
inline iterator end() { return offset_pointer<T>(pointer, sizeof(T)*count); }
/// Return an iterator to the beginning of the array
inline const_iterator begin() const { return const_iterator(pointer, sizeof(T)); }
/// Return an iterator to the end of the array
inline const_iterator end() const { return offset_pointer<const T>(pointer, sizeof(T)*count); }
};
/// Specialize for `void` which cannot be indexed or iterated
template <>
struct counted<void>
{
void *pointer;
size_t count;
};
using buffer = counted<void>;
} // namespace util

View File

@@ -2,11 +2,23 @@
namespace util {
/// Reverse the order of bytes in a 32 bit integer
constexpr uint32_t
byteswap(uint32_t x)
{
byteswap32(uint32_t x) {
return ((x >> 24) & 0x000000ff) | ((x >> 8) & 0x0000ff00)
| ((x << 8) & 0x00ff0000) | ((x << 24) & 0xff000000);
}
/// Do a simple byte-wise checksum of an area of memory. The area
/// summed will be the bytes at indicies [off, len).
/// \arg p The start of the memory region
/// \arg len The number of bytes in the region
/// \arg off An optional offset into the region
uint8_t checksum(const void *p, size_t len, size_t off = 0) {
uint8_t sum = 0;
const uint8_t *c = reinterpret_cast<const uint8_t *>(p);
for (size_t i = off; i < len; ++i) sum += c[i];
return sum;
}
}

View File

@@ -0,0 +1,95 @@
/// \file pointers.h
/// Helper functions and types for doing type-safe byte-wise pointer math.
#pragma once
#include <stddef.h>
#include <stdint.h>
namespace util {
/// Return a pointer offset from `input` by `offset` bytes.
/// \arg input The original pointer
/// \arg offset Offset `input` by this many bytes
template <typename T>
inline T* offset_pointer(T* input, ptrdiff_t offset) {
return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(input) + offset);
}
/// Return a pointer with the given bits masked out
/// \arg input The original pointer
/// \arg mask A bitmask of bits to clear from p
/// \returns The masked pointer
template <typename T>
inline T* mask_pointer(T *input, uintptr_t mask) {
return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(input) & ~mask);
}
/// Read a value of type T from a location in memory
/// \arg p The location in memory to read
/// \returns The value at the given location cast to T
template <typename T>
inline T read_from(const void *p) {
return *reinterpret_cast<const T *>(p);
}
/// Iterator for an array of `const T` whose size is known at runtime
/// \tparam T Type of the objects in the array, whose size might not be
/// what is returned by sizeof(T).
template <typename T>
class const_offset_iterator
{
public:
/// Constructor.
/// \arg t Pointer to the first item in the array
/// \arg off Offset applied to reach successive items. Default is 0,
/// which creates an effectively constant iterator.
const_offset_iterator(T const *t, size_t off=0) : m_t(t), m_off(off) {}
const T * operator++() { m_t = offset_pointer(m_t, m_off); return m_t; }
const T * operator++(int) { T* tmp = m_t; operator++(); return tmp; }
bool operator==(T* p) const { return p == m_t; }
bool operator!=(T* p) const { return p != m_t; }
bool operator==(const_offset_iterator<T> &i) const { return i.m_t == m_t; }
bool operator!=(const_offset_iterator<T> &i) const { return i.m_t != m_t; }
const T& operator*() const { return *m_t; }
operator const T& () const { return *m_t; }
const T* operator->() const { return m_t; }
private:
T const *m_t;
size_t m_off;
};
/// iterator for an array of `const T` whose size is known at runtime
/// \tparam T type of the objects in the array, whose size might not be
/// what is returned by sizeof(T).
template <typename T>
class offset_iterator
{
public:
/// constructor.
/// \arg t pointer to the first item in the array
/// \arg off offset applied to reach successive items. default is 0,
/// which creates an effectively constant iterator.
offset_iterator(T *t, size_t off=0) : m_t(t), m_off(off) {}
T * operator++() { m_t = offset_pointer(m_t, m_off); return m_t; }
T * operator++(int) { T* tmp = m_t; operator++(); return tmp; }
bool operator==(T *p) const { return p == m_t; }
bool operator!=(T *p) const { return p != m_t; }
bool operator==(offset_iterator<T> &i) const { return i.m_t == m_t; }
bool operator!=(offset_iterator<T> &i) const { return i.m_t != m_t; }
T & operator*() const { return *m_t; }
operator T & () const { return *m_t; }
T * operator->() const { return m_t; }
private:
T *m_t;
size_t m_off;
};
} // namespace util