Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
branches: ["main", "144-support-musl"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to remove this change before merging


jobs:
formatting-check:
Expand Down
3 changes: 3 additions & 0 deletions so3/arch/arm32/include/asm/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@

#define USER_SPACE_VADDR 0x1000ul

/* Anonymous start virtual address */
#define USER_ANONYMOUS_VADDR UL(CONFIG_KERNEL_VADDR / 2)

/* Memory space all I/O mapped registers and additional mappings */
#define IO_MAPPING_BASE 0xe0000000

Expand Down
3 changes: 3 additions & 0 deletions so3/arch/arm32/include/asm/syscall_number.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,7 @@
#define SYSCALL_SETSOCKOPT 110
#define SYSCALL_RECVFROM 111

#define SYSCALL_READV 145
#define SYSCALL_WRITEV 146

#endif /* ARCH_ARM32_SYSCALL_NUMBER_H */
6 changes: 6 additions & 0 deletions so3/arch/arm64/include/asm/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
/* Fixmap page used for temporary mapping */
#define FIXMAP_MAPPING UL(0xffffb00000000000)

/* Anonymous start virtual address */
#define USER_ANONYMOUS_VADDR UL(0x0000000100000000)

/* The user space can be up to bits [47:0] and uses ttbr0_el1
* as main L0 page table.
*/
Expand All @@ -45,6 +48,9 @@
/* Fixmap page used for temporary mapping */
#define FIXMAP_MAPPING UL(0xffffffd800000000)

/* Anonymous start virtual address */
#define USER_ANONYMOUS_VADDR UL(0x0000000100000000)

/* The user space can be up to bits [38:0] and uses ttbr0_el1
* as main L0 page table.
*/
Expand Down
3 changes: 3 additions & 0 deletions so3/arch/arm64/include/asm/syscall_number.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
#define SYSCALL_MUTEX_LOCK 60
#define SYSCALL_MUTEX_UNLOCK 61

#define SYSCALL_READV 65
#define SYSCALL_WRITEV 66

#define SYSCALL_NANOSLEEP 70

#define SYSCALL_SYSINFO 99
Expand Down
2 changes: 1 addition & 1 deletion so3/devices/serial/pl011.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static irq_return_t pl011_int(int irq, void *dummy)

#ifdef CONFIG_IPC_SIGNAL
if (current()->pcb != NULL)
do_kill(current()->pcb->pid, SIGINT);
sys_do_kill(current()->pcb->pid, SIGINT);
#endif
}

Expand Down
8 changes: 4 additions & 4 deletions so3/fs/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ uint8_t *elf_load_buffer(const char *filename)
struct stat st;

/* open and read file */
fd = do_open(filename, O_RDONLY);
fd = sys_do_open(filename, O_RDONLY);

if (fd < 0)
return NULL;

if (do_stat(filename, &st))
if (sys_do_stat(filename, &st))
return NULL;

if (!st.st_size)
Expand All @@ -52,9 +52,9 @@ uint8_t *elf_load_buffer(const char *filename)
return NULL;
}

do_read(fd, buffer, st.st_size);
sys_do_read(fd, buffer, st.st_size);

do_close(fd);
sys_do_close(fd);

return buffer;
}
Expand Down
177 changes: 143 additions & 34 deletions so3/fs/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,8 @@ int vfs_clone_fd(int *fd_src, int *fd_dst)

/**************************** Syscall implementation ****************************/

SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count)
/* Low Level read */
static int do_read(int fd, void *buffer, int count)
{
int gfd;
int ret;
Expand Down Expand Up @@ -421,10 +422,8 @@ SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count)
return ret;
}

/**
* @brief This function writes a REGULAR FILE/FOLDER. It only support regular file, dirs and pipes
*/
SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count)
/* Low Level write */
static int do_write(int fd, const void *buffer, int count)
{
int gfd;
int ret;
Expand Down Expand Up @@ -464,6 +463,88 @@ SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count)
return ret;
}

/* Low Level mmap */
static int do_mmap(int fd, addr_t virt_addr, uint32_t page_count, off_t offset)
{
int gfd;
struct file_operations *fops;

/* Get the fops associated to the file descriptor. */
gfd = vfs_get_gfd(fd);
if (-1 == gfd) {
printk("%s: could not get global fd.\n", __func__);
return -EBADF;
}

mutex_lock(&vfs_lock);
fops = vfs_get_fops(gfd);
if (!fops) {
printk("%s: could not get device fops.\n", __func__);
mutex_unlock(&vfs_lock);
return -EBADF;
}

mutex_unlock(&vfs_lock);

if (!fops->mmap) {
printk("%s: device doesn't support mmap.\n", __func__);
return -EACCES;
}

/* Call the mmap fops that will do the actual mapping. */
return (long) fops->mmap(fd, virt_addr, page_count, offset);
}

/* Low Level mmap - Anonymous case */
static int do_mmap_anon(int fd, addr_t virt_addr, uint32_t page_count, off_t offset)
{
uint32_t page;
pcb_t *pcb;
int i;

if (offset != 0) {
printk("%s: Offset should be 0 with MAP_ANONYMOUS flag\n", __func__);
return -EINVAL;
}

pcb = current()->pcb;

/* Start is smaller or NULL than initial virt_addr pointer */
if (virt_addr < pcb->next_anon_start)
virt_addr = pcb->next_anon_start;

for (i = 0; i < page_count; i++) {
page = get_free_page();
BUG_ON(!page);

create_mapping(pcb->pgtable, virt_addr + (i * PAGE_SIZE), page, PAGE_SIZE, false);
add_page_to_proc(pcb, phys_to_page(page));
}

memset((void *) virt_addr, 0, page_count * PAGE_SIZE);

/* WARNIMG - This is a simple/basic way to set the start virtual address:
It only increment the start address after each mmap call, no algorithm
to search for available spaces.
*/
pcb->next_anon_start = virt_addr + (page_count * PAGE_SIZE);

return virt_addr;
}

SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count)
{
return do_read(fd, buffer, count);
}

/**
* @brief This function writes a REGULAR FILE/FOLDER. It only support regular file, dirs and pipes
*/
SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count)
{
return do_write(fd, buffer, count);
}

/**
* @brief This function opens a file. Not all file types are supported.
*/
Expand Down Expand Up @@ -655,7 +736,7 @@ SYSCALL_DEFINE2(dup2, int, oldfd, int, newfd)
}

if (vfs_get_gfd(oldfd) != vfs_get_gfd(newfd))
do_close(newfd);
sys_do_close(newfd);

vfs_link_fd(newfd, vfs_get_gfd(oldfd));

Expand Down Expand Up @@ -726,43 +807,20 @@ SYSCALL_DEFINE2(stat, const char *, path, struct stat *, st)
/**
* An mmap() implementation in VFS.
*/
SYSCALL_DEFINE5(mmap, addr_t, start, size_t, length, int, prot, int, fd, off_t, offset)
SYSCALL_DEFINE6(mmap, addr_t, start, size_t, length, int, prot, int, flags, int, fd, off_t, offset)
{
int gfd;
uint32_t page_count;
struct file_operations *fops;

/* Get the fops associated to the file descriptor. */

gfd = vfs_get_gfd(fd);
if (-1 == gfd) {
printk("%s: could not get global fd.\n", __func__);
return -EBADF;
}

mutex_lock(&vfs_lock);
fops = vfs_get_fops(gfd);
if (!fops) {
printk("%s: could not get device fops.\n", __func__);
mutex_unlock(&vfs_lock);
return -EBADF;
}

mutex_unlock(&vfs_lock);

/* Page count to allocate to the current process to be able to map the desired region. */
page_count = length / PAGE_SIZE;
if (length % PAGE_SIZE != 0) {
page_count++;
}

if (!fops->mmap) {
printk("%s: device doesn't support mmap.\n", __func__);
return -EACCES;
}

/* Call the mmap fops that will do the actual mapping. */
return (long) fops->mmap(fd, start, page_count, offset);
if (flags & MAP_ANONYMOUS)
return do_mmap_anon(fd, start, page_count, offset);
else
return do_mmap(fd, start, page_count, offset);
}

SYSCALL_DEFINE3(ioctl, int, fd, unsigned long, cmd, unsigned long, args)
Expand Down Expand Up @@ -824,6 +882,57 @@ SYSCALL_DEFINE3(fcntl, int, fd, unsigned long, cmd, unsigned long, args)
return 0;
}

/*
* Implementation of the writev syscall
*/
SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec *, vec, unsigned long, vlen)
{
int i;
int ret = 0;
int total = 0;

for (i = 0; i < vlen; i++) {
ret = do_write(fd, (const void *) vec[i].iov_base, vec[i].iov_len);
if (ret < 0) {
break;
} else if ((ret >= 0) && (ret < vec[i].iov_len)) {
total += ret;
break;
}

total += ret;
}

if (total == 0)
return ret;
else
return total;
}

SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec *, vec, unsigned long, vlen)
{
int i;
int ret = 0;
int total = 0;

for (i = 0; i < vlen; i++) {
ret = do_read(fd, vec[i].iov_base, vec[i].iov_len);
if (ret < 0) {
break;
} else if ((ret >= 0) && (ret < vec[i].iov_len)) {
total += ret;
break;
}

total += ret;
}

if (total == 0)
return ret;
else
return total;
}

static void vfs_gfd_init(void)
{
memset(open_fds, 0, MAX_FDS * sizeof(struct fd *));
Expand Down
3 changes: 3 additions & 0 deletions so3/include/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ struct pcb {
/* current position of the heap pointer */
addr_t heap_pointer;

/* next anonymous start pointer */
addr_t next_anon_start;

/* Number of pages required by this process (including binary image) */
size_t page_count;

Expand Down
20 changes: 10 additions & 10 deletions so3/include/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,33 +84,33 @@
* __sys_SYSCALL_NAME taking syscall_args_t as arguments allowing for
* a common interface between all syscall to put them in an array.
*
* do_SYSCALL_NAME actual function with the syscall implementation with
* sys_do_SYSCALL_NAME actual function with the syscall implementation with
* arguments define like a normal function. That function is automatically
* called by __sys_SYCALL_NAME with the correct argument number and cast.
*/
#define SYSCALL_DECLARE(name, ...) \
long __sys_##name(syscall_args_t *args); \
inline long do_##name(__VA_ARGS__);
inline long sys_do_##name(__VA_ARGS__);

#define SYSCALL_DEFINE0(name) \
long __sys_##name(syscall_args_t *unused) \
{ \
return do_##name(); \
return sys_do_##name(); \
} \
inline long do_##name(void)
inline long sys_do_##name(void)
#define SYSCALL_DEFINE1(...) __SYSCALL_DEFINEx(1, __VA_ARGS__)
#define SYSCALL_DEFINE2(...) __SYSCALL_DEFINEx(2, __VA_ARGS__)
#define SYSCALL_DEFINE3(...) __SYSCALL_DEFINEx(3, __VA_ARGS__)
#define SYSCALL_DEFINE4(...) __SYSCALL_DEFINEx(4, __VA_ARGS__)
#define SYSCALL_DEFINE5(...) __SYSCALL_DEFINEx(5, __VA_ARGS__)
#define SYSCALL_DEFINE6(...) __SYSCALL_DEFINEx(6, __VA_ARGS__)

#define __SYSCALL_DEFINEx(x, name, ...) \
long __sys_##name(syscall_args_t *args) \
{ \
return do_##name(__MAP_ARGS(x, args->args, __VA_ARGS__)); \
} \
inline long do_##name(__MAP(x, __M_DECL, __VA_ARGS__))
#define __SYSCALL_DEFINEx(x, name, ...) \
long __sys_##name(syscall_args_t *args) \
{ \
return sys_do_##name(__MAP_ARGS(x, args->args, __VA_ARGS__)); \
} \
inline long sys_do_##name(__MAP(x, __M_DECL, __VA_ARGS__))

typedef struct {
unsigned long args[6];
Expand Down
Loading
Loading