Skip to content
Merged
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
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
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
102 changes: 74 additions & 28 deletions so3/fs/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,75 @@ static int do_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);
Expand Down Expand Up @@ -738,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
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
5 changes: 4 additions & 1 deletion so3/include/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
#define DT_LNK 10 /* Symbolic link */
#define DT_SOCK 12 /* Socket device */

/* mmap flags options */
#define MAP_ANONYMOUS 0x10 /* don't use a file */

/* Return error values */
#define MAP_FAILED ((void *) -1) /* mmap fail */

Expand Down Expand Up @@ -165,7 +168,7 @@ SYSCALL_DECLARE(close, int fd);
SYSCALL_DECLARE(dup, int oldfd);
SYSCALL_DECLARE(dup2, int oldfd, int newfd);
SYSCALL_DECLARE(stat, const char *path, struct stat *st);
SYSCALL_DECLARE(mmap, addr_t start, size_t length, int prot, int fd, off_t offset);
SYSCALL_DECLARE(mmap, addr_t start, size_t length, int prot, int flags, int fd, off_t offset);
SYSCALL_DECLARE(ioctl, int fd, unsigned long cmd, unsigned long args);
SYSCALL_DECLARE(fcntl, int fd, unsigned long cmd, unsigned long args);
SYSCALL_DECLARE(lseek, int fd, off_t off, int whence);
Expand Down
2 changes: 2 additions & 0 deletions so3/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ pcb_t *new_process(void)

pcb->state = PROC_STATE_NEW;

pcb->next_anon_start = USER_ANONYMOUS_VADDR;

/* Reset the ptrace request indicator */
pcb->ptrace_pending_req = PTRACE_NO_REQUEST;

Expand Down