Skip to content
Snippets Groups Projects
Commit e70e59aa authored by Florent Gluck's avatar Florent Gluck
Browse files

Minor update to lab4

Added new lab4 skeleton: skeleton_with_labs1-3
parent 069efe9b
Branches
No related tags found
No related merge requests found
Showing
with 522 additions and 1 deletion
......@@ -73,7 +73,7 @@ Chaque tâche est un programme en cours d'exécution. Chaque programme est compi
Au niveau du code fourni, la gestion des tâches est à implémenter dans `task/task.c`. Une petite partie du code vous est fournie, mais vous devez implémenter l'essentiel des fonctionalités. Les fonctions à implémenter sont décrites ci-dessous.
**`static task_t *task_create(char *name, uint_t addr_space_size)`**
**`static task_t *task_create(uint_t addr_space_size)`**
\vspace{-2mm}
Cette fonction créée une nouvelle tâche et la retourne (ou NULL si il n'y a plus de tâche disponible). Comme le nombre de tâches maximum est limité, la fonction doit vérifier qu'il y a encore au moins une tâche de disponible (dans le tableau de tâches). Ensuite, les structures associées à la tâche doivent être initialisées et l'espace d'adressage virtuel de la tâche doit être créé, en n'oubliant pas d'allouer dynamiquement, à l'aide de frames, l'espace mémoire nécessaire pour le code, les données et la pile (taille pile fixée à `TASK_STACK_SIZE_MB` en MB). Cet espace mémoire sera typiquement alloué dynamiquement avec la fonction `paging_alloc` du module `paging.h`. Cette fonction en plus d'allouer les frames pour l'espace mémoire nécessaire, réalise également le mapping à l'adresse virtuelle spécifiée en argument et modifie le répertoire de pages passé en argument en conséquence. A noter que vous devrez libérer les frames allouées lorsque la tâche sera terminée dans la fonction `task_free`.
......
No preview for this file type
include ../common.mk
SRC=$(shell find . -iname "*.c")
OBJ=$(SRC:.c=.o)
DEP=$(SRC:.c=.d)
all: $(OBJ)
%.o: %.c
$(CC) $(CC_FLAGS) $< -o $@
%.o: %.s
nasm -f elf32 $< -o $@
clean:
/bin/rm -f $(OBJ) $(DEP)
.PHONY: clean
-include $(DEP)
#ifndef _COLORS_H_
#define _COLORS_H_
// Convert a 8-bit color component to 5 bits
// by removing the 3 least significant bits
#define COL8TO5(x) (x >> 3)
// Convert a 8-bit color component to 6 bits
// by removing the 2 least significant bits
#define COL8TO6(x) (x >> 2)
// Convert a 24-bit color to a 16-bit one (RGB565)
#define RGB(r,g,b) ((COL8TO5(r))<<11|(COL8TO6(g))<<5|(COL8TO5(b)))
// "Broadcast" a 16-bit color into a 32-bit word
#define COLTO32(x) ((x&0xFFFF) << 16|(x&0xFFFF))
#define BLACK RGB(0,0,0)
#define WHITE RGB(255,255,255)
#define RED RGB(255,0,0)
#define BLUE RGB(0,0,255)
#define GREEN RGB(0,255,0)
#define YELLOW RGB(255,255,0)
#define CYAN RGB(0,255,255)
#define GREY RGB(150,150,150)
#define LIGHT_GREY RGB(220,220,220)
#define LIGHT_BLUE RGB(150,150,220)
#define LIGHT_GREEN RGB(150,220,150)
#define LIGHT_RED RGB(255,200,200)
#define LIGHT_YELLOW RGB(220,220,150)
#define DARK_GREY RGB(80,80,80)
#define DARK_BLUE RGB(0,0,100)
#define DARK_GREEN RGB(0,100,0)
#define DARK_RED RGB(100,0,0)
#define DARK_YELLOW RGB(100,100,0)
/*
typedef enum {
MAGENTA = 5,
BROWN = 6,
LIGHT_CYAN = 11,
LIGHT_MAGENTA = 13,
} term_colortype_t;
*/
typedef struct {
uint16_t fg; // foreground color
uint16_t bg; // background color
} term_colors_t;
#endif
#ifndef _KEYCODES_COMMON_H_
#define _KEYCODES_COMMON_H_
#define KEY_ESC 50000
#define KEY_HOME 50005
#define KEY_LEFT 50006
#define KEY_RIGHT 50007
#define KEY_UP 50008
#define KEY_DOWN 50009
#define KEY_END 50010
#define KEY_PGUP 50011
#define KEY_PGDOWN 50012
#define KEY_INSERT 50013
#define KEY_DEL 50014
#define KEY_F1 50015
#define KEY_F2 50016
#define KEY_F3 50017
#define KEY_F4 50018
#define KEY_F5 50019
#define KEY_F6 50020
#define KEY_F7 50021
#define KEY_F8 50022
#define KEY_F9 50023
#define KEY_F10 50024
#define KEY_F11 50025
#define KEY_F12 50026
// Hexadecimal values of IBM PC CP437's characters
// Full table here: http://www.ascii-codes.com/
#define KEY_A_CIRCUMFLEX 0x83
#define KEY_A_DIAERESIS 0x84
#define KEY_A_GRAVE 0x85
#define KEY_C_CEDILLA 0x87
#define KEY_E_ACUTE 0x82
#define KEY_E_CIRCUMFLEX 0x88
#define KEY_E_DIAERESIS 0x89
#define KEY_E_GRAVE 0x8A
#define KEY_I_DIAERESIS 0x8B
#define KEY_I_CIRCUMFLEX 0x8C
#define KEY_O_DIAERESIS 0x94
#define KEY_U_CIRCUMFLEX 0x96
#define KEY_U_DIAERESIS 0x81
#define KEY_PARAGRAPH 0x15
#define KEY_POUND 0x9C
#define KEY_DEGREE 0xF8
#endif
#include <stdint.h>
#include "mem.h"
void memset(void *dst, uint8_t value, uint_t count) {
uint8_t *d = dst;
while (count--)
*d++ = value;
}
void memsetdw(void *dst, uint32_t value, uint_t count) {
uint32_t *d = dst;
while (count--)
*d++ = value;
}
void memcpy(void *dst, void *src, uint_t count) {
uint8_t *d = dst;
uint8_t *s = src;
while (count--)
*d++ = *s++;
}
void memcpydw(void *dst, void *src, uint_t count) {
uint32_t *d = dst;
uint32_t *s = src;
while (count--)
*d++ = *s++;
}
#ifndef _MEM_COMMON_H_
#define _MEM_COMMON_H_
#include "types.h"
// Fills count bytes of the memory area pointed to by dst with the byte value.
extern void memset(void *dst, uint8_t value, uint_t count);
// Fills count dwords of the memory area pointed to by dst with the dword value.
// NOTE: dword = double word = 32-bit
extern void memsetdw(void *dst, uint32_t value, uint_t count);
// Copy count bytes from src to dst.
extern void memcpy(void *dst, void *src, uint_t count);
// Copy count dwords from src to dst.
// NOTE: dword = double word = 32-bit
extern void memcpydw(void *dst, void *src, uint_t count);
#endif
#include <stdbool.h>
#include "stdio.h"
#include "types.h"
// Print into buf in reverse, the value val in the given base.
// The argument sign indicates whether the value is signed (true) or not (false).
// The number of characters written is returned into length.
static void printint_rev(char *buf, int *length, int val, int base, bool sign) {
static char digits[] = "0123456789ABCDEF";
int count = 0;
uint_t x;
if (sign && (sign = val < 0))
x = -val;
else
x = val;
do {
buf[count++] = digits[x % base];
} while ((x /= base) != 0);
if (sign)
buf[count++] = '-';
buf[count] = 0;
*length = count;
}
int snprintf(char *dest, int size, char *fmt, ...) {
va_list args;
va_start(args, fmt);
int count = vsnprintf(dest, size, fmt, args);
va_end(args);
return count;
}
// Helper macro used in vsnprintf
#define putc(c) \
if (size > 0) { \
*dest = c; \
dest++; \
size--; \
count++; \
}
int vsnprintf(char *dest, int size, const char *fmt, va_list args) {
char buf[size+1];
int len;
int count = 0;
while (*fmt) {
if (*fmt == '%') { // found an argument
fmt++;
if (*fmt == 0) // missing value after %
break;
switch (*fmt) {
case 'c':
{
int c = va_arg(args, int);
putc(c)
}
break;
case 's':
{
char *s = va_arg(args, char *);
while (*s) {
putc(*s)
s++;
}
}
break;
case 'd':
{
int n = va_arg(args, int);
printint_rev(buf, &len, n, 10, true);
while (len) putc(buf[--len]);
}
break;
case 'u':
{
uint_t n = va_arg(args, uint_t);
printint_rev(buf, &len, n, 10, false);
while (len) putc(buf[--len]);
}
break;
case 'x':
{
int n = va_arg(args, int);
printint_rev(buf, &len, n, 16, false);
while (len) putc(buf[--len]);
}
break;
case '%':
putc('%')
break;
default:
// unkown argument, ignore it!
break;
}
}
else {
putc(*fmt)
}
fmt++;
}
*dest = 0;
return count;
}
#ifndef _STDIO_COMMON_H_
#define _STDIO_COMMON_H_
#include <stdarg.h>
// Writes at most size characters (including terminal 0) of the formatted string fmt
// into buffer dest.
// args are the variable length arguments as a va_list.
// Returns the number of characters written.
extern int vsnprintf(char *dest, int size, const char *fmt, va_list args);
// Writes at most size characters (including terminal 0) of the formatted string fmt
// into buffer dest.
// Any arbitrary number of arguments can be passed after fmt.
// Returns the number of characters written.
extern int snprintf(char *dest, int size, char *fmt, ...);
#endif
#include <stdint.h>
#include "string.h"
uint_t strlen(const char *s) {
int n;
for (n = 0; s[n]; n++);
return n;
}
char *strncpy(char *dest, const char *src, uint_t count) {
char *p = dest;
while (count && *src) {
*p = *src;
src++;
p++;
count--;
}
*p = 0;
return dest;
}
// Original FreeBSD implementation
// Source: https://github.com/freebsd/freebsd/blob/master/lib/libc/string/strcmp.c
int strcmp(const char *s1, const char *s2) {
while (*s1 == *s2++)
if (*s1++ == '\0')
return (0);
return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
}
// Original FreeBSD implementation
// Source: https://github.com/freebsd/freebsd/blob/master/lib/libc/string/strncmp.c
int strncmp(const char *s1, const char *s2, uint_t n) {
if (n == 0)
return (0);
do {
if (*s1 != *s2++)
return (*(const unsigned char *)s1 -
*(const unsigned char *)(s2 - 1));
if (*s1++ == '\0')
break;
} while (--n != 0);
return (0);
}
uint_t atoi(const char *s) {
uint_t n = 0;
while ('0' <= *s && *s <= '9')
n = n*10 + *s++ - '0';
return n;
}
char *tolower(char *s) {
for (int n = 0; s[n]; n++) {
if (s[n] >= 'A' && s[n] <= 'Z') {
// upper case letters differ by 32 from lower case ones (man ascii)
s[n] = s[n] + 32;
}
}
return s;
}
#ifndef _STRING_COMMON_H_
#define _STRING_COMMON_H_
#include "types.h"
// Returns the length of string s.
extern uint_t strlen(const char *s);
// Copy string src into dest, copying at most count characters.
// Returns the string dest.
extern char *strncpy(char *dest, const char *src, uint_t count);
// Compare alphanumerically string s1 with s2.
// Returns:
// 0 if identical
// a value > 0 if s1 > s2
// a value < 0 if s1 < s2
extern int strcmp(const char *s1, const char *s2);
// Identical to strcmp, except that it compares up to n characters.
extern int strncmp(const char *s1, const char *s2, uint_t n);
// Returns the integer representation of string s.
// IMPORTANT: does not perform any validation on the string!
extern uint_t atoi(const char *s);
// Convert, in-place, string s to its lower case representation.
extern char *tolower(char *s);
#endif
#ifndef _SYSCALL_NB_COMMON_H_
#define _SYSCALL_NB_COMMON_H_
typedef enum {
SYSCALL_xxx = 1,
__SYSCALL_END__
} syscall_t;
#endif
#ifndef _TYPES_COMMON_H_
#define _TYPES_COMMON_H_
#include <stdint.h>
#include <stdbool.h>
typedef unsigned char uchar_t;
typedef unsigned short ushort_t;
typedef unsigned int uint_t;
typedef unsigned long long ulong_t;
#ifndef NULL
#define NULL 0
#endif
#define UNUSED(x) ((void)(x))
#endif
#ifndef _VBE_FB_COMMON_H_
#define _VBE_FB_COMMON_H_
#include "common/types.h"
typedef struct {
uint16_t *addr;
uint32_t size; // in bytes
uint32_t pitch_in_bytes;
uint32_t pitch_in_pix;
uint32_t width;
uint32_t height;
uint8_t bpp;
} vbe_fb_t;
#endif
include ../common.mk
override LD_FLAGS+=-Tkernel.ld $(BAREMETAL_FLAGS) -lgcc
KERNEL_C_SRC=$(shell find . -iname "*.c")
KERNEL_ASM_SRC=$(shell find . -iname "*.s")
KERNEL_C_OBJ=$(KERNEL_C_SRC:.c=.o)
KERNEL_C_DEP=$(KERNEL_C_SRC:.c=.d)
KERNEL_ASM_OBJ=$(KERNEL_ASM_SRC:.s=.o)
KERNEL_OUT=kernel.elf
DEP=$(KERNEL_C_OBJ:%.o=%.d)
all: $(KERNEL_OUT)
%.o: %.c
$(CC) $(CC_FLAGS) $(CC_DEFINES) -I. -I.. $< -o $@
%.o: %.s
nasm -f elf32 $< -o $@
$(KERNEL_OUT): $(KERNEL_C_OBJ) $(KERNEL_ASM_OBJ) $(COMMON_OBJ)
$(LD) $^ -o $@ $(LD_FLAGS)
clean:
$(MAKE) -C $(COMMON_DIR) clean
/bin/rm -f $(KERNEL_C_OBJ) $(KERNEL_ASM_OBJ) $(KERNEL_C_DEP)
/bin/rm -f $(KERNEL_OUT)
.PHONY: clean
-include $(DEP)
File added
#ifndef _MODULE_H_
#define _MODULE_H_
#include "common/types.h"
#include "boot/multiboot.h"
// Returns the number of detected modules.
extern uint_t modules_count();
// Returns modules' last address in use, so we can safely assume addresses above this are free.
// Returns the kernel's last address in use if no modules are detected.
extern uint32_t modules_last_address();
// Returns a module's address.
// Note: first module is at index 0.
extern void *module_first_address(uint_t index);
// Returns a module's last address in use (inclusive).
// Note: first module is at index 0.
extern void *module_last_address(uint_t index);
// Returns a module' size in bytes.
// Note: first module is at index 0.
extern uint_t module_size(uint_t index);
// Returns a module's command line.
// Returns NULL if the module's command line is empty.
// Note: first module is at index 0.
extern char* module_cmdline(uint_t index);
// Displays modules' information:
// - number of detected modules
// - for each module: address, size (in bytes), command line
extern void modules_display_info();
// Returns the address of the first module whose argument matches name.
// Returns NULL if no such module is found.
extern void *module_addr_by_name(char *name);
// Returns the size in bytes of the first module whose argument matches name.
// Returns -1 if no such module is found.
extern int module_size_by_name(char *name);
#endif
File added
File added
#ifndef _MULTIBOOT_H_
#define _MULTIBOOT_H_
#include "common/types.h"
#include "multiboot_structs.h"
// Stores the multiboot info structure.
extern void multiboot_set_info(multiboot_info_t *_mbi);
// Retrieves the multiboot info structure.
extern multiboot_info_t* multiboot_get_info();
// Retrieves the amount of available RAM in KB.
extern uint_t multiboot_get_RAM_in_KB();
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment