Newer
Older
#include "drivers/isa-serial.hh"
#include <boost/format.hpp>
#include <cctype>
#include "tls.hh"
#include "msr.hh"
#include "drivers/driver.hh"
#include "drivers/virtio-blk.hh"
#include "drivers/clockevent.hh"
#include "barrier.hh"
#include "tests/tst-hub.hh"
asm(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1 \n"
".byte 1 \n"
".asciz \"scripts/loader.py\" \n"
".popsection \n");
namespace {
void test_locale()
{
auto loc = std::locale();
auto &fac = std::use_facet<std::ctype<char>>(loc);
bool ok = fac.is(std::ctype_base::digit, '3')
&& !fac.is(std::ctype_base::digit, 'x');
debug(ok ? "locale works" : "locale fails");
//asm volatile ("1: jmp 1b");
}
}
void setup_tls(elf::init_table inittab)
{
extern char tcb0[]; // defined by linker script
memcpy(tcb0, inittab.tls.start, inittab.tls.size);
auto p = reinterpret_cast<thread_control_block*>(tcb0 + inittab.tls.size);
p->self = p;
processor::wrmsr(msr::IA32_FS_BASE, reinterpret_cast<uint64_t>(p));
}
extern "C" {
void premain();
void vfs_init(void);
void ramdisk_init(void);
}
void premain()
{
auto inittab = elf::get_init(elf_header);
for (auto init = inittab.start; init < inittab.start + inittab.count; ++init) {
(*init)();
}
}
void disable_pic()
{
outb(0xff, 0x21);
outb(0xff, 0xa1);
}
elf::program* prog;
debug("Loader Copyright 2013 Unnamed");
void main_cont(int ac, char** av);
sched::init(tls_data, [=] { main_cont(ac, av); });
}
void main_cont(int ac, char** av)
{
prog = new elf::program(fs);
void main_thread(int ac, char** av);
struct argblock {
int ac;
char** av;
};
void run_main(elf::program *prog, struct argblock *args)
{
auto av = args->av;
auto ac = args->ac;
prog->add_object(av[0]);
++av, --ac;
auto osv_main = prog->lookup_function<void (int, char**)>("osv_main");
osv_main(ac, av);
void* do_main_thread(void *_args)
auto args = static_cast<argblock*>(_args);
unit_tests::tests::instance().execute_tests();
// Enumerate PCI devices
pci::pci_device_enumeration();
// Initialize all drivers
hw::driver_manager* drvman = hw::driver_manager::instance();
drvman->register_driver(virtio::virtio_blk::probe);
drvman->register_driver(virtio::virtio_net::probe);
drvman->load_all();
drvman->list_drivers();
void main_thread(int ac, char **av)
{
pthread_t pthread;
// run the payload in a pthread, so pthread_self() etc. work
argblock args{ ac, av };
pthread_create(&pthread, nullptr, do_main_thread, &args);
sched::thread::wait_until([] { return false; });
int __argc;
char** __argv;