File: gdt.c

package info (click to toggle)
libcaca 0.99.beta20-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,540 kB
  • sloc: ansic: 25,091; php: 2,763; python: 2,637; cs: 1,213; cpp: 1,127; java: 916; objc: 836; makefile: 545; perl: 505; sh: 472; asm: 297; ruby: 215; xml: 33
file content (121 lines) | stat: -rw-r--r-- 3,035 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
 *  libcaca       Colour ASCII-Art library
 *  Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
 *                2009 Jean-Yves Lamoureux <jylam@lnxscene.org>
 *                All Rights Reserved
 *
 *  This library is free software. It comes without any warranty, to
 *  the extent permitted by applicable law. You can redistribute it
 *  and/or modify it under the terms of the Do What the Fuck You Want
 *  to Public License, Version 2, as published by Sam Hocevar. See
 *  http://www.wtfpl.net/ for more details.
 */

/*
 *'freely' inspired by http://jojo.ouvaton.org/dossiers/boot_sector/tutorial02.html
 * (actually, that's mostly copied, with minor compilation fixes)
 */
#include "kernel.h"
#include "klibc.h"

#define GDTBASE	0x800           /* Physical address of GDT */
#define GDTSIZE	0xFF            /* Maximum table size (in entries) */

/* Segment descriptor */
struct gdtdesc
{
    u16 lim0_15;
    u16 base0_15;
    u8 base16_23;
    u8 acces;
    u8 lim16_19:4;
    u8 other:4;
    u8 base24_31;
} __attribute__ ((packed));

/* GDTR register */
struct gdtr
{
    u16 limite;
    u32 base;
} __attribute__ ((packed));
struct gdtr kgdtr;


struct gdtdesc kgdt[GDTSIZE] = { {0, 0, 0, 0, 0, 0, 0} };

unsigned int kgdtptr = 1;

void init_code_desc(u32 base, u32 limite, struct gdtdesc *desc);
void init_data_desc(u32 base, u32 limite, struct gdtdesc *desc);
void add_gdt_desc(struct gdtdesc desc);
void init_gdt(void);



void init_gdt_desc(u32 base, u32 limite, u8 acces, u8 other,
                   struct gdtdesc *desc)
{
    desc->lim0_15 = (limite & 0xffff);
    desc->base0_15 = (base & 0xffff);
    desc->base16_23 = (base & 0xff0000) >> 16;
    desc->acces = acces;
    desc->lim16_19 = (limite & 0xf0000) >> 16;
    desc->other = (other & 0xf);
    desc->base24_31 = (base & 0xff000000) >> 24;
    return;
}


void init_code_desc(u32 base, u32 limite, struct gdtdesc *desc)
{
    init_gdt_desc(base, limite, 0x9B, 0x0D, desc);
}

void init_data_desc(u32 base, u32 limite, struct gdtdesc *desc)
{
    init_gdt_desc(base, limite, 0x93, 0x0D, desc);
}

void add_gdt_desc(struct gdtdesc desc)
{
    kgdt[kgdtptr] = desc;
    kgdtptr++;
}

void init_gdt(void)
{
    struct gdtdesc code, data, stack;

    /* initialisation des descripteurs de segment */
    init_code_desc(0x0, 0xFFFFF, &code);
    init_data_desc(0x0, 0xFFFFF, &data);
    init_gdt_desc(0, 0x10, 0x97, 0x0D, &stack);
    add_gdt_desc(code);
    add_gdt_desc(data);
    add_gdt_desc(stack);

    /* initialisation de la structure pour GDTR */
    kgdtr.limite = GDTSIZE * 8;
    kgdtr.base = GDTBASE;

    /* recopie de la GDT a son adresse */
    memcpy((void *)kgdtr.base, kgdt, kgdtr.limite);

    /* chargement du registre GDTR */
    asm("lgdtl (kgdtr)");

    /* initialisation des segments */
    asm("	movw $0x10,%ax	\n \
		movw %ax, %ds	\n \
		movw %ax, %es	\n \
		movw %ax, %fs	\n \
		movw %ax, %gs	\n \
		movw $0x18,%ax	\n \
		movw %ax, %ss	\n \
		movl $0x1FFFF,%esp	\n \
		nop	\n \
		nop	\n \
		ljmp $0x08,$next	\n \
		next:	\n");
}