PageRenderTime 67ms CodeModel.GetById 38ms RepoModel.GetById 1ms app.codeStats 0ms

/mona/core/kernel/kernel.cpp

https://github.com/ShotaroTsuji/mona
C++ | 457 lines | 290 code | 60 blank | 107 comment | 47 complexity | 6ade0f0c4d4755a586be006acaf7d576 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*!
  2. COPYRIGHT AND PERMISSION NOTICE
  3. Copyright (c) 2002-2010 Higepon
  4. Copyright (c) 2002-2003 Guripon
  5. Copyright (c) 2003 .mjt
  6. Copyright (c) 2004 Gaku
  7. All rights reserved.
  8. Permission is hereby granted, free of charge, to any person obtaining a copy
  9. of this software and associated documentation files (the "Software"), to
  10. deal in the Software without restriction, including without limitation the
  11. rights to use, copy, modify, merge, publish, distribute, and/or sell copies
  12. of the Software, and to permit persons to whom the Software is furnished to
  13. do so, provided that the above copyright notice(s) and this permission
  14. notice appear in all copies of the Software and that both the above
  15. copyright notice(s) and this permission notice appear in supporting
  16. documentation.
  17. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
  20. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
  21. LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR
  22. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  23. IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  24. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  25. Except as contained in this notice, the name of a copyright holder shall not
  26. be used in advertising or otherwise to promote the sale, use or other
  27. dealings in this Software without prior written authorization of the
  28. copyright holder.
  29. */
  30. /*!
  31. \file kernel.cpp
  32. \brief mona kernel start at this point
  33. mona kernel start at this point.
  34. before startKernel, os entered protected mode.
  35. Copyright (c) 2002-2007 Higepon and the individuals listed on the ChangeLog entries.
  36. All rights reserved.
  37. License=MIT/X License
  38. \author Higepon
  39. \version $Revision$
  40. \date create:2002/07/21 update:$Date$
  41. */
  42. #define GLOBAL_VALUE_DEFINED
  43. #include <sys/types.h>
  44. #include "global.h"
  45. #include "kernel.h"
  46. #include "operator.h"
  47. #include "checker.h"
  48. #include "GraphicalConsole.h"
  49. #include "ihandlers.h"
  50. #include "pic.h"
  51. #include <sys/Bitmap.h>
  52. #include "string.h"
  53. #include "syscalls.h"
  54. #include "PageManager.h"
  55. #include "MemoryManager.h"
  56. #include "vbe.h"
  57. #include "VesaConsole.h"
  58. #include "LogConsole.h"
  59. #include "Loader.h"
  60. #include "Scheduler.h"
  61. #include "monaboot.h"
  62. #include "RTC.h"
  63. #include "apm.h"
  64. #include "addressmap.h"
  65. #include "Uart.h"
  66. #include "KObjectService.h"
  67. #ifdef __GNUC__
  68. #define CC_NAME "gcc-%d.%d.%d"
  69. #define CC_VER __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__
  70. #endif
  71. const char* version = "Mona version.0.3.3";
  72. uint32_t version_number = 0x00000330;
  73. void mainProcess();
  74. typedef void (FuncVoid)();
  75. extern "C" FuncVoid* __CTOR_LIST__[];
  76. void invokeFuncList(FuncVoid** list, const char* file, int line)
  77. {
  78. int count = (int)*list++;
  79. list = (FuncVoid**)((((uint32_t)list) + 3) & ~3);
  80. if (count == -1)
  81. {
  82. for (; *list != NULL; list++) (**list)();
  83. }
  84. else
  85. {
  86. for (int i = 0; i < count; i++, list++)
  87. {
  88. (**list)();
  89. }
  90. }
  91. }
  92. static int fileptr = KERNEL_BASE_ADDR + REL_KERNEL_ADDR, sizeptr = 0x00001100;
  93. /*!
  94. \brief mona kernel start at this point
  95. cstart call this function.
  96. actually, kernel starts at this point
  97. \author Higepon
  98. \date create:2002/07/21 update:$Date$
  99. */
  100. void startKernel()
  101. {
  102. /* kernel memory range */
  103. km = FirstFitAllocator(0x200000, 0xBfffff);
  104. /* APM */
  105. g_apmInfo = new APMInfo;
  106. memcpy(g_apmInfo, (APMInfo*)0x900, sizeof(APMInfo));
  107. /* set segment */
  108. GDTUtil::setup();
  109. /* VESA */
  110. g_vesaInfo = new VesaInfo;
  111. memcpy(g_vesaInfo, (VesaInfo*)0x800, sizeof(VesaInfo));
  112. /* console */
  113. if (g_vesaInfo->sign[0] == 'N')
  114. {
  115. g_console = new GraphicalConsole();
  116. g_console->printf("VESA not supported. sorry kernel stop.\n");
  117. for (;;);
  118. }
  119. else
  120. {
  121. g_vesaDetail = new VesaInfoDetail;
  122. memcpy(g_vesaDetail, (VesaInfoDetail*)0x830, sizeof(VesaInfoDetail));
  123. g_console = new VesaConsole(g_vesaDetail);
  124. g_console->setCHColor(GP_LIGHTGREEN);
  125. g_console->setBGColor(GP_WHITE);
  126. g_console->clearScreen();
  127. }
  128. g_console->printf("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\n");
  129. g_console->printf("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\n");
  130. g_console->printf("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff %s\n", version);
  131. g_console->printf("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff ["CC_NAME" @ %s]\n", CC_VER, OSTYPE);
  132. g_console->printf("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff Copyright (c) 2002-2010 higepon\n");
  133. g_console->printf("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\n");
  134. g_console->printf("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\n");
  135. #if 1
  136. int w = g_vesaDetail->xResolution;
  137. int bpp = g_vesaDetail->bitsPerPixel / 8;
  138. uint8_t *vram = (uint8_t*)g_vesaDetail->physBasePtr;
  139. switch (bpp) {
  140. case 2:
  141. for (int y = 0; y < 105; y++) {
  142. for (int x = 0; x < 55; x++) {
  143. uint8_t *pixel = NULL;
  144. uint16_t rgb16 = 0;
  145. // hi 4bit
  146. pixel = &vram[(x * 2 + y * w) * bpp];
  147. rgb16 = (uint16_t)(((palette16[(monaboot[y][x] >> 4) & 0xF] >> 8) & 0xF800) |
  148. ((palette16[(monaboot[y][x] >> 4) & 0xF] >> 5) & 0x07E0) |
  149. ((palette16[(monaboot[y][x] >> 4) & 0xF] >> 3) & 0x001F));
  150. *((uint16_t*)pixel) = rgb16;
  151. // low 4bit
  152. pixel = &vram[(x * 2 + 1 + y * w) * bpp];
  153. rgb16 = (uint16_t)(((palette16[monaboot[y][x] & 0xF] >> 8) & 0xF800) |
  154. ((palette16[monaboot[y][x] & 0xF] >> 5) & 0x07E0) |
  155. ((palette16[monaboot[y][x] & 0xF] >> 3) & 0x001F));
  156. *((uint16_t*)pixel) = rgb16;
  157. }
  158. }
  159. break;
  160. default:
  161. for (int y = 0; y < 105; y++) {
  162. for (int x = 0; x < 55; x++) {
  163. uint8_t *pixel = NULL;
  164. uint8_t *p_color = NULL;
  165. // hi 4bit
  166. pixel = &vram[(x * 2 + y * w) * bpp];
  167. p_color = (uint8_t*)&palette16[(monaboot[y][x] >> 4) & 0xF];
  168. pixel[0] = p_color[0];
  169. pixel[1] = p_color[1];
  170. pixel[2] = p_color[2];
  171. // low 4bit
  172. pixel = &vram[(x * 2 + 1 + y * w) * bpp];
  173. p_color = (uint8_t*)&palette16[monaboot[y][x] & 0xF];
  174. pixel[0] = p_color[0];
  175. pixel[1] = p_color[1];
  176. pixel[2] = p_color[2];
  177. }
  178. }
  179. break;
  180. }
  181. #endif
  182. // use COM1 serial port
  183. g_log = new LogConsole();
  184. // use COM2 serial port
  185. g_com2 = new Uart(Uart::COM2);
  186. // g_console->printf("read from COM2<%c>:", g_com2->readChar());
  187. pic_init();
  188. RTC::init();
  189. printOK("Setting PIC ");
  190. IDTUtil::setup();
  191. printOK("Setting IDT ");
  192. printOK("Setting GDT ");
  193. checkTypeSize();
  194. printOK("Checking type size ");
  195. /* get total system memory */
  196. g_total_system_memory = MemoryManager::getPhysicalMemorySize();
  197. g_console->printf("\nSystem Total Memory %d[MB]. VRAM=%x Paging on \n", g_total_system_memory / 1024 / 1024, g_vesaDetail->physBasePtr);
  198. g_console->printf("VESA: %dx%d %dbpp\n", g_vesaDetail->xResolution, g_vesaDetail->yResolution, g_vesaDetail->bitsPerPixel);
  199. if( !g_apmInfo->isSupported )
  200. {
  201. g_console->printf("Warning: APM is not supported.\n");
  202. }
  203. else
  204. {
  205. apm_init();
  206. }
  207. // dumpAddressMap();
  208. /* IDManager */
  209. g_id = new IDManager();
  210. /* This mutex has no owner, so will never deleted */
  211. g_mutexShared = KObjectService::createNullOwner<KMutex>();
  212. /* Paging start */
  213. PhysicalAddress vramAddress = g_vesaDetail->physBasePtr;
  214. int vramSizeBytes = (g_vesaDetail->xResolution * g_vesaDetail->yResolution * g_vesaDetail->bitsPerPixel / 8);
  215. g_page_manager = new PageManager(g_total_system_memory, vramAddress, vramSizeBytes);
  216. g_page_directory = g_page_manager->createPageDirectory();
  217. g_page_manager->startPaging((PhysicalAddress)g_page_directory);
  218. // Just after the paging is on, we call static initializer.
  219. invokeFuncList(__CTOR_LIST__, __FILE__, __LINE__);
  220. /* dummy thread struct */
  221. Thread* dummy1 = new Thread();
  222. Thread* dummy2 = new Thread();
  223. g_prevThread = dummy1->tinfo;
  224. g_currentThread = dummy2->tinfo;
  225. /* this should be called, before timer enabled */
  226. ProcessOperation::initialize(g_page_manager);
  227. g_scheduler = new Scheduler();
  228. /* messenger */
  229. g_messenger = new Messenger(g_scheduler);
  230. /* at first create idle process */
  231. Process* idleProcess = ProcessOperation::create(ProcessOperation::KERNEL_PROCESS, "IDLE");
  232. g_idleThread = ThreadOperation::create(idleProcess, (uint32_t)monaIdle);
  233. g_scheduler->Join(g_idleThread, ThreadPriority::Min);
  234. /* start up Process */
  235. Process* initProcess = ProcessOperation::create(ProcessOperation::KERNEL_PROCESS, "INIT");
  236. Thread* initThread = ThreadOperation::create(initProcess, (uint32_t)mainProcess);
  237. g_scheduler->Join(initThread);
  238. disableTimer();
  239. disableKeyboard();
  240. enableInterrupt();
  241. /* dummy thread struct */
  242. g_prevThread = dummy1->tinfo;
  243. g_currentThread = dummy2->tinfo;
  244. g_prevThread->archinfo->cr3 = 1;
  245. g_currentThread->archinfo->cr3 = 2;
  246. // Just before enable timer, sync epochNanosec.
  247. RTC::syncEpochNanosec();
  248. /*
  249. g_console->printf("inb8:%x\n", inp8(0x21));
  250. g_console->printf("%s:%d\n", __FILE__, __LINE__);
  251. */
  252. enableTimer();
  253. #ifdef HIGE
  254. #endif
  255. for (;;);
  256. }
  257. /*!
  258. \brief mona kernel panic
  259. kernel panic
  260. \author Higepon
  261. \date create:2002/12/02 update:2003/03/01
  262. */
  263. void panic(const char* msg)
  264. {
  265. g_console->setCHColor(GP_RED);
  266. g_console->printf("kernel panic\nMessage:%s\n", msg);
  267. for (;;);
  268. }
  269. void checkMemoryAllocate(void* p, const char* msg)
  270. {
  271. if (p != NULL) return;
  272. panic(msg);
  273. }
  274. /*!
  275. \brief print OK
  276. print "msg [OK]"
  277. \param msg message
  278. \author Higepon
  279. \date create:2003/01/26 update:2003/01/25
  280. */
  281. inline void printOK(const char* msg)
  282. {
  283. static int i = 0;
  284. if (i % 2) g_console->printf(" ");
  285. g_console->printf((char*)msg);
  286. g_console->printf("[");
  287. g_console->setCHColor(GP_LIGHTBLUE);
  288. g_console->printf("OK");
  289. g_console->setCHColor(GP_LIGHTGREEN);
  290. g_console->printf("]");
  291. if (i % 2) g_console->printf("\n");
  292. i++;
  293. }
  294. void loadServer(const char* server, const char* name)
  295. {
  296. g_console->printf("loading %s....", server);
  297. if (strstr(server, ".BIN"))
  298. {
  299. uint8_t* image = (uint8_t*)fileptr;
  300. uint32_t size = (*(int*)sizeptr) * 512;
  301. sizeptr += 4;
  302. fileptr += size;
  303. if (image == NULL)
  304. {
  305. g_console->printf("server %s not found\n", name);
  306. return;
  307. }
  308. g_console->printf("%s\n", Loader::Load(image, size, Loader::ORG, name, true, NULL) == M_OK ? "OK" : "NG");
  309. }
  310. else
  311. {
  312. g_console->printf("unknown server type!\n");
  313. }
  314. MessageInfo msg;
  315. for (;;)
  316. {
  317. if (g_messenger->receive(g_currentThread->thread, &msg)) continue;
  318. if (msg.header == MSG_STARTED) break;
  319. }
  320. return;
  321. }
  322. int execSysConf()
  323. {
  324. uint8_t* buf = (uint8_t*)MONA_CFG_ADDR;
  325. int fileSize = (*(int*)sizeptr) * 512;
  326. sizeptr += 4;
  327. fileptr += (*(int*)sizeptr) * 512;
  328. sizeptr += 4;
  329. /* execute */
  330. char line[256];
  331. int linepos = 0;
  332. for (int pos = 0; pos <= fileSize; pos++) {
  333. char ch = pos < fileSize ? (char)buf[pos] : '\n';
  334. if (ch == '\r' || ch == '\n') {
  335. if (linepos > 0) {
  336. line[linepos] = '\0';
  337. if (strstr(line, "SERVER=") == line) {
  338. const char* server = &line[7];
  339. const char* name = &line[linepos - 1];
  340. for (;; name--) {
  341. if (*name == '/') {
  342. name++;
  343. break;
  344. }
  345. if (name == server) break;
  346. }
  347. enableTimer(); // qemu need this why?
  348. loadServer(server, name);
  349. }
  350. linepos = 0;
  351. }
  352. } else if (linepos < 255) {
  353. line[linepos++] = ch;
  354. }
  355. }
  356. return 0;
  357. }
  358. inline intptr_t syscall0(intptr_t syscall_number)
  359. {
  360. intptr_t ret = 0;
  361. asm volatile("movl $%c1, %%ebx \n"
  362. "int $0x80 \n"
  363. "movl %%eax, %0 \n"
  364. :"=m"(ret)
  365. :"g"(syscall_number)
  366. :"ebx"
  367. );
  368. return ret;
  369. }
  370. void mainProcess()
  371. {
  372. if (execSysConf() != 0)
  373. {
  374. g_console->printf("/MONA.CFG does not exist\n");
  375. for (;;);
  376. }
  377. // enableKeyboard();
  378. #ifdef HIGE
  379. #endif
  380. /* end */
  381. syscall0(SYSTEM_CALL_KILL);
  382. for (;;);
  383. }