Skip to content

Commit 4217fd6

Browse files
committed
Merge ukvm64
2 parents 89b6d3c + 273172c commit 4217fd6

41 files changed

Lines changed: 1679 additions & 196 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ install(PROGRAMS
213213
${CMAKE_CURRENT_SOURCE_DIR}/etc/scripts/grubify.sh
214214
${CMAKE_CURRENT_SOURCE_DIR}/etc/scripts/qemu-ifup
215215
${CMAKE_CURRENT_SOURCE_DIR}/etc/scripts/qemu_cmd.sh
216+
${CMAKE_CURRENT_SOURCE_DIR}/etc/scripts/ukvm-ifup.sh
216217
${CMAKE_CURRENT_SOURCE_DIR}/etc/scripts/run.sh
217218
DESTINATION includeos/scripts)
218219

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ More information is [available on the wiki](https://github.com/hioa-cs/IncludeOS
9797

9898
### Writing your first service
9999

100-
1. Copy the [./seed/service](./seed/service) directory to a convenient location like `~/your_service`. Then, just start implementing the `Service::start` function in the `Service` class, located in [your_service/service.cpp](./seed/service/service.cpp) (Very simple example provided). This function will be called once the OS is up and running.
100+
1. Copy the [./seed/service](./seed/service) directory to a convenient location like `~/your_service`. Then, just start implementing the `Service::start` function in the `Service` class, located in [your_service/service.cpp](./seed/service/service.cpp) (very simple example provided). This function will be called once the OS is up and running.
101101
2. Update the [CMakeLists.txt](./seed/service/CMakeLists.txt) to specify the name of your project, enable any needed drivers or plugins, etc.
102102

103103
**Example:**

api/hw/mac_addr.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,29 @@ union Addr {
6464
: part{a,b,c,d,e,f}
6565
{}
6666

67+
static uint8_t dehex(char c)
68+
{
69+
if (c >= '0' && c <= '9')
70+
return (c - '0');
71+
else if (c >= 'a' && c <= 'f')
72+
return 10 + (c - 'a');
73+
else if (c >= 'A' && c <= 'F')
74+
return 10 + (c - 'A');
75+
else
76+
return 0;
77+
}
78+
79+
Addr(const char *smac) noexcept
80+
{
81+
uint8_t macaddr[PARTS_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
82+
for (size_t i = 0; i < PARTS_LEN; i++) {
83+
macaddr[i] = dehex(*smac++) << 4;
84+
macaddr[i] |= dehex(*smac++);
85+
smac++;
86+
}
87+
memcpy(part, macaddr, PARTS_LEN);
88+
}
89+
6790
/**
6891
* Assignment operator
6992
*

api/hw/nic.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ namespace hw {
100100
virtual void flush() = 0;
101101

102102
virtual ~Nic() {}
103+
104+
/** Trigger a read from buffers, pusing any packets up the stack */
105+
virtual void poll() = 0;
106+
103107
protected:
104108
/**
105109
* Constructor

api/hw/pci_device.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ namespace PCI {
4444

4545
static const uint32_t WTF {~0x0U};
4646

47+
static const uint32_t SOLO5_NET_DUMMY_ADDR {0xFFFE};
48+
static const uint32_t SOLO5_BLK_DUMMY_ADDR {0xFFFF};
49+
4750
/**
4851
* @brief PCI device message format
4952
*
@@ -103,6 +106,7 @@ namespace PCI {
103106
VENDOR_VIRTIO = 0x1AF4,
104107
VENDOR_REALTEK = 0x10EC,
105108
VENDOR_VMWARE = 0x15AD,
109+
VENDOR_SOLO5 = 0x5050,
106110
};
107111

108112
static inline const char* classcode_str(uint8_t code);

api/kernel/os.hpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,10 @@ class OS {
6969
static int64_t micros_since_boot() noexcept;
7070

7171
/** Timestamp for when OS was booted */
72-
static RTC::timestamp_t boot_timestamp()
73-
{ return RTC::boot_timestamp(); }
72+
static RTC::timestamp_t boot_timestamp();
7473

7574
/** Uptime in whole seconds. */
76-
static RTC::timestamp_t uptime() {
77-
return RTC::time_since_boot();
78-
}
75+
static RTC::timestamp_t uptime();
7976

8077
static MHz cpu_freq() noexcept
8178
{ return cpu_mhz_; }
@@ -145,6 +142,8 @@ class OS {
145142
**/
146143
static void add_stdout_default_serial();
147144

145+
static void add_stdout_solo5();
146+
148147
/** Memory page helpers */
149148
static constexpr uint32_t page_size() noexcept {
150149
return 4096;
@@ -217,6 +216,8 @@ class OS {
217216
/** Start the OS. @todo Should be `init()` - and not accessible from ABI */
218217
static void start(uint32_t boot_magic, uint32_t boot_addr);
219218

219+
static void start(char *cmdline, uintptr_t mem_size);
220+
220221
/** Get "kernel modules", provided by multiboot */
221222
static Span_mods modules();
222223

@@ -250,6 +251,9 @@ class OS {
250251
static bool power_;
251252
static bool boot_sequence_passed_;
252253
static MHz cpu_mhz_;
254+
255+
// XXX: Only used by solo5
256+
static RTC::timestamp_t booted_at_;
253257
static std::string version_str_;
254258
static std::string arch_str_;
255259
static Plugin_vec plugins_;

api/kernel/solo5_manager.hpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// This file is a part of the IncludeOS unikernel - www.includeos.org
2+
//
3+
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
4+
// and Alfred Bratterud
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
#ifndef KERNEL_SOLO5_MANAGER_HPP
19+
#define KERNEL_SOLO5_MANAGER_HPP
20+
21+
#include <vector>
22+
#include <cstdio>
23+
#include <unordered_map>
24+
#include <delegate>
25+
26+
#include <hw/pci_device.hpp>
27+
#include <hw/devices.hpp>
28+
29+
class Solo5_manager {
30+
private:
31+
using Device_registry = std::unordered_map<PCI::classcode, std::vector<hw::PCI_Device>>;
32+
33+
public:
34+
template <PCI::classcode CLASS>
35+
static hw::PCI_Device& device(const int n) noexcept {
36+
return devices_[CLASS][n];
37+
};
38+
39+
template <PCI::classcode CLASS>
40+
static size_t num_of_devices() noexcept {
41+
return devices_[CLASS].size();
42+
}
43+
44+
/** Whats being stored and returned is a unique_ptr of the given device */
45+
template <typename Device_type>
46+
using Dev_ptr = std::unique_ptr<Device_type>;
47+
48+
/** The function (factory) thats create the Dev_ptr from PCI_Device, supplied by the driver */
49+
template <typename Device_type>
50+
using Driver_factory = delegate< Dev_ptr<Device_type>(hw::PCI_Device&) >;
51+
52+
/**
53+
* @brief Register a specific type of driver factory
54+
* @details Register a specific type of driver factory
55+
* (function that creates a pointer to the given Device, with its full driver implementation)
56+
* Indexed as a combination of vendor + product
57+
*
58+
* @param vendor Driver vendor id
59+
* @param product Driver product id
60+
* @param driver_factory Function for creating a driver
61+
* @tparam Device_type The specific type of Device the driver is for
62+
*/
63+
template <typename Device_type>
64+
static void register_driver(uint16_t vendor, uint16_t product,
65+
Driver_factory<Device_type> driver_factory)
66+
{
67+
drivers<Device_type>().emplace(get_driver_id(vendor, product), driver_factory);
68+
}
69+
70+
/** Currently a combination of Model + Product (we don't care about the revision etc. atm.)*/
71+
using driver_id_t = uint32_t;
72+
73+
/** Combine vendor and product id to represent a driver id */
74+
static driver_id_t get_driver_id(uint16_t vendor, uint16_t product)
75+
{ return (uint32_t)(vendor) << 16 | product; }
76+
77+
static driver_id_t get_driver_id(hw::PCI_Device& dev)
78+
{ return get_driver_id(dev.vendor_id(), dev.product_id()); }
79+
80+
private:
81+
static Device_registry devices_;
82+
83+
/** A register for a specific type of drivers: map[driver_id, driver_factory]*/
84+
template <typename Device_type>
85+
using Driver_registry = std::unordered_map<driver_id_t, Driver_factory<Device_type> >;
86+
87+
/**
88+
* @brief Retrieve drivers (factories) of a given type of device
89+
*
90+
* @return A collection of driver factories indexed by driver_id
91+
*/
92+
template <typename Device_type>
93+
static Driver_registry<Device_type>& drivers() {
94+
static Driver_registry<Device_type> drivers_;
95+
return drivers_;
96+
}
97+
98+
template <typename Device_type>
99+
inline static bool register_device(hw::PCI_Device& dev);
100+
101+
/**
102+
* Keep track of certain devices
103+
*
104+
* The PCI manager can probe and keep track of devices which can (possibly)
105+
* be specialized by the Dev-class later.
106+
*/
107+
static void init();
108+
109+
friend class OS;
110+
}; //< class Solo5_manager
111+
112+
template <typename Device_type>
113+
inline bool Solo5_manager::register_device(hw::PCI_Device& dev) {
114+
try {
115+
auto driver_factory = drivers<Device_type>().at(get_driver_id(dev));
116+
INFO2("| +--+ Driver: Found");
117+
118+
hw::Devices::register_device(driver_factory(dev));
119+
return true;
120+
} catch(std::out_of_range) {
121+
INFO2("| +--+ Driver: Not found");
122+
}
123+
return false;
124+
}
125+
126+
#endif //< KERNEL_SOLO5_MANAGER_HPP

cmake/cross_compiled_libraries.txt

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,35 @@ else(BUNDLE_LOC)
2828

2929
endif (BUNDLE_LOC)
3030

31+
ExternalProject_Add(solo5_repo
32+
PREFIX precompiled
33+
BUILD_IN_SOURCE 1
34+
GIT_REPOSITORY https://github.com/ricarkol/solo5.git
35+
GIT_TAG includeos64
36+
CONFIGURE_COMMAND ./configure.sh
37+
UPDATE_COMMAND ""
38+
BUILD_COMMAND make build
39+
INSTALL_COMMAND ""
40+
)
41+
42+
set(SOLO5_REPO_DIR ${CMAKE_CURRENT_BINARY_DIR}/precompiled/src/solo5_repo)
43+
set(SOLO5_INCLUDE_DIR ${SOLO5_REPO_DIR}/build/include/)
44+
set(SOLO5_LIB_DIR ${SOLO5_REPO_DIR}/build/${ARCH})
45+
46+
# solo5 in ukvm mode (let's call it "solo5")
47+
add_library(solo5 STATIC IMPORTED)
48+
set_target_properties(solo5 PROPERTIES IMPORTED_LOCATION ${SOLO5_LIB_DIR}/ukvm/solo5.o)
49+
50+
# ukvm-bin
51+
add_library(ukvm-bin STATIC IMPORTED)
52+
set_target_properties(solo5 PROPERTIES IMPORTED_LOCATION ${SOLO5_LIB_DIR}/ukvm/ukvm-bin)
53+
54+
add_dependencies(solo5 solo5_repo)
55+
add_dependencies(ukvm-bin solo5_repo)
56+
57+
# Some OS components depend on solo5 (for solo5.h for example)
58+
add_dependencies(PrecompiledLibraries solo5)
59+
3160
set(PRECOMPILED_DIR ${CMAKE_CURRENT_BINARY_DIR}/precompiled/src/PrecompiledLibraries/${ARCH})
3261

3362
set(LIBCXX_INCLUDE_DIR ${PRECOMPILED_DIR}/libcxx/include/)
@@ -54,10 +83,6 @@ add_library(libm STATIC IMPORTED)
5483
set_target_properties(libm PROPERTIES IMPORTED_LOCATION ${NEWLIB_LIB_DIR}/libm.a)
5584
add_dependencies(libm PrecompiledLibraries)
5685

57-
add_library(libgcc STATIC IMPORTED)
58-
set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION ${LIBGCC_LIB_DIR}/libgcc.a)
59-
add_dependencies(libgcc PrecompiledLibraries)
60-
6186
set(CRTEND ${PRECOMPILED_DIR}/crt/crtend.o)
6287
set(CRTBEGIN ${PRECOMPILED_DIR}/crt/crtbegin.o)
6388

@@ -66,6 +91,13 @@ install(DIRECTORY ${LIBCXX_INCLUDE_DIR} DESTINATION includeos/${ARCH}/include/li
6691

6792
install(DIRECTORY ${NEWLIB_INCLUDE_DIR} DESTINATION includeos/${ARCH}/include/newlib)
6893

94+
install(DIRECTORY ${SOLO5_INCLUDE_DIR} DESTINATION includeos/${ARCH}/include/solo5)
95+
6996
install(FILES ${CRTEND} ${CRTBEGIN} DESTINATION includeos/${ARCH}/lib)
7097

98+
# Only x86_64 supported at the moment
99+
if ("${ARCH}" STREQUAL "x86_64")
100+
install(FILES ${SOLO5_LIB_DIR}/ukvm/solo5.o ${SOLO5_LIB_DIR}/ukvm/ukvm-bin DESTINATION includeos/${ARCH}/lib)
101+
endif()
102+
71103
install(FILES ${NEWLIB_LIB_DIR}/libc.a ${NEWLIB_LIB_DIR}/libg.a ${NEWLIB_LIB_DIR}/libm.a ${LIBGCC_LIB_DIR}/libgcc.a ${LIBCXX_LIB_DIR}/libc++.a ${LIBCXX_LIB_DIR}/libc++abi.a DESTINATION includeos/${ARCH}/lib)

cmake/library.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ include_directories(${LOCAL_INCLUDES})
7070
include_directories(${INSTALL_LOC}/api/posix)
7171
include_directories(${INSTALL_LOC}/${ARCH}/include/libcxx)
7272
include_directories(${INSTALL_LOC}/${ARCH}/include/newlib)
73+
include_directories(${INSTALL_LOC}/${ARCH}/include/solo5)
7374
include_directories(${INSTALL_LOC}/api)
7475
include_directories(${INSTALL_LOC}/include)
7576
include_directories($ENV{INCLUDEOS_PREFIX}/include)

cmake/post.service.cmake

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ include_directories(${LOCAL_INCLUDES})
170170
include_directories(${INSTALL_LOC}/api/posix)
171171
include_directories(${INSTALL_LOC}/${ARCH}/include/libcxx)
172172
include_directories(${INSTALL_LOC}/${ARCH}/include/newlib)
173+
174+
if ("${PLATFORM}" STREQUAL "x86_solo5")
175+
include_directories(${INSTALL_LOC}/${ARCH}/include/solo5)
176+
endif()
177+
173178
include_directories(${INSTALL_LOC}/${ARCH}/include)
174179
include_directories(${INSTALL_LOC}/api)
175180
include_directories(${INSTALL_LOC}/include)
@@ -248,6 +253,12 @@ add_library(libgcc STATIC IMPORTED)
248253
set_target_properties(libgcc PROPERTIES LINKER_LANGUAGE C)
249254
set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION ${INSTALL_LOC}/${ARCH}/lib/libgcc.a)
250255

256+
if ("${PLATFORM}" STREQUAL "x86_solo5")
257+
add_library(solo5 STATIC IMPORTED)
258+
set_target_properties(solo5 PROPERTIES LINKER_LANGUAGE C)
259+
set_target_properties(solo5 PROPERTIES IMPORTED_LOCATION ${INSTALL_LOC}/${ARCH}/lib/solo5.o)
260+
endif()
261+
251262
# Depending on the output of this command will make it always run. Like magic.
252263
add_custom_command(OUTPUT fake_news
253264
COMMAND cmake -E touch_nocreate alternative_facts)
@@ -320,6 +331,10 @@ add_library(crtn STATIC IMPORTED)
320331
set_target_properties(crtn PROPERTIES LINKER_LANGUAGE CXX)
321332
set_target_properties(crtn PROPERTIES IMPORTED_LOCATION ${INSTALL_LOC}/${ARCH}/lib/libcrtn.a)
322333

334+
if ("${PLATFORM}" STREQUAL "x86_solo5")
335+
target_link_libraries(service solo5 --whole-archive crtn --no-whole-archive)
336+
endif()
337+
323338
# all the OS and C/C++ libraries + crt end
324339
target_link_libraries(service
325340
libplatform

0 commit comments

Comments
 (0)