-
Avi Kivity authored
The main thread has a bogus wait_for_interrupts() which consumed wakeups, so the scheduler on the cpu running it could not schedule stuff. This manifested itself in lots of zombies from bsd callouts not getting reaped. Drop.
Avi Kivity authoredThe main thread has a bogus wait_for_interrupts() which consumed wakeups, so the scheduler on the cpu running it could not schedule stuff. This manifested itself in lots of zombies from bsd callouts not getting reaped. Drop.
loader.cc 3.44 KiB
#include "drivers/isa-serial.hh"
#include "fs/fs.hh"
#include <bsd/net.hh>
#include <boost/format.hpp>
#include <cctype>
#include "elf.hh"
#include "tls.hh"
#include "msr.hh"
#include "exceptions.hh"
#include "debug.hh"
#include "drivers/pci.hh"
#include "smp.hh"
#include "drivers/driver.hh"
#include "drivers/virtio-net.hh"
#include "drivers/virtio-blk.hh"
#include "sched.hh"
#include "drivers/clock.hh"
#include "drivers/clockevent.hh"
#include "barrier.hh"
#include "tests/tst-hub.hh"
#include "arch.hh"
#include "osv/trace.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");
}
}
elf::Elf64_Ehdr* elf_header;
elf::tls_data tls_data;
void setup_tls(elf::init_table inittab)
{
tls_data = inittab.tls;
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);
setup_tls(inittab);
for (auto init = inittab.start; init < inittab.start + inittab.count; ++init) {
(*init)();
}
}
void disable_pic()
{
outb(0xff, 0x21);
outb(0xff, 0xa1);
}
elf::program* prog;
int main(int ac, char **av)
{
debug("Loader Copyright 2013 Unnamed");
test_locale();
idt.load_on_cpu();
void main_cont(int ac, char** av);
sched::init(tls_data, [=] { main_cont(ac, av); });
}
void main_cont(int ac, char** av)
{
smp_launch();
enable_trace();
sched::init_detached_threads_reaper();
vfs_init();
ramdisk_init();
filesystem fs;
net_init();
disable_pic();
processor::sti();
prog = new elf::program(fs);
void main_thread(int ac, char** av);
main_thread(ac, 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);
//Tests malloc and free using threads.
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(new virtio::virtio_blk(0));
drvman->register_driver(new virtio::virtio_blk(1));
drvman->register_driver(new virtio::virtio_net(0));
drvman->load_all();
drvman->list_drivers();
run_main(prog, args);
return nullptr;
}
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;