vgadbg.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include <kernel/system.h>
  2. #include <kernel/printf.h>
  3. #include <kernel/module.h>
  4. #include <kernel/ata.h>
  5. static unsigned short * textmemptr = (unsigned short *)0xB8000;
  6. static void placech(unsigned char c, int x, int y, int attr) {
  7. unsigned short *where;
  8. unsigned att = attr << 8;
  9. where = textmemptr + (y * 80 + x);
  10. *where = c | att;
  11. }
  12. static char vga_to_ansi[] = {
  13. 0, 4, 2, 6, 1, 5, 3, 7,
  14. 8,12,10,14, 9,13,11,15
  15. };
  16. static int fg = 0x07;
  17. static int bg = 0x10;
  18. static int cur_x = 0;
  19. static int cur_y = 0;
  20. static int write_string(char * s) {
  21. int written = 0;
  22. while (*s) {
  23. switch (*s) {
  24. case '\n':
  25. cur_x = 0;
  26. cur_y++;
  27. break;
  28. case '\b':
  29. if (cur_x > 0) cur_x--;
  30. placech(' ', cur_x, cur_y, (vga_to_ansi[fg] & 0xF) | (vga_to_ansi[bg] << 4));
  31. break;
  32. default:
  33. placech(*s, cur_x, cur_y, (vga_to_ansi[fg] & 0xF) | (vga_to_ansi[bg] << 4));
  34. cur_x++;
  35. break;
  36. }
  37. if (cur_x == 80) {
  38. cur_x = 0;
  39. cur_y++;
  40. }
  41. if (cur_y == 25) {
  42. memmove(textmemptr, (textmemptr + 80), sizeof(unsigned short) * 80 * 24);
  43. memset(textmemptr + 80 * 24, 0x00, 80 * sizeof(unsigned short));
  44. cur_y = 24;
  45. }
  46. s++;
  47. written++;
  48. }
  49. return written;
  50. }
  51. static void reset(void) {
  52. fg = 0x07;
  53. bg = 0x10;
  54. }
  55. static void list_files(char * directory) {
  56. fs_node_t * wd = kopen(directory, 0);
  57. uint32_t index = 0;
  58. struct dirent * kentry = readdir_fs(wd, index);
  59. while (kentry) {
  60. write_string(kentry->name);
  61. write_string("\n");
  62. free(kentry);
  63. index++;
  64. kentry = readdir_fs(wd, index);
  65. }
  66. close_fs(wd);
  67. }
  68. static void debug_ata_wait(void) {
  69. inportb(0x1F0 + ATA_REG_ALTSTATUS);
  70. inportb(0x1F0 + ATA_REG_ALTSTATUS);
  71. inportb(0x1F0 + ATA_REG_ALTSTATUS);
  72. inportb(0x1F0 + ATA_REG_ALTSTATUS);
  73. }
  74. static void debug_ata_primary(void) {
  75. /* Reset */
  76. char tmp[100];
  77. outportb(0x3F6, 0x04);
  78. debug_ata_wait();
  79. outportb(0x3F6, 0x00);
  80. debug_ata_wait();
  81. outportb(0x1F0 + ATA_REG_HDDEVSEL, 0xA0);
  82. debug_ata_wait();
  83. /* Wait on device */
  84. int status;
  85. int i = 0;
  86. while ((status = inportb(0x1F0 + ATA_REG_STATUS)) & ATA_SR_BSY) i++;
  87. sprintf(tmp, "Waited on status %d times\n", i);
  88. write_string(tmp);
  89. unsigned char cl = inportb(0x1F0 + ATA_REG_LBA1); /* CYL_LO */
  90. unsigned char ch = inportb(0x1F0 + ATA_REG_LBA2); /* CYL_HI */
  91. if (cl == 0xD0) {
  92. write_string("Waiting some more...\n");
  93. inportb(0x1F0 + ATA_REG_ALTSTATUS);
  94. inportb(0x1F0 + ATA_REG_ALTSTATUS);
  95. cl = inportb(0x1F0 + ATA_REG_LBA1); /* CYL_LO */
  96. ch = inportb(0x1F0 + ATA_REG_LBA2); /* CYL_HI */
  97. }
  98. sprintf(tmp, "ATA Primary 0x%2x 0x%2x\n", cl, ch);
  99. write_string(tmp);
  100. /* Now check partitions */
  101. mbr_t mbr;
  102. fs_node_t * f = kopen("/dev/hda", 0);
  103. if (!f) {
  104. write_string("Couldn't open /dev/hda\n");
  105. } else {
  106. read_fs(f, 0, 512, (uint8_t *)&mbr);
  107. sprintf(tmp, "signature[0] = 0x%2x\n", mbr.signature[0]);
  108. write_string(tmp);
  109. sprintf(tmp, "signature[1] = 0x%2x\n", mbr.signature[1]);
  110. write_string(tmp);
  111. write_string("Partitions:\n");
  112. for (int i = 0; i < 4; ++i) {
  113. if (mbr.partitions[i].status & 0x80) {
  114. sprintf(tmp, "Partition #%d: @%d+%d\n", i+1, mbr.partitions[i].lba_first_sector, mbr.partitions[i].sector_count);
  115. write_string(tmp);
  116. } else {
  117. sprintf(tmp, "Partition #%d: inactive\n", i+1);
  118. write_string(tmp);
  119. }
  120. }
  121. }
  122. }
  123. static void tasklet(void * data, char * name) {
  124. write_string("Tasklet created, sleeping... _");
  125. for (int i = 5; i > 0; i--) {
  126. char tmp[3];
  127. sprintf(tmp, "\b%d", i);
  128. write_string(tmp);
  129. unsigned long s, ss;
  130. relative_time(1, 0, &s, &ss);
  131. sleep_until((process_t *)current_process, s, ss);
  132. switch_task(0);
  133. }
  134. write_string("\bDone.\nReady to go.\n");
  135. write_string("Here's /dev:\n");
  136. fg = 6;
  137. list_files("/dev");
  138. reset();
  139. write_string("Now let's debug the primary PATA drive:\n");
  140. debug_ata_primary();
  141. reset();
  142. write_string("Here's /\n");
  143. fg = 6;
  144. list_files("/");
  145. reset();
  146. write_string("Here's /home");
  147. fg = 6;
  148. list_files("/home");
  149. reset();
  150. }
  151. static int vgadbg_init(void) {
  152. memset(textmemptr, 0x00, sizeof(unsigned short) * 80 * 25);
  153. write_string("VGA Text-Mode Debugger\n");
  154. write_string(" If you're seeing this, module loading completed successfully.\n");
  155. write_string(" We'll now do some checks to see what may be wrong with the system.\n");
  156. write_string("\n");
  157. create_kernel_tasklet(tasklet, "[[vgadbg]]", NULL);
  158. return 0;
  159. }
  160. static int vgadbg_fini(void) {
  161. return 0;
  162. }
  163. MODULE_DEF(vgadbg, vgadbg_init, vgadbg_fini);