Compare commits
2 Commits
baca443465
...
17744e00af
Author | SHA1 | Date |
---|---|---|
Adrien Bourmault | 17744e00af | |
Adrien Bourmault | 716e4cd880 |
|
@ -20,7 +20,37 @@ Pour savoir si elle est terminale, TODO.
|
|||
|
||||
### Q3
|
||||
|
||||
fait.
|
||||
```C
|
||||
void print_pgt(paddr_t pml, uint8_t lvl) {
|
||||
paddr_t *cur = (paddr_t *)(pml & PGT_ADDR_MASK);
|
||||
|
||||
if (lvl == 0)
|
||||
return;
|
||||
if (lvl == 4)
|
||||
printk("[print_pgt]\n");
|
||||
|
||||
printk("\tPML%d @ 0x%lx exists\n",
|
||||
lvl,
|
||||
cur);
|
||||
|
||||
while (*cur) {
|
||||
printk("\t\tPML%d[%lx] -> 0x%lx (FLAGS ",
|
||||
lvl,
|
||||
cur,
|
||||
(uint64_t)(*cur) & PGT_ADDR_MASK);
|
||||
if (*cur & PGT_USER_MASK)
|
||||
printk("U");
|
||||
if (*cur & PGT_WRITABLE_MASK)
|
||||
printk("W");
|
||||
if (*cur & PGT_VALID_MASK)
|
||||
printk("P");
|
||||
printk(")\n");
|
||||
if (*cur & PGT_ADDR_MASK)
|
||||
print_pgt(*cur, lvl - 1);
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Exercice 2
|
||||
|
||||
|
@ -34,7 +64,99 @@ $$index = (vaddr & (0x1FF000 << (9 × (lvl-1)))) >> (12 + (9 × (lvl-1)))$$
|
|||
|
||||
### Q2
|
||||
|
||||
fait.
|
||||
```C
|
||||
void map_page(struct task *ctx, vaddr_t vaddr, paddr_t paddr)
|
||||
{
|
||||
uint64_t *cur_pml = NULL;
|
||||
uint64_t *cr3_pml = NULL;
|
||||
uint64_t n = 4;
|
||||
|
||||
// We have to create a new page table
|
||||
if (!ctx->pgt) {
|
||||
|
||||
// Creating PML4
|
||||
ctx->pgt = alloc_page();
|
||||
cur_pml = (uint64_t *)ctx->pgt;
|
||||
|
||||
// Creating PML3
|
||||
cur_pml[PGT_PML_INDEX(4, 0x0)] = alloc_page();
|
||||
cur_pml[PGT_PML_INDEX(4, 0x0)] |= PGT_VALID_MASK
|
||||
| PGT_WRITABLE_MASK
|
||||
| PGT_USER_MASK;
|
||||
|
||||
// Getting PML3 entry in PML4 from CR3
|
||||
cur_pml = (uint64_t *)(cur_pml[PGT_PML_INDEX(4, 0x0)]
|
||||
& PGT_ADDR_MASK);
|
||||
cr3_pml = (uint64_t *)(store_cr3()
|
||||
& PGT_ADDR_MASK);
|
||||
cr3_pml = (uint64_t *)(cr3_pml[PGT_PML_INDEX(4, 0x0)]
|
||||
& PGT_ADDR_MASK);
|
||||
|
||||
// Duplicating PML2 entry in PML3
|
||||
cur_pml[PGT_PML_INDEX(3, 0x0)] =
|
||||
cr3_pml[PGT_PML_INDEX(3, 0x0)];
|
||||
}
|
||||
|
||||
cur_pml = (uint64_t *)ctx->pgt;
|
||||
|
||||
/* printk("[map_page] trying to map 0x%lx -> 0x%lx\n", */
|
||||
/* vaddr, paddr); */
|
||||
|
||||
// Exploring each level to the ground
|
||||
while(n > 1) {
|
||||
// Checking entry validity if level n > 1
|
||||
// Also checking if ADDR != 0
|
||||
if (cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_VALID_MASK
|
||||
&& cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_ADDR_MASK) {
|
||||
/* printk("[map_page] PML%d entry 0x%lx @ 0x%lx is valid (=0x%lx)\n", */
|
||||
/* n, */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)], */
|
||||
/* &cur_pml[PGT_PML_INDEX(n, vaddr)], */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)] */
|
||||
/* & PGT_VALID_MASK); */
|
||||
} else {
|
||||
/* printk("[map_page] PML%d entry 0x%lx @ 0x%lx is NOT valid (=0x%lx)\n", */
|
||||
/* n, */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)], */
|
||||
/* &cur_pml[PGT_PML_INDEX(n, vaddr)], */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)] */
|
||||
/* & PGT_VALID_MASK); */
|
||||
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)] = alloc_page();
|
||||
|
||||
/* printk("[map_page] allocated page at 0x%lx\n", */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)]); */
|
||||
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)] |= PGT_VALID_MASK
|
||||
| PGT_WRITABLE_MASK
|
||||
| PGT_USER_MASK;
|
||||
}
|
||||
// Computing the next PML_n entry
|
||||
cur_pml = (uint64_t *)(cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_ADDR_MASK);
|
||||
n--;
|
||||
}
|
||||
|
||||
// Mapping, we're n == 1
|
||||
// Checking validity and addr != 0
|
||||
if (cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_VALID_MASK) {
|
||||
printk("[map_page] ERR : vaddr 0x%lx WAS ALREADY mapped to 0x%lx !!!\n",
|
||||
vaddr,
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)]
|
||||
& PGT_ADDR_MASK);
|
||||
return;
|
||||
} else {
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)] = paddr | PGT_VALID_MASK
|
||||
| PGT_WRITABLE_MASK
|
||||
| PGT_USER_MASK;
|
||||
|
||||
/* printk("[map_page] vaddr 0x%lx mapped to 0x%lx\n", */
|
||||
/* vaddr, */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)] */
|
||||
/* & PGT_ADDR_MASK); */
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Exercice 3
|
||||
|
||||
|
@ -94,3 +216,60 @@ On va donc avoir en commun :
|
|||
### Q3
|
||||
|
||||
|
||||
Le payload se situe à partir de l'adresse 0x2000000000. L'adresse de début du payload sera `0x2000000000` et sa fin à `0x2000000000 + ctx->load_end_paddr - ctx->load_paddr`, qui constituera le début du bss, qui lui se termine à `ctx->bss_end_vaddr`.
|
||||
|
||||
|
||||
### Q4
|
||||
|
||||
```C
|
||||
void load_task(struct task *ctx)
|
||||
{
|
||||
uint64_t *cur_vaddr = NULL;
|
||||
uint64_t *end_vaddr = NULL;
|
||||
|
||||
cur_vaddr = (uint64_t *)ctx->load_vaddr;
|
||||
end_vaddr = (uint64_t *)(ctx->load_vaddr
|
||||
+ ctx->load_end_paddr
|
||||
- ctx->load_paddr);
|
||||
|
||||
// Allocating payload pages
|
||||
while (cur_vaddr < end_vaddr) {
|
||||
map_page(ctx, (vaddr_t)cur_vaddr, alloc_page());
|
||||
cur_vaddr += PGT_PAGE_SIZE;
|
||||
}
|
||||
|
||||
//printk("\tfinished map payload\n");
|
||||
|
||||
// Allocating bss
|
||||
while ((vaddr_t)cur_vaddr < ctx->bss_end_vaddr) {
|
||||
map_page(ctx, (vaddr_t)cur_vaddr, alloc_page());
|
||||
}
|
||||
|
||||
// Mapping one stack page
|
||||
map_page(ctx, (vaddr_t)ctx->context.rsp - PGT_PAGE_SIZE, alloc_page());
|
||||
|
||||
printk("[load_task] task from @0x%lx loaded\n", ctx->load_paddr);
|
||||
}
|
||||
```
|
||||
|
||||
### Q5
|
||||
|
||||
```C
|
||||
void set_task(struct task *ctx)
|
||||
{
|
||||
uint64_t *cur_vaddr = (uint64_t *)(ctx->load_vaddr
|
||||
+ ctx->load_end_paddr
|
||||
- ctx->load_paddr);
|
||||
load_cr3(ctx->pgt);
|
||||
printk("[set_task] new PML4 loaded @ 0x%lx\n", ctx->pgt);
|
||||
|
||||
// Zeroing page
|
||||
while((vaddr_t)cur_vaddr < ctx->bss_end_vaddr) {
|
||||
*cur_vaddr = (uint64_t)0;
|
||||
cur_vaddr++;
|
||||
}
|
||||
printk("[set_task] task set @ 0x%lx (PML4 at 0x%lx)\n",
|
||||
ctx->load_paddr, ctx->pgt);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -20,7 +20,37 @@ Pour savoir si elle est terminale, TODO.
|
|||
|
||||
### Q3
|
||||
|
||||
fait.
|
||||
```C
|
||||
void print_pgt(paddr_t pml, uint8_t lvl) {
|
||||
paddr_t *cur = (paddr_t *)(pml & PGT_ADDR_MASK);
|
||||
|
||||
if (lvl == 0)
|
||||
return;
|
||||
if (lvl == 4)
|
||||
printk("[print_pgt]\n");
|
||||
|
||||
printk("\tPML%d @ 0x%lx exists\n",
|
||||
lvl,
|
||||
cur);
|
||||
|
||||
while (*cur) {
|
||||
printk("\t\tPML%d[%lx] -> 0x%lx (FLAGS ",
|
||||
lvl,
|
||||
cur,
|
||||
(uint64_t)(*cur) & PGT_ADDR_MASK);
|
||||
if (*cur & PGT_USER_MASK)
|
||||
printk("U");
|
||||
if (*cur & PGT_WRITABLE_MASK)
|
||||
printk("W");
|
||||
if (*cur & PGT_VALID_MASK)
|
||||
printk("P");
|
||||
printk(")\n");
|
||||
if (*cur & PGT_ADDR_MASK)
|
||||
print_pgt(*cur, lvl - 1);
|
||||
cur++;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Exercice 2
|
||||
|
||||
|
@ -34,6 +64,212 @@ $$index = (vaddr & (0x1FF000 << (9 × (lvl-1)))) >> (12 + (9 × (lvl-1)))$$
|
|||
|
||||
### Q2
|
||||
|
||||
```C
|
||||
void map_page(struct task *ctx, vaddr_t vaddr, paddr_t paddr)
|
||||
{
|
||||
uint64_t *cur_pml = NULL;
|
||||
uint64_t *cr3_pml = NULL;
|
||||
uint64_t n = 4;
|
||||
|
||||
// We have to create a new page table
|
||||
if (!ctx->pgt) {
|
||||
|
||||
// Creating PML4
|
||||
ctx->pgt = alloc_page();
|
||||
cur_pml = (uint64_t *)ctx->pgt;
|
||||
|
||||
// Creating PML3
|
||||
cur_pml[PGT_PML_INDEX(4, 0x0)] = alloc_page();
|
||||
cur_pml[PGT_PML_INDEX(4, 0x0)] |= PGT_VALID_MASK
|
||||
| PGT_WRITABLE_MASK
|
||||
| PGT_USER_MASK;
|
||||
|
||||
// Getting PML3 entry in PML4 from CR3
|
||||
cur_pml = (uint64_t *)(cur_pml[PGT_PML_INDEX(4, 0x0)]
|
||||
& PGT_ADDR_MASK);
|
||||
cr3_pml = (uint64_t *)(store_cr3()
|
||||
& PGT_ADDR_MASK);
|
||||
cr3_pml = (uint64_t *)(cr3_pml[PGT_PML_INDEX(4, 0x0)]
|
||||
& PGT_ADDR_MASK);
|
||||
|
||||
// Duplicating PML2 entry in PML3
|
||||
cur_pml[PGT_PML_INDEX(3, 0x0)] =
|
||||
cr3_pml[PGT_PML_INDEX(3, 0x0)];
|
||||
}
|
||||
|
||||
cur_pml = (uint64_t *)ctx->pgt;
|
||||
|
||||
/* printk("[map_page] trying to map 0x%lx -> 0x%lx\n", */
|
||||
/* vaddr, paddr); */
|
||||
|
||||
// Exploring each level to the ground
|
||||
while(n > 1) {
|
||||
// Checking entry validity if level n > 1
|
||||
// Also checking if ADDR != 0
|
||||
if (cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_VALID_MASK
|
||||
&& cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_ADDR_MASK) {
|
||||
/* printk("[map_page] PML%d entry 0x%lx @ 0x%lx is valid (=0x%lx)\n", */
|
||||
/* n, */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)], */
|
||||
/* &cur_pml[PGT_PML_INDEX(n, vaddr)], */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)] */
|
||||
/* & PGT_VALID_MASK); */
|
||||
} else {
|
||||
/* printk("[map_page] PML%d entry 0x%lx @ 0x%lx is NOT valid (=0x%lx)\n", */
|
||||
/* n, */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)], */
|
||||
/* &cur_pml[PGT_PML_INDEX(n, vaddr)], */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)] */
|
||||
/* & PGT_VALID_MASK); */
|
||||
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)] = alloc_page();
|
||||
|
||||
/* printk("[map_page] allocated page at 0x%lx\n", */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)]); */
|
||||
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)] |= PGT_VALID_MASK
|
||||
| PGT_WRITABLE_MASK
|
||||
| PGT_USER_MASK;
|
||||
}
|
||||
// Computing the next PML_n entry
|
||||
cur_pml = (uint64_t *)(cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_ADDR_MASK);
|
||||
n--;
|
||||
}
|
||||
|
||||
// Mapping, we're n == 1
|
||||
// Checking validity and addr != 0
|
||||
if (cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_VALID_MASK) {
|
||||
printk("[map_page] ERR : vaddr 0x%lx WAS ALREADY mapped to 0x%lx !!!\n",
|
||||
vaddr,
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)]
|
||||
& PGT_ADDR_MASK);
|
||||
return;
|
||||
} else {
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)] = paddr | PGT_VALID_MASK
|
||||
| PGT_WRITABLE_MASK
|
||||
| PGT_USER_MASK;
|
||||
|
||||
/* printk("[map_page] vaddr 0x%lx mapped to 0x%lx\n", */
|
||||
/* vaddr, */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)] */
|
||||
/* & PGT_ADDR_MASK); */
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Exercice 3
|
||||
|
||||
### Q1
|
||||
|
||||
L'adresse 0x2000000030 correspond à la zone de pile (stack) utilisateur,
|
||||
on peut donc supposer que la faute de page est provoquée par un appel de fonction
|
||||
effectué depuis le code utilisateur.
|
||||
|
||||
### Q2
|
||||
|
||||
+----------------------+ 0xffffffffffffffff
|
||||
| Higher half |
|
||||
| (unused) |
|
||||
+----------------------+ 0xffff800000000000
|
||||
| (impossible address) |
|
||||
+----------------------+ 0x00007fffffffffff
|
||||
| User |
|
||||
| (text + data + heap) |
|
||||
+----------------------+ 0x2000000000
|
||||
| User |
|
||||
| (stack) |
|
||||
+----------------------+ 0x40000000
|
||||
| Kernel |
|
||||
| (valloc) |
|
||||
+----------------------+ 0x201000
|
||||
| Kernel |
|
||||
| (APIC) |
|
||||
+----------------------+ 0x200000
|
||||
| Kernel |
|
||||
| (text + data) |
|
||||
+----------------------+ 0x100000
|
||||
| Kernel |
|
||||
| (BIOS + VGA) |
|
||||
+----------------------+ 0x0
|
||||
|
||||
Pour toutes les tâches, les zones communes sont évidemment celles du noyau (car
|
||||
il faut pouvoir effectuer des appels système notamment, avoir un buffer VGA
|
||||
fonctionnel).
|
||||
|
||||
On va donc avoir en commun :
|
||||
|
||||
+----------------------+ 0x40000000
|
||||
| Kernel |
|
||||
| (valloc) |
|
||||
+----------------------+ 0x201000
|
||||
| Kernel |
|
||||
| (APIC) |
|
||||
+----------------------+ 0x200000
|
||||
| Kernel |
|
||||
| (text + data) |
|
||||
+----------------------+ 0x100000
|
||||
| Kernel |
|
||||
| (BIOS + VGA) |
|
||||
+----------------------+ 0x0
|
||||
|
||||
### Q3
|
||||
|
||||
|
||||
Le payload se situe à partir de l'adresse 0x2000000000. L'adresse de début du payload sera `0x2000000000` et sa fin à `0x2000000000 + ctx->load_end_paddr - ctx->load_paddr`, qui constituera le début du bss, qui lui se termine à `ctx->bss_end_vaddr`.
|
||||
|
||||
|
||||
### Q4
|
||||
|
||||
```C
|
||||
void load_task(struct task *ctx)
|
||||
{
|
||||
uint64_t *cur_vaddr = NULL;
|
||||
uint64_t *end_vaddr = NULL;
|
||||
|
||||
cur_vaddr = (uint64_t *)ctx->load_vaddr;
|
||||
end_vaddr = (uint64_t *)(ctx->load_vaddr
|
||||
+ ctx->load_end_paddr
|
||||
- ctx->load_paddr);
|
||||
|
||||
// Allocating payload pages
|
||||
while (cur_vaddr < end_vaddr) {
|
||||
map_page(ctx, (vaddr_t)cur_vaddr, alloc_page());
|
||||
cur_vaddr += PGT_PAGE_SIZE;
|
||||
}
|
||||
|
||||
//printk("\tfinished map payload\n");
|
||||
|
||||
// Allocating bss
|
||||
while ((vaddr_t)cur_vaddr < ctx->bss_end_vaddr) {
|
||||
map_page(ctx, (vaddr_t)cur_vaddr, alloc_page());
|
||||
}
|
||||
|
||||
// Mapping one stack page
|
||||
map_page(ctx, (vaddr_t)ctx->context.rsp - PGT_PAGE_SIZE, alloc_page());
|
||||
|
||||
printk("[load_task] task from @0x%lx loaded\n", ctx->load_paddr);
|
||||
}
|
||||
```
|
||||
|
||||
### Q5
|
||||
|
||||
```C
|
||||
void set_task(struct task *ctx)
|
||||
{
|
||||
uint64_t *cur_vaddr = (uint64_t *)(ctx->load_vaddr
|
||||
+ ctx->load_end_paddr
|
||||
- ctx->load_paddr);
|
||||
load_cr3(ctx->pgt);
|
||||
printk("[set_task] new PML4 loaded @ 0x%lx\n", ctx->pgt);
|
||||
|
||||
// Zeroing page
|
||||
while((vaddr_t)cur_vaddr < ctx->bss_end_vaddr) {
|
||||
*cur_vaddr = (uint64_t)0;
|
||||
cur_vaddr++;
|
||||
}
|
||||
printk("[set_task] task set @ 0x%lx (PML4 at 0x%lx)\n",
|
||||
ctx->load_paddr, ctx->pgt);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ BIN := bin/
|
|||
|
||||
AS := gcc
|
||||
ASFLAGS := -Wall -Wextra -O2 -nostdlib -nodefaultlibs
|
||||
CC := gcc
|
||||
CC := gcc -g
|
||||
CCFLAGS := -Wall -Wextra -O2 -nostdlib -nodefaultlibs -fno-builtin \
|
||||
-fno-stack-protector -Wno-implicit-fallthrough -mno-sse -mno-mmx
|
||||
LD := ld
|
||||
|
@ -149,4 +149,17 @@ clean:
|
|||
$(Q)rm -rf $(OBJ) $(BIN) 2> /dev/null || true
|
||||
|
||||
|
||||
gdb: all $(BIN)rackdoll.iso
|
||||
$(call cmd-print, BOOT $(BIN)rackdoll.iso)
|
||||
$(Q)qemu-system-x86_64 -smp 1 -m 4G \
|
||||
-drive file=$(BIN)rackdoll.iso,format=raw -monitor stdio \
|
||||
-no-reboot -no-shutdown -d \
|
||||
cpu_reset,guest_errors,pcall,int -s -S 2> qemu.log &
|
||||
$(Q)gdb \
|
||||
-ex "set arch i386:x86-64:intel" \
|
||||
-ex "target remote localhost:1234" \
|
||||
-ex "symbol-file $(BIN)rackdoll.elf" \
|
||||
-ex "break main_multiboot2"
|
||||
|
||||
|
||||
.SECONDARY:
|
||||
|
|
|
@ -11,7 +11,6 @@ paddr_t alloc_page(void); /* Allocate a physical page identity mapped */
|
|||
|
||||
void free_page(paddr_t addr); /* Release a page allocated with alloc_page() */
|
||||
|
||||
|
||||
void map_page(struct task *ctx, vaddr_t vaddr, paddr_t paddr);
|
||||
|
||||
void load_task(struct task *ctx);
|
||||
|
|
|
@ -58,6 +58,17 @@
|
|||
#define RFLAGS_VIP (1ul << 20)
|
||||
#define RFLAGS_ID (1ul << 21)
|
||||
|
||||
/*
|
||||
* Memory
|
||||
*/
|
||||
#define PGT_VALID_MASK (1 << 0)
|
||||
#define PGT_WRITABLE_MASK (1 << 1)
|
||||
#define PGT_USER_MASK (1 << 2)
|
||||
#define PGT_ADDR_MASK (0xFFFFFFFFFFFFF000)
|
||||
|
||||
#define PGT_PML_INDEX(n, vaddr) (vaddr & (0x1FF000ul << (9ul * (n-1ul)))) >> (12ul + (9ul * (n-1ul)))
|
||||
|
||||
#define PGT_PAGE_SIZE 4096
|
||||
|
||||
static inline void load_rsp(uint64_t rsp)
|
||||
{
|
||||
|
@ -172,13 +183,5 @@ static inline uint64_t rdmsr(uint32_t msr)
|
|||
asm volatile ("rdmsr" : "=a" (eax), "=d" (edx) : "c" (msr));
|
||||
return (((uint64_t) edx) << 32) | eax;
|
||||
}
|
||||
|
||||
#define PGT_VALID_MASK (1 << 0)
|
||||
#define PGT_WRITABLE_MASK (1 << 1)
|
||||
#define PGT_USER_MASK (1 << 2)
|
||||
#define PGT_ADDR_MASK (0xFFFFFFFFFFFFF000)
|
||||
|
||||
#define PGT_PML_INDEX(n, vaddr) (vaddr & (0x1FF000 << (9 * (n-1)))) >> (12 + (9 * (n-1)))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -82,3 +82,4 @@ void main_multiboot2(void *mb2)
|
|||
printk("\nGoodbye!\n"); /* fairewell */
|
||||
die(); /* the work is done, we can die now... */
|
||||
}
|
||||
|
||||
|
|
|
@ -104,14 +104,43 @@ void free_page(paddr_t addr)
|
|||
|
||||
void map_page(struct task *ctx, vaddr_t vaddr, paddr_t paddr)
|
||||
{
|
||||
uint64_t *cur_pml = (uint64_t *)ctx->pgt;
|
||||
int n = 4;
|
||||
uint64_t *cur_pml = NULL;
|
||||
uint64_t *cr3_pml = NULL;
|
||||
uint64_t n = 4;
|
||||
|
||||
// We have to create a new page table
|
||||
if (!ctx->pgt) {
|
||||
|
||||
// Creating PML4
|
||||
ctx->pgt = alloc_page();
|
||||
cur_pml = (uint64_t *)ctx->pgt;
|
||||
|
||||
printk("[map_page] trying to map 0x%lx -> 0x%lx\n",
|
||||
vaddr, paddr);
|
||||
// Creating PML3
|
||||
cur_pml[PGT_PML_INDEX(4, 0x0)] = alloc_page();
|
||||
cur_pml[PGT_PML_INDEX(4, 0x0)] |= PGT_VALID_MASK
|
||||
| PGT_WRITABLE_MASK
|
||||
| PGT_USER_MASK;
|
||||
|
||||
// Getting PML3 entry in PML4 from CR3
|
||||
cur_pml = (uint64_t *)(cur_pml[PGT_PML_INDEX(4, 0x0)]
|
||||
& PGT_ADDR_MASK);
|
||||
cr3_pml = (uint64_t *)(store_cr3()
|
||||
& PGT_ADDR_MASK);
|
||||
cr3_pml = (uint64_t *)(cr3_pml[PGT_PML_INDEX(4, 0x0)]
|
||||
& PGT_ADDR_MASK);
|
||||
|
||||
// Duplicating PML2 entry in PML3
|
||||
cur_pml[PGT_PML_INDEX(3, 0x0)] =
|
||||
cr3_pml[PGT_PML_INDEX(3, 0x0)];
|
||||
}
|
||||
|
||||
cur_pml = (uint64_t *)ctx->pgt;
|
||||
|
||||
/* printk("[map_page] trying to map 0x%lx -> 0x%lx\n", */
|
||||
/* vaddr, paddr); */
|
||||
|
||||
// Exploring each level to the ground
|
||||
while(n > 1) {
|
||||
while(n > 1) {
|
||||
// Checking entry validity if level n > 1
|
||||
// Also checking if ADDR != 0
|
||||
if (cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_VALID_MASK
|
||||
|
@ -132,8 +161,8 @@ void map_page(struct task *ctx, vaddr_t vaddr, paddr_t paddr)
|
|||
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)] = alloc_page();
|
||||
|
||||
printk("[map_page] Allocated page at 0x%lx\n",
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)]);
|
||||
/* printk("[map_page] allocated page at 0x%lx\n", */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)]); */
|
||||
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)] |= PGT_VALID_MASK
|
||||
| PGT_WRITABLE_MASK
|
||||
|
@ -147,7 +176,7 @@ void map_page(struct task *ctx, vaddr_t vaddr, paddr_t paddr)
|
|||
// Mapping, we're n == 1
|
||||
// Checking validity and addr != 0
|
||||
if (cur_pml[PGT_PML_INDEX(n, vaddr)] & PGT_VALID_MASK) {
|
||||
printk("[map_page] vaddr 0x%lx WAS ALREADY mapped to 0x%lx !!!\n",
|
||||
printk("[map_page] ERR : vaddr 0x%lx WAS ALREADY mapped to 0x%lx !!!\n",
|
||||
vaddr,
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)]
|
||||
& PGT_ADDR_MASK);
|
||||
|
@ -157,20 +186,58 @@ void map_page(struct task *ctx, vaddr_t vaddr, paddr_t paddr)
|
|||
| PGT_WRITABLE_MASK
|
||||
| PGT_USER_MASK;
|
||||
|
||||
printk("[map_page] vaddr 0x%lx mapped to 0x%lx\n",
|
||||
vaddr,
|
||||
cur_pml[PGT_PML_INDEX(n, vaddr)]
|
||||
& PGT_ADDR_MASK);
|
||||
/* printk("[map_page] vaddr 0x%lx mapped to 0x%lx\n", */
|
||||
/* vaddr, */
|
||||
/* cur_pml[PGT_PML_INDEX(n, vaddr)] */
|
||||
/* & PGT_ADDR_MASK); */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void load_task(struct task *ctx)
|
||||
{
|
||||
uint64_t *cur_vaddr = NULL;
|
||||
uint64_t *end_vaddr = NULL;
|
||||
|
||||
cur_vaddr = (uint64_t *)ctx->load_vaddr;
|
||||
end_vaddr = (uint64_t *)(ctx->load_vaddr
|
||||
+ ctx->load_end_paddr
|
||||
- ctx->load_paddr);
|
||||
|
||||
// Allocating payload pages
|
||||
while (cur_vaddr < end_vaddr) {
|
||||
map_page(ctx, (vaddr_t)cur_vaddr, alloc_page());
|
||||
cur_vaddr += PGT_PAGE_SIZE;
|
||||
}
|
||||
|
||||
//printk("\tfinished map payload\n");
|
||||
|
||||
// Allocating bss
|
||||
while ((vaddr_t)cur_vaddr < ctx->bss_end_vaddr) {
|
||||
map_page(ctx, (vaddr_t)cur_vaddr, alloc_page());
|
||||
}
|
||||
|
||||
// Mapping one stack page
|
||||
map_page(ctx, (vaddr_t)ctx->context.rsp - PGT_PAGE_SIZE, alloc_page());
|
||||
|
||||
printk("[load_task] task from @0x%lx loaded\n", ctx->load_paddr);
|
||||
}
|
||||
|
||||
void set_task(struct task *ctx)
|
||||
{
|
||||
uint64_t *cur_vaddr = (uint64_t *)(ctx->load_vaddr
|
||||
+ ctx->load_end_paddr
|
||||
- ctx->load_paddr);
|
||||
load_cr3(ctx->pgt);
|
||||
printk("[set_task] new PML4 loaded @ 0x%lx\n", ctx->pgt);
|
||||
|
||||
// Zeroing page
|
||||
while((vaddr_t)cur_vaddr < ctx->bss_end_vaddr) {
|
||||
*cur_vaddr = (uint64_t)0;
|
||||
cur_vaddr++;
|
||||
}
|
||||
printk("[set_task] task set @ 0x%lx (PML4 at 0x%lx)\n",
|
||||
ctx->load_paddr, ctx->pgt);
|
||||
}
|
||||
|
||||
void mmap(struct task *ctx, vaddr_t vaddr)
|
||||
|
|
|
@ -13,5 +13,5 @@
|
|||
\gdef\HyperFirstAtBeginDocument#1{#1}
|
||||
\providecommand*\HyPL@Entry[1]{}
|
||||
\HyPL@Entry{0<</S/D>>}
|
||||
\pgfsyspdfmark {pgfid2}{559409}{53288039}
|
||||
\pgfsyspdfmark {pgfid2}{559409}{53847448}
|
||||
\gdef \@abspage@last{1}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
This is XeTeX, Version 3.141592653-2.6-0.999995 (TeX Live 2023/GNU Guix) (preloaded format=xelatex 2023.7.11) 15 OCT 2023 19:33
|
||||
This is XeTeX, Version 3.141592653-2.6-0.999995 (TeX Live 2023/GNU Guix) (preloaded format=xelatex 2023.7.11) 15 OCT 2023 21:39
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
|
@ -901,14 +901,14 @@ Package hyperref Info: Link coloring OFF on input line 26.
|
|||
* layoutoffset:(h,v)=(0.0pt,0.0pt)
|
||||
* modes:
|
||||
* h-part:(L,W,R)=(8.5359pt, 580.43607pt, 8.5359pt)
|
||||
* v-part:(T,H,B)=(8.5359pt, 827.97504pt, 8.5359pt)
|
||||
* v-part:(T,H,B)=(0.0pt, 836.51094pt, 8.5359pt)
|
||||
* \paperwidth=597.50787pt
|
||||
* \paperheight=845.04684pt
|
||||
* \textwidth=580.43607pt
|
||||
* \textheight=827.97504pt
|
||||
* \textheight=836.51094pt
|
||||
* \oddsidemargin=-63.73409pt
|
||||
* \evensidemargin=-63.73409pt
|
||||
* \topmargin=-100.73409pt
|
||||
* \topmargin=-109.26999pt
|
||||
* \headheight=12.0pt
|
||||
* \headsep=25.0pt
|
||||
* \topskip=10.0pt
|
||||
|
@ -955,11 +955,6 @@ LaTeX Font Info: External font `cmex10' loaded for size
|
|||
LaTeX Font Info: External font `cmex10' loaded for size
|
||||
(Font) <5> on input line 62.
|
||||
|
||||
Overfull \hbox (3.73265pt too wide) in paragraph at lines 61--70
|
||||
[]
|
||||
[]
|
||||
|
||||
|
||||
Underfull \hbox (badness 10000) in paragraph at lines 73--74
|
||||
|
||||
[]
|
||||
|
@ -1069,8 +1064,8 @@ LaTeX Font Info: External font `cmex10' loaded for size
|
|||
LaTeX Font Info: Font shape `TU/Raleway(0)/b/n' will be
|
||||
(Font) scaled to size 9.0pt on input line 149.
|
||||
|
||||
Underfull \hbox (badness 2452) in paragraph at lines 149--149
|
||||
\TU/Raleway(0)/m/sc/9 SystÈmes Électroniques, systÈmes informatiques $\OMS/cmsy/m/n/9 ^^A$ \TU/Raleway(0)/m/n/9 Sor-
|
||||
Underfull \hbox (badness 2707) in paragraph at lines 149--149
|
||||
\TU/Raleway(0)/m/sc/9 Systèmes électroniques, systèmes informatiques $\OMS/cmsy/m/n/9 ^^A$ \TU/Raleway(0)/m/n/9 Sor-
|
||||
[]
|
||||
|
||||
File: su.png Graphic file (type bmp)
|
||||
|
@ -1106,15 +1101,18 @@ File: fsf.png Graphic file (type bmp)
|
|||
[1
|
||||
|
||||
] (./cv.aux)
|
||||
|
||||
LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
|
||||
|
||||
Package rerunfilecheck Info: File `cv.out' has not changed.
|
||||
(rerunfilecheck) Checksum: D41D8CD98F00B204E9800998ECF8427E;0.
|
||||
)
|
||||
Here is how much of TeX's memory you used:
|
||||
30197 strings out of 476682
|
||||
662162 string characters out of 5779954
|
||||
1887018 words of memory out of 5000000
|
||||
49845 multiletter control sequences out of 15000+600000
|
||||
518836 words of font info for 101 fonts, out of 8000000 for 9000
|
||||
30192 strings out of 476682
|
||||
662087 string characters out of 5779954
|
||||
1886018 words of memory out of 5000000
|
||||
49842 multiletter control sequences out of 15000+600000
|
||||
518828 words of font info for 100 fonts, out of 8000000 for 9000
|
||||
1348 hyphenation exceptions out of 8191
|
||||
129i,12n,132p,446b,1003s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -4,7 +4,7 @@
|
|||
%\usepackage[utf8]{inputenc}
|
||||
%\usepackage{fontspec}
|
||||
\usepackage[default]{raleway}
|
||||
\usepackage[margin=0.3cm, a4paper]{geometry}
|
||||
\usepackage[margin=0.3cm, a4paper, top=0cm]{geometry}
|
||||
%\usepackage{arev}
|
||||
|
||||
%------------------------------------------------------------------ Variablen
|
||||
|
@ -33,7 +33,7 @@
|
|||
|
||||
|
||||
|
||||
\header{}{\bgupper{headerfontbox}{headerfontboxfont}{\bfseries\LARGE Stagiaire chef de projet}}{\bgupper{headerfontbox}{headerfontboxfont}{\bfseries\Large informatique embarquée}}{photo.jpg}{headerblue}{2.5cm}{0cm}
|
||||
\header{}{\bgupper{headerfontbox}{headerfontboxfont}{\bfseries\LARGE Stagiaire chef de projet}}{\bgupper{headerfontbox}{headerfontboxfont}{\bfseries\Large informatique embarquée}}{photo.jpg}{headerblue}{2.5cm}{1cm}
|
||||
|
||||
|
||||
|
||||
|
@ -60,8 +60,8 @@
|
|||
\setasidefontcolour
|
||||
\bg{cvgreen}{white}{\Large Adrien BOURMAULT} \\
|
||||
\begin{tabular}{ll}
|
||||
\faAt&\url{neox@gnu.org}\\
|
||||
\faAt&\url{adrien.bourmault@etu.upmc.fr}\\
|
||||
\faAt&\href{mailto:neox@gnu.org}{neox@gnu.org}\\
|
||||
\faAt&\href{mailto:adrien.bourmault@etu.upmc.fr}{adrien.bourmault@etu.upmc.fr}\\
|
||||
\faPhone&06.73.81.53.67 \\
|
||||
\faMapMarker&5 rue Boissonade \\
|
||||
&77340 Pontault-Combault \\
|
||||
|
@ -146,7 +146,7 @@ Capacité rédactionnelle.
|
|||
\section*{\large Formation}
|
||||
|
||||
\begin{tabular}{r| p{0.45\textwidth} c}
|
||||
\cvevent{2021--}{Master d'informatique}{SystÈmes Électroniques, systÈmes informatiques}{Sorbonne Université}{VLSI, Architecture, Programmation parallèle, Noyau mémoire et virtualisation.}{su.png} \\
|
||||
\cvevent{2021--}{Master d'informatique}{Systèmes électroniques, systèmes informatiques}{Sorbonne Université}{VLSI, Architecture, Programmation parallèle, Noyau mémoire et virtualisation.}{su.png} \\
|
||||
\cvevent{2018--2021}{Licence d'informatique}{Mention informatique}{Sorbonne Université}{Architecture des ordinateurs, Systèmes exploitation, Programmation avancée en C, etc.}{blank.png} \\
|
||||
\cvevent{2016}{Baccalauréat Général}{Série S}{Lycée Paul Valéry (Paris 12e)}{Mention bien.}{blank.png}
|
||||
\end{tabular}
|
||||
|
|
|
@ -1,177 +0,0 @@
|
|||
\documentclass[grey]{hipstercv}
|
||||
% available options are: darkhipster, lighthipster, pastel, allblack, grey, verylight
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[default]{raleway}
|
||||
\usepackage[margin=1cm, a4paper]{geometry}
|
||||
|
||||
|
||||
%------------------------------------------------------------------ Variablen
|
||||
|
||||
\newlength{\rightcolwidth}
|
||||
\newlength{\leftcolwidth}
|
||||
\setlength{\leftcolwidth}{0.3\textwidth}
|
||||
\setlength{\rightcolwidth}{0.65\textwidth}
|
||||
|
||||
%------------------------------------------------------------------
|
||||
\title{Hipster-CV}
|
||||
\author{\LaTeX{} Ninja}
|
||||
\date{October 2023}
|
||||
|
||||
\pagestyle{empty}
|
||||
\begin{document}
|
||||
|
||||
|
||||
\thispagestyle{empty}
|
||||
%-------------------------------------------------------------
|
||||
|
||||
\section*{Start}
|
||||
|
||||
|
||||
|
||||
\header{\bg{headerfontbox}{headerfontboxfont}{ } }{\bgupper{headerfontbox}{headerfontboxfont}{\bfseries\Huge INTITULÉ DE POSTE}}{\bg{headerfontbox}{headerfontboxfont}{ }}{photo.jpg}{headerblue}{3.5cm}{2cm}
|
||||
|
||||
|
||||
|
||||
%------------------------------------------------
|
||||
|
||||
% hier muss die "unsichtbare" Überschrift rein, weil er sonst nicht die Paracols startet... komisch...
|
||||
\subsection*{}
|
||||
\vspace{4em}
|
||||
|
||||
|
||||
\setlength{\columnsep}{1.5cm}
|
||||
\columnratio{0.3}[0.65]
|
||||
\begin{paracol}{2}
|
||||
\hbadness5000
|
||||
%\backgroundcolor{c[1]}[rgb]{1,1,0.8} % cream yellow for column-1 %\backgroundcolor{g}[rgb]{0.8,1,1} % \backgroundcolor{l}[rgb]{0,0,0.7} % dark blue for left margin
|
||||
|
||||
\paracolbackgroundoptions
|
||||
|
||||
% 0.9,0.9,0.9 -- 0.8,0.8,0.8
|
||||
|
||||
|
||||
\footnotesize{
|
||||
\setasidefontcolour
|
||||
\bgupper{cvgreen}{white}{Facts} \\
|
||||
\bg{cvgreen}{white}{\Large Adrien BOURMAULT} \\
|
||||
|
||||
\begin{tabular}{ll}
|
||||
\faAt&\url{adrien.bourmault@etu.upmc.fr}\\
|
||||
\faPhone&06.73.81.53.67 \\
|
||||
\faMapMarker&5 rue Boissonade \\
|
||||
&77340 Pontault-Combault \\
|
||||
\faBirthdayCake&06/01/1998 \\
|
||||
\end{tabular}
|
||||
|
||||
\bigskip
|
||||
|
||||
\bg{cvgreen}{white}{\large Compétences} \\
|
||||
|
||||
\bg{cvgreen}{white}{Langues}
|
||||
\begin{tabular}{l | ll}
|
||||
\textbf{Anglais} & C2 & {\footnotesize courant} \\
|
||||
\textbf{Allemand} & B2 & {\footnotesize scolaire}
|
||||
\end{tabular}
|
||||
|
||||
\bigskip
|
||||
|
||||
\bg{cvgreen}{white}{Informatique} \\
|
||||
|
||||
\begin{minipage}[t]{0.3\textwidth}
|
||||
\begin{tabular}{r @{\hspace{0.5em}}l}
|
||||
\bg{skilllabelcolour}{iconcolour}{C}&\barrule{0.5}{0.5em}{cvpurple}\\
|
||||
\bg{skilllabelcolour}{iconcolour}{Assembleurs}&\barrule{0.4}{0.5em}{cvpurple}\\
|
||||
\bg{skilllabelcolour}{iconcolour}{Python 3.x}&\barrule{0.45}{0.5em}{cvpurple}\\
|
||||
\bg{skilllabelcolour}{iconcolour}{Rust}&\barrule{0.1}{0.5em}{cvpurple}\\
|
||||
\bg{skilllabelcolour}{iconcolour}{Bash}&\barrule{0.3}{0.5em}{cvpurple}\\
|
||||
\bg{skilllabelcolour}{iconcolour}{\LaTeX}&\barrule{0.3}{0.5em}{cvpurple}\\
|
||||
\end{tabular}
|
||||
\end{minipage}
|
||||
|
||||
|
||||
\bigskip
|
||||
\bigskip
|
||||
\bigskip
|
||||
}
|
||||
%-----------------------------------------------------------
|
||||
\switchcolumn
|
||||
|
||||
\small
|
||||
\section*{Short Resumé}
|
||||
|
||||
\begin{tabular}{r| p{0.4\textwidth} c}
|
||||
\cvevent{2018--2021}{Captain of the Black Pearl}{Lead}{East Indies \color{cvred}}{Finally got the goddamn ship back.}{disney.png} \\
|
||||
\cvevent{2019}{Freelance Pirate}{Bucaneering}{Tortuga \color{cvred}}{This and that. The usual, aye?}{medal.jpeg} \\
|
||||
\cvevent{2016--2017}{Captain of the Black Pearl}{Lead}{Tortuga \color{cvred}}{Found a secret treasure, lost the ship.}{medal.jpeg}
|
||||
\end{tabular}
|
||||
|
||||
\vspace{4em}
|
||||
|
||||
\begin{minipage}[t]{0.4\textwidth}
|
||||
\section*{Degrees}
|
||||
\begin{tabular}{r p{0.6\textwidth} c}
|
||||
\cvdegree{1710}{Captain}{Certified}{Tortuga Uni \color{headerblue}}{}{disney.png} \\
|
||||
\cvdegree{1715}{Bucaneering}{M.A.}{London \color{headerblue}}{}{medal.jpeg} \\
|
||||
\cvdegree{1720}{Bucaneering}{B.A.}{London \color{headerblue}}{}{medal.jpeg}
|
||||
\end{tabular}
|
||||
\end{minipage}\hfill
|
||||
\begin{minipage}[t]{0.16\textwidth}
|
||||
\section*{Hobbies}
|
||||
% usage \hobbyicon{<fontawesome icon}{Text}{background color of circle}{size of icon}{space text below icon}
|
||||
\hobbyicon{\color{iconcolour}\faFlask}{Rhum}{cvgreen}{\iconsize}{2em} \hfill
|
||||
\hobbyicon{\color{iconcolour}\faBook}{The Code}{cvorange}{\iconsize}{2em}
|
||||
|
||||
\hobbyicon{\color{iconcolour}\faComment}{Parler}{cvpurple}{\iconsize}{2em} \hspace{1em}
|
||||
\hobbyicon{\color{iconcolour}\faBeer}{Beer}{headerblue}{\iconsize}{2em}
|
||||
\end{minipage}
|
||||
|
||||
\vspace{4em}
|
||||
|
||||
\begin{minipage}[t]{0.3\textwidth}
|
||||
\section*{Certificates \& Grants}
|
||||
\begin{tabular}{>{\footnotesize\bfseries}r >{\footnotesize}p{0.55\textwidth}}
|
||||
1708 & Captain's Certificates \\
|
||||
1710 & Travel grant \\
|
||||
1715--1716 & Grant from the Pirate's Company
|
||||
\end{tabular}
|
||||
\section*{Strenghts}
|
||||
\cvtag{honest}
|
||||
\cvtag{thieving}
|
||||
\cvtag{handsome}
|
||||
\section*{References}
|
||||
\cvkeyword{Will Turner}{cvgreen}{iconcolour}
|
||||
\cvkeyword{Barbossa}{cvgreen}{iconcolour} \\
|
||||
|
||||
\cvkeyword{possibly Mr. Swan}{headerblue}{iconcolour}
|
||||
\end{minipage}\hfill
|
||||
\begin{minipage}[t]{0.3\textwidth}
|
||||
\section*{Publications}
|
||||
\begin{tabular}{>{\footnotesize\bfseries}r >{\footnotesize}p{0.7\textwidth}}
|
||||
1729 & \emph{How I almost got killed by Lady Swan}, Tortuga Printing Press. \\
|
||||
1720 & ``Privateering for Beginners'', in: \emph{The Pragmatic Pirate} (1/1720).
|
||||
\end{tabular}
|
||||
\section*{Talks}
|
||||
\begin{tabular}{>{\footnotesize\bfseries}r >{\footnotesize}p{0.6\textwidth}}
|
||||
Nov. 1726 & ``How I lost my ship (\& and how to get it back)'', at: \emph{Annual Pirate's Conference} in Tortuga, Nov. 1726.
|
||||
\end{tabular}
|
||||
\end{minipage}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\vfill{} % Whitespace before final footer
|
||||
|
||||
%----------------------------------------------------------------------------------------
|
||||
% FINAL FOOTER
|
||||
%----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
\end{paracol}
|
||||
|
||||
\end{document}
|
Binary file not shown.
After Width: | Height: | Size: 790 KiB |
|
@ -1 +0,0 @@
|
|||
Subproject commit e5812b0746f04ffd9584c9574b08574e3abff317
|
|
@ -1,90 +0,0 @@
|
|||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/BI
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/B
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome/I
|
||||
mktextfm FontAwesome
|
||||
mktextfm FontAwesome
|
Loading…
Reference in New Issue