You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

125 lines
3.0 KiB

  1. /*
  2. * libcaca
  3. * libcaca Colour ASCII-Art library
  4. * Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
  5. * 2009 Jean-Yves Lamoureux <jylam@lnxscene.org>
  6. * All Rights Reserved
  7. *
  8. * $Id: kernel.h 4154 2009-12-20 13:33:11Z jylam $
  9. *
  10. * This library is free software. It comes without any warranty, to
  11. * the extent permitted by applicable law. You can redistribute it
  12. * and/or modify it under the terms of the Do What The Fuck You Want
  13. * To Public License, Version 2, as published by Sam Hocevar. See
  14. * http://sam.zoy.org/wtfpl/COPYING for more details.
  15. */
  16. /*
  17. *'freely' inspired by http://jojo.ouvaton.org/dossiers/boot_sector/tutorial02.html
  18. * (actually, that's mostly copied, with minor compilation fixes)
  19. */
  20. #include "kernel.h"
  21. #include "klibc.h"
  22. #define GDTBASE 0x800 /* Physical address of GDT */
  23. #define GDTSIZE 0xFF /* Maximum table size (in entries) */
  24. /* Segment descriptor */
  25. struct gdtdesc
  26. {
  27. u16 lim0_15;
  28. u16 base0_15;
  29. u8 base16_23;
  30. u8 acces;
  31. u8 lim16_19:4;
  32. u8 other:4;
  33. u8 base24_31;
  34. } __attribute__ ((packed));
  35. /* GDTR register */
  36. struct gdtr
  37. {
  38. u16 limite;
  39. u32 base;
  40. } __attribute__ ((packed));
  41. struct gdtr kgdtr;
  42. struct gdtdesc kgdt[GDTSIZE] = { {0, 0, 0, 0, 0, 0, 0} };
  43. unsigned int kgdtptr = 1;
  44. void init_code_desc(u32 base, u32 limite, struct gdtdesc *desc);
  45. void init_data_desc(u32 base, u32 limite, struct gdtdesc *desc);
  46. void add_gdt_desc(struct gdtdesc desc);
  47. void init_gdt(void);
  48. void init_gdt_desc(u32 base, u32 limite, u8 acces, u8 other,
  49. struct gdtdesc *desc)
  50. {
  51. desc->lim0_15 = (limite & 0xffff);
  52. desc->base0_15 = (base & 0xffff);
  53. desc->base16_23 = (base & 0xff0000) >> 16;
  54. desc->acces = acces;
  55. desc->lim16_19 = (limite & 0xf0000) >> 16;
  56. desc->other = (other & 0xf);
  57. desc->base24_31 = (base & 0xff000000) >> 24;
  58. return;
  59. }
  60. void init_code_desc(u32 base, u32 limite, struct gdtdesc *desc)
  61. {
  62. init_gdt_desc(base, limite, 0x9B, 0x0D, desc);
  63. }
  64. void init_data_desc(u32 base, u32 limite, struct gdtdesc *desc)
  65. {
  66. init_gdt_desc(base, limite, 0x93, 0x0D, desc);
  67. }
  68. void add_gdt_desc(struct gdtdesc desc)
  69. {
  70. kgdt[kgdtptr] = desc;
  71. kgdtptr++;
  72. }
  73. void init_gdt(void)
  74. {
  75. struct gdtdesc code, data, stack;
  76. /* initialisation des descripteurs de segment */
  77. init_code_desc(0x0, 0xFFFFF, &code);
  78. init_data_desc(0x0, 0xFFFFF, &data);
  79. init_gdt_desc(0, 0x10, 0x97, 0x0D, &stack);
  80. add_gdt_desc(code);
  81. add_gdt_desc(data);
  82. add_gdt_desc(stack);
  83. /* initialisation de la structure pour GDTR */
  84. kgdtr.limite = GDTSIZE * 8;
  85. kgdtr.base = GDTBASE;
  86. /* recopie de la GDT a son adresse */
  87. memcpy((void *)kgdtr.base, kgdt, kgdtr.limite);
  88. /* chargement du registre GDTR */
  89. asm("lgdtl (kgdtr)");
  90. /* initialisation des segments */
  91. asm(" movw $0x10,%ax \n \
  92. movw %ax, %ds \n \
  93. movw %ax, %es \n \
  94. movw %ax, %fs \n \
  95. movw %ax, %gs \n \
  96. movw $0x18,%ax \n \
  97. movw %ax, %ss \n \
  98. movl $0x1FFFF,%esp \n \
  99. nop \n \
  100. nop \n \
  101. ljmp $0x08,$next \n \
  102. next: \n");
  103. }