initial working example as made hacking around
This commit is contained in:
parent
8838cfd301
commit
cf17a45c15
310
.config.helloworld_qemu-x86_64
Normal file
310
.config.helloworld_qemu-x86_64
Normal file
|
@ -0,0 +1,310 @@
|
|||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Unikraft/0.17.0~8838cfd Configuration
|
||||
#
|
||||
CONFIG_UK_FULLVERSION="0.17.0~8838cfd"
|
||||
CONFIG_UK_CODENAME="Calypso"
|
||||
CONFIG_UK_ARCH="x86_64"
|
||||
CONFIG_HOST_ARCH="x86_64"
|
||||
CONFIG_UK_BASE="/home/lobo/home/unikraft-zig-native-hello/.unikraft/unikraft"
|
||||
CONFIG_UK_APP="/home/lobo/home/unikraft-zig-native-hello"
|
||||
CONFIG_UK_DEFNAME="helloworld"
|
||||
|
||||
#
|
||||
# Architecture Selection
|
||||
#
|
||||
CONFIG_ARCH_X86_64=y
|
||||
# CONFIG_ARCH_ARM_64 is not set
|
||||
# CONFIG_ARCH_ARM_32 is not set
|
||||
# CONFIG_MARCH_X86_64_NATIVE is not set
|
||||
CONFIG_MARCH_X86_64_GENERIC=y
|
||||
# CONFIG_MARCH_X86_64_NOCONA is not set
|
||||
# CONFIG_MARCH_X86_64_CORE2 is not set
|
||||
# CONFIG_MARCH_X86_64_COREI7 is not set
|
||||
# CONFIG_MARCH_X86_64_COREI7AVX is not set
|
||||
# CONFIG_MARCH_X86_64_COREI7AVXI is not set
|
||||
# CONFIG_MARCH_X86_64_ATOM is not set
|
||||
# CONFIG_MARCH_X86_64_K8 is not set
|
||||
# CONFIG_MARCH_X86_64_K8SSE3 is not set
|
||||
# CONFIG_MARCH_X86_64_AMDFAM10 is not set
|
||||
# CONFIG_MARCH_X86_64_BTVER1 is not set
|
||||
# CONFIG_MARCH_X86_64_BDVER1 is not set
|
||||
# CONFIG_MARCH_X86_64_BDVER2 is not set
|
||||
# CONFIG_MARCH_X86_64_BDVER3 is not set
|
||||
# CONFIG_MARCH_X86_64_BTVER2 is not set
|
||||
|
||||
#
|
||||
# Processor Features
|
||||
#
|
||||
CONFIG_X86_64_HAVE_RANDOM=y
|
||||
# end of Processor Features
|
||||
|
||||
CONFIG_STACK_SIZE_PAGE_ORDER=4
|
||||
CONFIG_CPU_EXCEPT_STACK_SIZE_PAGE_ORDER=4
|
||||
CONFIG_AUXSTACK_SIZE_PAGE_ORDER=4
|
||||
CONFIG_HAVE_RANDOM=y
|
||||
# end of Architecture Selection
|
||||
|
||||
#
|
||||
# Platform Configuration
|
||||
#
|
||||
CONFIG_PLAT_KVM=y
|
||||
CONFIG_KVM_BOOT_PROTO_MULTIBOOT=y
|
||||
|
||||
#
|
||||
# Hint: EFI stub depends on OPTIMIZE_PIE
|
||||
#
|
||||
CONFIG_KVM_VMM_QEMU=y
|
||||
# CONFIG_KVM_VMM_FIRECRACKER is not set
|
||||
|
||||
#
|
||||
# Console Options
|
||||
#
|
||||
CONFIG_KVM_KERNEL_VGA_CONSOLE=y
|
||||
CONFIG_KVM_DEBUG_SERIAL_CONSOLE=y
|
||||
CONFIG_KVM_DEBUG_VGA_CONSOLE=y
|
||||
CONFIG_KVM_KERNEL_SERIAL_CONSOLE=y
|
||||
|
||||
#
|
||||
# Serial console configuration
|
||||
#
|
||||
CONFIG_KVM_SERIAL_BAUD_115200=y
|
||||
# CONFIG_KVM_SERIAL_BAUD_57600 is not set
|
||||
# CONFIG_KVM_SERIAL_BAUD_38400 is not set
|
||||
# CONFIG_KVM_SERIAL_BAUD_19200 is not set
|
||||
# end of Serial console configuration
|
||||
# end of Console Options
|
||||
|
||||
# CONFIG_PLAT_XEN is not set
|
||||
|
||||
#
|
||||
# Platform Interface Options
|
||||
#
|
||||
# CONFIG_UKPLAT_MEMRNAME is not set
|
||||
CONFIG_UKPLAT_MEMREGION_MAX_COUNT=128
|
||||
# CONFIG_UKPLAT_ACPI is not set
|
||||
CONFIG_UKPLAT_LCPU_MAXCOUNT=1
|
||||
# CONFIG_PAGING is not set
|
||||
# end of Platform Interface Options
|
||||
|
||||
CONFIG_HZ=100
|
||||
# end of Platform Configuration
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
|
||||
#
|
||||
# Real Time Clock
|
||||
#
|
||||
# end of Real Time Clock
|
||||
|
||||
#
|
||||
# Serial console
|
||||
#
|
||||
# end of Serial console
|
||||
|
||||
#
|
||||
# Bus drivers
|
||||
#
|
||||
CONFIG_HAVE_PCI=y
|
||||
# CONFIG_LIBUKBUS_PCI is not set
|
||||
# CONFIG_LIBUKBUS_PLATFORM is not set
|
||||
# end of Bus drivers
|
||||
|
||||
#
|
||||
# Interrupt controller
|
||||
#
|
||||
CONFIG_HAVE_APIC=y
|
||||
CONFIG_LIBUKINTCTLR_XPIC=y
|
||||
# CONFIG_LIBUKINTCTLR_APIC is not set
|
||||
# end of Interrupt controller
|
||||
|
||||
#
|
||||
# Virtio
|
||||
#
|
||||
CONFIG_HAVE_MMIO=y
|
||||
# end of Virtio
|
||||
|
||||
#
|
||||
# Xen
|
||||
#
|
||||
# end of Xen
|
||||
# end of Device Drivers
|
||||
|
||||
#
|
||||
# Library Configuration
|
||||
#
|
||||
CONFIG_LIBISRLIB=y
|
||||
CONFIG_LIBNOLIBC=y
|
||||
CONFIG_LIBNOLIBC_UKDEBUG_ASSERT=y
|
||||
# CONFIG_LIBNOLIBC_SYSLOG is not set
|
||||
CONFIG_LIBNOLIBC_FD_SETSIZE=64
|
||||
# CONFIG_LIBPOSIX_ENVIRON is not set
|
||||
# CONFIG_LIBPOSIX_EVENTFD is not set
|
||||
# CONFIG_LIBPOSIX_FDIO is not set
|
||||
# CONFIG_LIBPOSIX_FDTAB is not set
|
||||
# CONFIG_LIBPOSIX_FUTEX is not set
|
||||
# CONFIG_LIBPOSIX_LIBDL is not set
|
||||
# CONFIG_LIBPOSIX_PIPE is not set
|
||||
# CONFIG_LIBPOSIX_POLL is not set
|
||||
CONFIG_LIBPOSIX_PROCESS=y
|
||||
CONFIG_LIBPOSIX_PROCESS_PIDS=y
|
||||
CONFIG_LIBPOSIX_PROCESS_MAX_PID=31
|
||||
CONFIG_LIBPOSIX_PROCESS_INIT_PIDS=y
|
||||
# CONFIG_LIBPOSIX_PROCESS_CLONE is not set
|
||||
# CONFIG_LIBPOSIX_PROCESS_DEBUG is not set
|
||||
# CONFIG_LIBPOSIX_SOCKET is not set
|
||||
# CONFIG_LIBPOSIX_SYSINFO is not set
|
||||
# CONFIG_LIBPOSIX_TIME is not set
|
||||
# CONFIG_LIBPOSIX_TIMERFD is not set
|
||||
# CONFIG_LIBPOSIX_TTY is not set
|
||||
# CONFIG_LIBPOSIX_UNIXSOCKET is not set
|
||||
# CONFIG_LIBPOSIX_USER is not set
|
||||
# CONFIG_LIBSYSCALL_SHIM is not set
|
||||
# CONFIG_LIBUBSAN is not set
|
||||
# CONFIG_LIBUK9P is not set
|
||||
CONFIG_LIBUKALLOC=y
|
||||
# CONFIG_LIBUKALLOC_IFMALLOC is not set
|
||||
# CONFIG_LIBUKALLOC_IFSTATS is not set
|
||||
CONFIG_LIBUKALLOCBBUDDY=y
|
||||
# CONFIG_LIBUKALLOCBBUDDY_FREELIST_SANITY is not set
|
||||
# CONFIG_LIBUKALLOCPOOL is not set
|
||||
# CONFIG_LIBUKALLOCREGION is not set
|
||||
CONFIG_LIBUKALLOCSTACK=y
|
||||
CONFIG_LIBUKARGPARSE=y
|
||||
# CONFIG_LIBUKARGPARSE_TEST is not set
|
||||
CONFIG_LIBUKATOMIC=y
|
||||
CONFIG_LIBUKBITOPS=y
|
||||
# CONFIG_LIBUKBLKDEV is not set
|
||||
CONFIG_LIBUKBOOT=y
|
||||
# CONFIG_LIBUKBOOT_BANNER_NONE is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_MINIMAL is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_CLASSIC is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_POWEREDBY is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_POWEREDBY_ANSI is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_POWEREDBY_ANSI2 is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_POWEREDBY_EA is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_POWEREDBY_EAANSI is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_POWEREDBY_EAANSI2 is not set
|
||||
# CONFIG_LIBUKBOOT_BANNER_POWEREDBY_U8 is not set
|
||||
CONFIG_LIBUKBOOT_BANNER_POWEREDBY_U8ANSI=y
|
||||
# CONFIG_LIBUKBOOT_BANNER_POWEREDBY_U8ANSI2 is not set
|
||||
CONFIG_LIBUKBOOT_MAXNBARGS=60
|
||||
CONFIG_LIBUKBOOT_INITALLOC=y
|
||||
CONFIG_LIBUKBOOT_INITBBUDDY=y
|
||||
# CONFIG_LIBUKBOOT_INITREGION is not set
|
||||
# CONFIG_LIBUKBOOT_INITNOALLOC is not set
|
||||
CONFIG_LIBUKBOOT_INITSCHED=y
|
||||
CONFIG_LIBUKBOOT_INITSCHEDCOOP=y
|
||||
# CONFIG_LIBUKBOOT_INITNOSCHED is not set
|
||||
# CONFIG_LIBUKBOOT_MAINTHREAD is not set
|
||||
CONFIG_LIBUKBOOT_ALLOCSTACK=y
|
||||
# CONFIG_LIBUKBUS is not set
|
||||
CONFIG_LIBUKDEBUG=y
|
||||
CONFIG_LIBUKDEBUG_PRINTK=y
|
||||
# CONFIG_LIBUKDEBUG_PRINTK_INFO is not set
|
||||
# CONFIG_LIBUKDEBUG_PRINTK_WARN is not set
|
||||
CONFIG_LIBUKDEBUG_PRINTK_ERR=y
|
||||
# CONFIG_LIBUKDEBUG_PRINTK_CRIT is not set
|
||||
# CONFIG_LIBUKDEBUG_PRINTD is not set
|
||||
# CONFIG_LIBUKDEBUG_NOREDIR is not set
|
||||
CONFIG_LIBUKDEBUG_REDIR_PRINTD=y
|
||||
# CONFIG_LIBUKDEBUG_REDIR_PRINTK is not set
|
||||
CONFIG_LIBUKDEBUG_PRINT_TIME=y
|
||||
# CONFIG_LIBUKDEBUG_PRINT_THREAD is not set
|
||||
# CONFIG_LIBUKDEBUG_PRINT_CALLER is not set
|
||||
CONFIG_LIBUKDEBUG_PRINT_SRCNAME=y
|
||||
# CONFIG_LIBUKDEBUG_ANSI_COLOR is not set
|
||||
CONFIG_LIBUKDEBUG_ENABLE_ASSERT=y
|
||||
# CONFIG_LIBUKDEBUG_TRACEPOINTS is not set
|
||||
# CONFIG_LIBUKFALLOC is not set
|
||||
# CONFIG_LIBUKFALLOCBUDDY is not set
|
||||
CONFIG_LIBUKFILE=y
|
||||
# CONFIG_LIBUKGCOV is not set
|
||||
CONFIG_HAVE_INTCTLR=y
|
||||
CONFIG_LIBUKINTCTLR=y
|
||||
CONFIG_LIBUKINTCTLR_MAX_HANDLERS_PER_IRQ=8
|
||||
# CONFIG_LIBUKINTCTLR_ISR_ECTX_ASSERTIONS is not set
|
||||
CONFIG_LIBUKLIBID=y
|
||||
CONFIG_LIBUKLIBID_INFO=y
|
||||
|
||||
#
|
||||
# Global metadata
|
||||
#
|
||||
CONFIG_LIBUKLIBID_INFO_UKFULLVERSION=y
|
||||
# CONFIG_LIBUKLIBID_INFO_UKCODENAME is not set
|
||||
# CONFIG_LIBUKLIBID_INFO_COMPILER is not set
|
||||
CONFIG_LIBUKLIBID_INFO_COMPILEDATE=y
|
||||
# CONFIG_LIBUKLIBID_INFO_UKCONFIGGZ is not set
|
||||
# end of Global metadata
|
||||
|
||||
#
|
||||
# Per library metadata
|
||||
#
|
||||
# CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION is not set
|
||||
# CONFIG_LIBUKLIBID_INFO_LIB_UKCODENAME is not set
|
||||
CONFIG_LIBUKLIBID_INFO_LIB_COMPILER=y
|
||||
# CONFIG_LIBUKLIBID_INFO_LIB_COMPILEDATE is not set
|
||||
# end of Per library metadata
|
||||
|
||||
# CONFIG_LIBUKLIBID_INFO_COMPILEDBY is not set
|
||||
# CONFIG_LIBUKLIBID_INFO_BOOTDUMP is not set
|
||||
# CONFIG_LIBUKLIBPARAM is not set
|
||||
CONFIG_LIBUKLOCK=y
|
||||
CONFIG_LIBUKLOCK_SEMAPHORE=y
|
||||
CONFIG_LIBUKLOCK_MUTEX=y
|
||||
# CONFIG_LIBUKLOCK_MUTEX_METRICS is not set
|
||||
CONFIG_LIBUKLOCK_RWLOCK=y
|
||||
# CONFIG_LIBUKMMAP is not set
|
||||
# CONFIG_LIBUKMPI is not set
|
||||
# CONFIG_LIBUKNETDEV is not set
|
||||
# CONFIG_LIBUKNOFAULT is not set
|
||||
CONFIG_LIBUKRANDOM=y
|
||||
# CONFIG_LIBUKRANDOM_SEED_INSECURE is not set
|
||||
# CONFIG_LIBUKRING is not set
|
||||
# CONFIG_LIBUKRUST is not set
|
||||
CONFIG_LIBUKSCHED=y
|
||||
# CONFIG_LIBUKSCHED_DEBUG is not set
|
||||
CONFIG_LIBUKSCHEDCOOP=y
|
||||
# CONFIG_LIBUKSGLIST is not set
|
||||
# CONFIG_LIBUKSIGNAL is not set
|
||||
# CONFIG_LIBUKSP is not set
|
||||
# CONFIG_LIBUKSTORE is not set
|
||||
CONFIG_LIBUKSTREAMBUF=y
|
||||
# CONFIG_LIBUKSTREAMBUF_TEST is not set
|
||||
# CONFIG_LIBUKTEST is not set
|
||||
CONFIG_LIBUKTIMECONV=y
|
||||
# CONFIG_LIBUKVMEM is not set
|
||||
# CONFIG_LIBVFSCORE is not set
|
||||
CONFIG_HAVE_BOOTENTRY=y
|
||||
CONFIG_HAVE_SCHED=y
|
||||
# end of Library Configuration
|
||||
|
||||
#
|
||||
# Application Options
|
||||
#
|
||||
|
||||
#
|
||||
# Build Options
|
||||
#
|
||||
CONFIG_OPTIMIZE_NONE=y
|
||||
# CONFIG_OPTIMIZE_PERF is not set
|
||||
# CONFIG_OPTIMIZE_SIZE is not set
|
||||
CONFIG_OPTIMIZE_NOOMITFP=y
|
||||
# CONFIG_OPTIMIZE_DEADELIM is not set
|
||||
# CONFIG_OPTIMIZE_LTO is not set
|
||||
# CONFIG_OPTIMIZE_PIE is not set
|
||||
# CONFIG_DEBUG_SYMBOLS_LVL0 is not set
|
||||
# CONFIG_DEBUG_SYMBOLS_LVL1 is not set
|
||||
# CONFIG_DEBUG_SYMBOLS_LVL2 is not set
|
||||
CONFIG_DEBUG_SYMBOLS_LVL3=y
|
||||
# CONFIG_OPTIMIZE_WARNISERROR is not set
|
||||
# CONFIG_OPTIMIZE_SYMFILE is not set
|
||||
# CONFIG_OPTIMIZE_COMPRESS is not set
|
||||
# CONFIG_RECORD_BUILDTIME is not set
|
||||
CONFIG_CROSS_COMPILE=""
|
||||
CONFIG_LLVM_TARGET_ARCH=""
|
||||
# end of Build Options
|
||||
|
||||
CONFIG_UK_NAME="helloworld"
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.zig-cache
|
||||
zig-out
|
13
Kraftfile
Normal file
13
Kraftfile
Normal file
|
@ -0,0 +1,13 @@
|
|||
spec: v0.6
|
||||
|
||||
name: helloworld
|
||||
|
||||
unikraft:
|
||||
version: stable
|
||||
|
||||
targets:
|
||||
- fc/arm64
|
||||
- fc/x86_64
|
||||
- qemu/arm64
|
||||
- qemu/x86_64
|
||||
- xen/x86_64
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Emil Lerch
|
||||
|
||||
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.
|
5
Makefile.uk
Normal file
5
Makefile.uk
Normal file
|
@ -0,0 +1,5 @@
|
|||
$(eval $(call addlib,apphelloworld))
|
||||
|
||||
APPHELLOWORLD_SRCS-y += $(APPHELLOWORLD_BASE)/helloworld.c
|
||||
APPHELLOWORLD_SRCS-y += $(APPHELLOWORLD_BASE)/undefined.c
|
||||
UK_ALIBS-y += $(APPHELLOWORLD_BASE)/libziggy.a
|
2
README.md
Normal file
2
README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
(cd ziggy && zig build -Doptimize=ReleaseSafe -Dtarget=x86_64-linux-gnu.2.13 -Dcpu=baseline) && cp ziggy/zig-out/lib/libziggy.a . && kraft build --plat qemu --arch x86_64 --log-level debug --log-type basic && kraft run --pla
|
||||
t qemu --arch x86_64
|
22
helloworld.c
Normal file
22
helloworld.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern int add(int, int);
|
||||
extern int gettid(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int result = add(2, 2);
|
||||
/* write(1, "from helloworld", 15); */
|
||||
printf("Hello, World! 2+2=");
|
||||
char buffer[10];
|
||||
for (int i = 0; i < 10; i++ ) buffer[i] = 0;
|
||||
buffer[0] = '0' + result;
|
||||
puts(buffer);
|
||||
|
||||
// requires posix-process, process and thread ids
|
||||
puts("Attempting gettid()");
|
||||
printf("tid=%d\n", gettid());
|
||||
|
||||
return 0;
|
||||
}
|
196
undefined.c
Normal file
196
undefined.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/* Linking our zig to libc results in the following undefined symbols:
|
||||
mmap64
|
||||
dl_iterate_phdr
|
||||
getcontext
|
||||
sigaction
|
||||
write
|
||||
close
|
||||
realpath
|
||||
read
|
||||
msync
|
||||
munmap
|
||||
environ
|
||||
openat64
|
||||
flock
|
||||
fstat64
|
||||
dl_iterate_phdr
|
||||
getenv
|
||||
isatty
|
||||
*/
|
||||
|
||||
// Provide stubs for missing functions
|
||||
#define UNUSED(x) (void)(x)
|
||||
#define SEGFAULT() {int *ptr = 0; *ptr = 42;}
|
||||
void *mmap64(void *addr, size_t length, int prot, int flags,
|
||||
int fd, long int offset){
|
||||
UNUSED(addr);
|
||||
UNUSED(length);
|
||||
UNUSED(prot);
|
||||
UNUSED(flags);
|
||||
UNUSED(flags);
|
||||
UNUSED(fd);
|
||||
UNUSED(offset);
|
||||
puts("unsupported function mmap called");
|
||||
// force a seg fault
|
||||
SEGFAULT();
|
||||
return 0; // unreachable
|
||||
}
|
||||
|
||||
int dl_iterate_phdr(
|
||||
int (*callback)(struct dl_phdr_info *info,
|
||||
size_t size, void *data),
|
||||
void *data){
|
||||
UNUSED(callback);
|
||||
UNUSED(data);
|
||||
puts("unsupported function dl_iterate_phdr called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
int getcontext(void *ucp) {
|
||||
UNUSED(ucp);
|
||||
puts("unsupported function getcontext called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sigaction(int signum, void* act, void* oldact) {
|
||||
UNUSED(signum);
|
||||
UNUSED(act);
|
||||
UNUSED(oldact);
|
||||
// const struct sigaction *_Nullable restrict act,
|
||||
// struct sigaction *_Nullable restrict oldact) {
|
||||
puts("unsupported function sigaction called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ANSI_COLOR_RED "\x1b[31m"
|
||||
#define ANSI_COLOR_GREEN "\x1b[32m"
|
||||
#define ANSI_COLOR_YELLOW "\x1b[33m"
|
||||
#define ANSI_COLOR_BLUE "\x1b[34m"
|
||||
#define ANSI_COLOR_MAGENTA "\x1b[35m"
|
||||
#define ANSI_COLOR_CYAN "\x1b[36m"
|
||||
#define ANSI_COLOR_RESET "\x1b[0m"
|
||||
|
||||
// TODO: This if is not correct
|
||||
#if !(defined(CONFIG_LIBPOSIX_TTY) || defined(CONFIG_LIBSYSCALL_SHIM))
|
||||
size_t write(int fd, const char *buf, size_t count){
|
||||
UNUSED(fd);
|
||||
UNUSED(buf);
|
||||
UNUSED(count);
|
||||
char *color;
|
||||
switch (fd) {
|
||||
case 1: // stdout
|
||||
color = ANSI_COLOR_RESET;
|
||||
break;
|
||||
case 2:
|
||||
color = ANSI_COLOR_RED;
|
||||
break;
|
||||
default:
|
||||
printf("write called on unsupported file descriptor: ");
|
||||
char fd_buf[10] = "fd = ";
|
||||
fd_buf[5] = '0' + fd;
|
||||
fd_buf[6] = 0;
|
||||
puts(fd_buf);
|
||||
SEGFAULT();
|
||||
break;
|
||||
}
|
||||
if (fd != 1) printf(color);
|
||||
if (fd == 2) printf("(stderr): ");
|
||||
printf("%.*s", (int)count, buf);
|
||||
if (fd != 1) printf(ANSI_COLOR_RESET);
|
||||
return count;
|
||||
}
|
||||
|
||||
int close(int fd) {
|
||||
UNUSED(fd);
|
||||
// const struct sigaction *_Nullable restrict act,
|
||||
// struct sigaction *_Nullable restrict oldact) {
|
||||
puts("unsupported function close called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
size_t read(int fd, void *buf, size_t count) {
|
||||
UNUSED(fd);
|
||||
UNUSED(buf);
|
||||
UNUSED(count);
|
||||
puts("unsupported function read called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *realpath(const char *path,
|
||||
char *resolved_path) {
|
||||
UNUSED(path);
|
||||
UNUSED(resolved_path);
|
||||
// const struct sigaction *_Nullable restrict act,
|
||||
// struct sigaction *_Nullable restrict oldact) {
|
||||
puts("unsupported function realpath called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msync(void *addr, size_t length, int flags) {
|
||||
UNUSED(addr);
|
||||
UNUSED(length);
|
||||
UNUSED(flags);
|
||||
puts("unsupported function msync called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
int munmap(void *addr, size_t length) {
|
||||
UNUSED(addr);
|
||||
UNUSED(length);
|
||||
puts("unsupported function munmap called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openat64(int fd, const char * path, int oflag, ...) {
|
||||
UNUSED(fd);
|
||||
UNUSED(path);
|
||||
UNUSED(oflag);
|
||||
puts("unsupported function openat64 called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flock(int fd, int operation) {
|
||||
UNUSED(fd);
|
||||
UNUSED(operation);
|
||||
puts("unsupported function flock called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fstat64(int fd, void *statbuf) {
|
||||
UNUSED(fd);
|
||||
UNUSED(statbuf);
|
||||
puts("unsupported function fstat called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
// If .config... file has environment support (CONFIG_LIBPOSIX_ENVIRON=y)
|
||||
// defined, these variable are handled
|
||||
#ifndef CONFIG_LIBPOSIX_ENVIRON
|
||||
char **environ = 0;
|
||||
char *getenv(const char *name) {
|
||||
UNUSED(name);
|
||||
puts(ANSI_COLOR_RED);
|
||||
puts("unsupported function getenv called. use `kraft menu` to configure environment variable support");
|
||||
puts("or set CONFIG_LIBPOSIX_ENVIRON in .config.<appname>_<system>-<architecture>");
|
||||
puts(ANSI_COLOR_RESET);
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int isatty(int fd) {
|
||||
UNUSED(fd);
|
||||
puts("unsupported function isatty called");
|
||||
SEGFAULT();
|
||||
return 0;
|
||||
}
|
92
ziggy/build.zig
Normal file
92
ziggy/build.zig
Normal file
|
@ -0,0 +1,92 @@
|
|||
const std = @import("std");
|
||||
|
||||
// Although this function looks imperative, note that its job is to
|
||||
// declaratively construct a build graph that will be executed by an external
|
||||
// runner.
|
||||
pub fn build(b: *std.Build) void {
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
// what target to build for. Here we do not override the defaults, which
|
||||
// means any target is allowed, and the default is native. Other options
|
||||
// for restricting supported target set are available.
|
||||
const target = b.standardTargetOptions(.{});
|
||||
|
||||
// Standard optimization options allow the person running `zig build` to select
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
||||
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const lib = b.addStaticLibrary(.{
|
||||
.name = "ziggy",
|
||||
// In this case the main source file is merely a path, however, in more
|
||||
// complicated build scripts, this could be a generated file.
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
lib.bundle_compiler_rt = true; // necessary since we're linking with a c program
|
||||
lib.linkLibC();
|
||||
// This declares intent for the library to be installed into the standard
|
||||
// location when the user invokes the "install" step (the default step when
|
||||
// running `zig build`).
|
||||
b.installArtifact(lib);
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "ziggy",
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// This declares intent for the executable to be installed into the
|
||||
// standard location when the user invokes the "install" step (the default
|
||||
// step when running `zig build`).
|
||||
b.installArtifact(exe);
|
||||
|
||||
// This *creates* a Run step in the build graph, to be executed when another
|
||||
// step is evaluated that depends on it. The next line below will establish
|
||||
// such a dependency.
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
|
||||
// By making the run step depend on the install step, it will be run from the
|
||||
// installation directory rather than directly from within the cache directory.
|
||||
// This is not necessary, however, if the application depends on other installed
|
||||
// files, this ensures they will be present and in the expected location.
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
// This allows the user to pass arguments to the application in the build
|
||||
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
// This creates a build step. It will be visible in the `zig build --help` menu,
|
||||
// and can be selected like this: `zig build run`
|
||||
// This will evaluate the `run` step rather than the default, which is "install".
|
||||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
// Creates a step for unit testing. This only builds the test executable
|
||||
// but does not run it.
|
||||
const lib_unit_tests = b.addTest(.{
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||
|
||||
const exe_unit_tests = b.addTest(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||
|
||||
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||
// the `zig build --help` menu, providing a way for the user to request
|
||||
// running the unit tests.
|
||||
const test_step = b.step("test", "Run unit tests");
|
||||
test_step.dependOn(&run_lib_unit_tests.step);
|
||||
test_step.dependOn(&run_exe_unit_tests.step);
|
||||
}
|
72
ziggy/build.zig.zon
Normal file
72
ziggy/build.zig.zon
Normal file
|
@ -0,0 +1,72 @@
|
|||
.{
|
||||
// This is the default name used by packages depending on this one. For
|
||||
// example, when a user runs `zig fetch --save <url>`, this field is used
|
||||
// as the key in the `dependencies` table. Although the user can choose a
|
||||
// different name, most users will stick with this provided value.
|
||||
//
|
||||
// It is redundant to include "zig" in this name because it is already
|
||||
// within the Zig package namespace.
|
||||
.name = "ziggy",
|
||||
|
||||
// This is a [Semantic Version](https://semver.org/).
|
||||
// In a future version of Zig it will be used for package deduplication.
|
||||
.version = "0.0.0",
|
||||
|
||||
// This field is optional.
|
||||
// This is currently advisory only; Zig does not yet do anything
|
||||
// with this value.
|
||||
//.minimum_zig_version = "0.11.0",
|
||||
|
||||
// This field is optional.
|
||||
// Each dependency must either provide a `url` and `hash`, or a `path`.
|
||||
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
|
||||
// Once all dependencies are fetched, `zig build` no longer requires
|
||||
// internet connectivity.
|
||||
.dependencies = .{
|
||||
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
|
||||
//.example = .{
|
||||
// // When updating this field to a new URL, be sure to delete the corresponding
|
||||
// // `hash`, otherwise you are communicating that you expect to find the old hash at
|
||||
// // the new URL.
|
||||
// .url = "https://example.com/foo.tar.gz",
|
||||
//
|
||||
// // This is computed from the file contents of the directory of files that is
|
||||
// // obtained after fetching `url` and applying the inclusion rules given by
|
||||
// // `paths`.
|
||||
// //
|
||||
// // This field is the source of truth; packages do not come from a `url`; they
|
||||
// // come from a `hash`. `url` is just one of many possible mirrors for how to
|
||||
// // obtain a package matching this `hash`.
|
||||
// //
|
||||
// // Uses the [multihash](https://multiformats.io/multihash/) format.
|
||||
// .hash = "...",
|
||||
//
|
||||
// // When this is provided, the package is found in a directory relative to the
|
||||
// // build root. In this case the package's hash is irrelevant and therefore not
|
||||
// // computed. This field and `url` are mutually exclusive.
|
||||
// .path = "foo",
|
||||
|
||||
// // When this is set to `true`, a package is declared to be lazily
|
||||
// // fetched. This makes the dependency only get fetched if it is
|
||||
// // actually used.
|
||||
// .lazy = false,
|
||||
//},
|
||||
},
|
||||
|
||||
// Specifies the set of files and directories that are included in this package.
|
||||
// Only files and directories listed here are included in the `hash` that
|
||||
// is computed for this package. Only files listed here will remain on disk
|
||||
// when using the zig package manager. As a rule of thumb, one should list
|
||||
// files required for compilation plus any license(s).
|
||||
// Paths are relative to the build root. Use the empty string (`""`) to refer to
|
||||
// the build root itself.
|
||||
// A directory listed here means that all files within, recursively, are included.
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
// For example...
|
||||
//"LICENSE",
|
||||
//"README.md",
|
||||
},
|
||||
}
|
24
ziggy/src/main.zig
Normal file
24
ziggy/src/main.zig
Normal file
|
@ -0,0 +1,24 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
|
||||
std.debug.print("All your {s} are belong to us.\n", .{"codebase"});
|
||||
|
||||
// stdout is for the actual output of your application, for example if you
|
||||
// are implementing gzip, then only the compressed bytes should be sent to
|
||||
// stdout, not any debugging messages.
|
||||
const stdout_file = std.io.getStdOut().writer();
|
||||
var bw = std.io.bufferedWriter(stdout_file);
|
||||
const stdout = bw.writer();
|
||||
|
||||
try stdout.print("Run `zig build test` to run the tests.\n", .{});
|
||||
|
||||
try bw.flush(); // don't forget to flush!
|
||||
}
|
||||
|
||||
test "simple test" {
|
||||
var list = std.ArrayList(i32).init(std.testing.allocator);
|
||||
defer list.deinit(); // try commenting this out and see if zig detects the memory leak!
|
||||
try list.append(42);
|
||||
try std.testing.expectEqual(@as(i32, 42), list.pop());
|
||||
}
|
43
ziggy/src/root.zig
Normal file
43
ziggy/src/root.zig
Normal file
|
@ -0,0 +1,43 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const testing = std.testing;
|
||||
|
||||
pub extern "c" fn gettid() std.c.pid_t;
|
||||
|
||||
export fn add(a: i32, b: i32) i32 {
|
||||
if (builtin.mode == .Debug) {
|
||||
const out = std.io.getStdErr().writer();
|
||||
out.print("WARNING: Building debug mode will likely crash in Unikraft environment. Use -Doptimize=ReleaseSafe\n", .{}) catch {};
|
||||
}
|
||||
const out = std.io.getStdOut().writer();
|
||||
out.print("Hello from lib\n", .{}) catch {};
|
||||
std.log.err("logging error", .{});
|
||||
out.print("Checking thread id\n", .{}) catch {};
|
||||
out.print("WAT: {d}\n", .{gettid()}) catch {};
|
||||
out.print("Thread id: {d}\n", .{gettid()}) catch {};
|
||||
// out.print("Thread id: {d}\n", .{std.Thread.getCurrentId()}) catch {};
|
||||
// We have a theory we need posix-futex enabled for locking/unlocking
|
||||
// std.debug.print("debug print", .{});
|
||||
// if (builtin.single_threaded) @compileError("single threaded");
|
||||
return a + b + 1;
|
||||
}
|
||||
|
||||
// Unhandled Trap 6 (invalid opcode), error code=0x0
|
||||
//
|
||||
// Thread.getCurrentId() calls fall flat. It looks like they use the linux
|
||||
// call gettid, but that is not implemented by unikraft as of 0.17.0 (I
|
||||
// believe). I tried adding process/thread support, but that did not address
|
||||
// the problem. getCurrentId is used by the following:
|
||||
//
|
||||
// Mutex (only when building debug mode)
|
||||
// Condition (only when building in debug mode)
|
||||
// std.debug panic implementation
|
||||
//
|
||||
// So:
|
||||
// 1) don't call it ourselves
|
||||
// 2) build in release mode
|
||||
// 3) don't panic ;-)
|
||||
|
||||
test "basic add functionality" {
|
||||
try testing.expect(add(3, 7) == 10);
|
||||
}
|
Loading…
Reference in New Issue
Block a user