MAIN.C
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:15k
源码类别:

操作系统开发

开发平台:

DOS

  1. /****************************************************************/
  2. /*                                                              */
  3. /*                           main.c                             */
  4. /*                            DOS-C                             */
  5. /*                                                              */
  6. /*                    Main Kernel Functions                     */
  7. /*                                                              */
  8. /*                   Copyright (c) 1995, 1996                   */
  9. /*                      Pasquale J. Villani                     */
  10. /*                      All Rights Reserved                     */
  11. /*                                                              */
  12. /* This file is part of DOS-C.                                  */
  13. /*                                                              */
  14. /* DOS-C is free software; you can redistribute it and/or       */
  15. /* modify it under the terms of the GNU General Public License  */
  16. /* as published by the Free Software Foundation; either version */
  17. /* 2, or (at your option) any later version.                    */
  18. /*                                                              */
  19. /* DOS-C is distributed in the hope that it will be useful, but */
  20. /* WITHOUT ANY WARRANTY; without even the implied warranty of   */
  21. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    */
  22. /* the GNU General Public License for more details.             */
  23. /*                                                              */
  24. /* You should have received a copy of the GNU General Public    */
  25. /* License along with DOS-C; see the file COPYING.  If not,     */
  26. /* write to the Free Software Foundation, 675 Mass Ave,         */
  27. /* Cambridge, MA 02139, USA.                                    */
  28. /****************************************************************/
  29. #define MAIN
  30. #include "../../hdr/portab.h"
  31. #include "globals.h"
  32. /* $Logfile:   C:/dos-c/src/kernel/main.c_v  $ */
  33. #ifdef VERSION_STRINGS
  34. static BYTE *mainRcsId = "$Header:   C:/dos-c/src/kernel/main.c_v   1.11   22 Jan 1998  4:09:24   patv  $";
  35. #endif
  36. /* $Log:   C:/dos-c/src/kernel/main.c_v  $
  37.  * 
  38.  *    Rev 1.11   22 Jan 1998  4:09:24   patv
  39.  * Fixed pointer problems affecting SDA
  40.  * 
  41.  *    Rev 1.10   04 Jan 1998 23:15:20   patv
  42.  * Changed Log for strip utility
  43.  * 
  44.  *    Rev 1.9   04 Jan 1998 17:26:16   patv
  45.  * Corrected subdirectory bug
  46.  * 
  47.  *    Rev 1.8   03 Jan 1998  8:36:48   patv
  48.  * Converted data area to SDA format
  49.  * 
  50.  *    Rev 1.7   06 Feb 1997 21:35:46   patv
  51.  * Modified to support new version format and changed debug message to
  52.  * output drive letter instead of number.
  53.  * 
  54.  *    Rev 1.6   22 Jan 1997 13:05:02   patv
  55.  * Now does correct default drive initialization.
  56.  * 
  57.  *    Rev 1.5   16 Jan 1997 12:47:00   patv
  58.  * pre-Release 0.92 feature additions
  59.  * 
  60.  *    Rev 1.3   29 May 1996 21:03:32   patv
  61.  * bug fixes for v0.91a
  62.  * 
  63.  *    Rev 1.2   19 Feb 1996  3:21:36   patv
  64.  * Added NLS, int2f and config.sys processing
  65.  * 
  66.  *    Rev 1.1   01 Sep 1995 17:54:18   patv
  67.  * First GPL release.
  68.  * 
  69.  *    Rev 1.0   02 Jul 1995  8:33:18   patv
  70.  * Initial revision.
  71.  */
  72. /* $EndLog$ */
  73. static COUNT BlockIndex = 0;
  74. VOID    configDone(VOID);
  75. VOID init_kernel(VOID), signon(VOID), kernel(VOID);
  76. static COUNT p_0(VOID);
  77. VOID FsConfig(VOID);
  78. VOID 
  79. main (void)
  80. {
  81. #ifdef KDB
  82. BootDrive = 1;
  83. #endif
  84.         init_kernel();
  85. #ifdef DEBUG
  86. /* Non-portable message kludge alert! */
  87.         printf("KERNEL: Boot drive = %cn", 'A' + BootDrive - 1);
  88. #endif
  89.         signon();
  90.         kernel();
  91. }
  92. VOID 
  93. reinit_k (void)
  94. {
  95.         REG COUNT i;
  96.         UWORD FAR *stack = (UWORD FAR *)&error_tos;
  97.         /* Re-initialize drivers                        */
  98.         syscon = &con_dev;
  99.         /* Re-initialize stacks                         */
  100.         api_sp = FP_OFF(stack);
  101.         api_ss = FP_SEG(stack);
  102.         /* Test ram for sane mcb's                      */
  103.         if(DosMemCheck() != SUCCESS)
  104.                 panic("Memory corrupted");
  105. }
  106. static VOID 
  107. init_kernel (void)
  108. {
  109.         REG struct dhdr FAR *dhp = (struct dhdr FAR *)&nul_dev;
  110.         UWORD FAR *stack;
  111.         COUNT i;
  112.         
  113.         cu_psp = DOS_PSP;    
  114.         nblkdev = 0;
  115.         maxbksize = 0x200;
  116.         switchar = '/';
  117.         
  118.         /* initialize stack                                     */
  119.         stack = (UWORD FAR *)&error_tos;
  120.         /* Init oem hook - returns memory size in KB    */
  121.         ram_top = init_oem();
  122.         /* Initialize driver chain                                      */
  123.         dhp = link_dhdr(dhp, (struct dhdr FAR *)&con_dev, NULL);
  124.         dhp = link_dhdr(dhp, (struct dhdr FAR *)&clk_dev, NULL);
  125.         dhp = link_dhdr(dhp, (struct dhdr FAR *)&blk_dev, NULL);
  126.         syscon = (struct dhdr FAR *)&con_dev;
  127.         clock = (struct dhdr FAR *)&clk_dev;
  128. #ifndef KDB
  129. for (i = 0x20; i <= 0x3f; i++)
  130.      setvec(i, empty_handler);
  131. /* set interrupt vectors                                        */
  132. setvec(0x20, int20_handler);
  133. setvec(0x21, int21_handler);
  134. setvec(0x22, int22_handler);
  135. setvec(0x23, int23_handler);
  136. setvec(0x24, int24_handler);
  137. setvec(0x25, (VOID (INRPT FAR *)())low_int25_handler);
  138. setvec(0x26, (VOID (INRPT FAR *)())low_int26_handler);
  139. setvec(0x27, int27_handler);
  140. setvec(0x28, int28_handler);
  141. setvec(0x29, int29_handler);    /* Requires Fast Con Driver     */
  142. setvec(0x2f, int2f_handler);
  143. #endif
  144. /* Initialize stacks                                            */
  145.         api_sp = FP_OFF(stack);
  146.         api_ss = FP_SEG(stack);
  147.         /* Initialize the screen handler for backspaces                 */
  148.         scr_pos = 0;
  149.         break_ena = TRUE;
  150.         /* Do first initialization of system variable buffers so that   */
  151.         /* we can read config.sys later.                                */
  152. lastdrive = Config.cfgLastdrive;
  153. PreConfig();
  154. /* Now config the temporary file system                         */
  155. FsConfig();
  156. #ifndef KDB
  157. /* Now process CONFIG.SYS                                       */
  158. DoConfig();
  159. lastdrive = Config.cfgLastdrive;
  160. if (lastdrive < nblkdev)
  161. lastdrive = nblkdev;
  162.         /* and do final buffer allocation.                              */
  163.         PostConfig();
  164.         
  165.         /* Now config the final file system                             */
  166.         FsConfig();
  167.         /* and process CONFIG.SYS one last time to load device drivers. */
  168.         DoConfig();
  169. configDone();
  170. #endif
  171.         /* Now to initialize all special flags, etc.                    */
  172.         mem_access_mode = FIRST_FIT;
  173.         verify_ena = FALSE;
  174.         InDOS = 0;
  175.         version_flags = 0;
  176.         pDirFileNode = 0;
  177. }
  178. VOID FsConfig(VOID)
  179. {
  180.         REG COUNT i;
  181.         /* Initialize the file tables                                   */
  182.         for(i = 0; i < Config.cfgFiles; i++)
  183.                 f_nodes[i].f_count = 0;
  184.         /* The system file tables need special handling and are "hand   */
  185.         /* built. Included is the stdin, stdout, stdaux and atdprn.     */
  186.         sfthead -> sftt_next = (sfttbl FAR *)-1;
  187.         sfthead -> sftt_count = Config.cfgFiles;
  188.         for(i = 0; i < sfthead -> sftt_count ; i++)
  189.         {
  190.                 sfthead -> sftt_table[i].sft_count = 0;
  191.                 sfthead -> sftt_table[i].sft_status = -1;
  192.         }
  193.         /* 0 is /dev/con (stdin)                                        */
  194.         sfthead -> sftt_table[0].sft_count = 1;
  195.         sfthead -> sftt_table[0].sft_mode = SFT_MREAD;
  196.         sfthead -> sftt_table[0].sft_attrib = 0;
  197.         sfthead -> sftt_table[0].sft_flags =
  198.           (con_dev.dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF | SFT_FSTDIN | SFT_FSTDOUT;
  199.         sfthead -> sftt_table[0].sft_psp = DOS_PSP;
  200.         fbcopy(
  201.                 (VOID FAR *)"CON        ",
  202.                 (VOID FAR *)sfthead -> sftt_table[0].sft_name, 11);
  203.         sfthead -> sftt_table[0].sft_dev = (struct dhdr FAR *)&con_dev;
  204.         /* 1 is /dev/con (stdout)                                       */
  205.         sfthead -> sftt_table[1].sft_count = 1;
  206.         sfthead -> sftt_table[1].sft_mode = SFT_MWRITE;
  207.         sfthead -> sftt_table[1].sft_attrib = 0;
  208.         sfthead -> sftt_table[1].sft_flags = 
  209.           (con_dev.dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF | SFT_FSTDIN  | SFT_FSTDOUT;
  210.         sfthead -> sftt_table[1].sft_psp = DOS_PSP;
  211.         fbcopy(
  212.                 (VOID FAR *)"CON        ",
  213.                 (VOID FAR *)sfthead -> sftt_table[1].sft_name, 11);
  214.         sfthead -> sftt_table[1].sft_dev = (struct dhdr FAR *)&con_dev;
  215.         /* 2 is /dev/con (stderr)                                       */
  216.         sfthead -> sftt_table[2].sft_count = 1;
  217.         sfthead -> sftt_table[2].sft_mode = SFT_MWRITE;
  218.         sfthead -> sftt_table[2].sft_attrib = 0;
  219.         sfthead -> sftt_table[2].sft_flags = 
  220.           (con_dev.dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF | SFT_FSTDIN  | SFT_FSTDOUT;
  221.         sfthead -> sftt_table[2].sft_psp = DOS_PSP;
  222.         fbcopy(
  223.                 (VOID FAR *)"CON        ",
  224.                 (VOID FAR *)sfthead -> sftt_table[2].sft_name, 11);
  225.         sfthead -> sftt_table[2].sft_dev = (struct dhdr FAR *)&con_dev;
  226.         /* 3 is /dev/aux (/dev/null for now)                            */
  227.         sfthead -> sftt_table[3].sft_count = 1;
  228.         sfthead -> sftt_table[3].sft_mode = SFT_MWRITE;
  229.         sfthead -> sftt_table[3].sft_attrib = 0;
  230.         sfthead -> sftt_table[3].sft_flags = 
  231.           (nul_dev.dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FNUL;
  232.         sfthead -> sftt_table[3].sft_psp = DOS_PSP;
  233.         fbcopy(
  234.                 (VOID FAR *)"NUL        ",
  235.                 (VOID FAR *)sfthead -> sftt_table[3].sft_name, 11);
  236.         sfthead -> sftt_table[3].sft_dev = (struct dhdr FAR *)&nul_dev;
  237.         /* 4 is /dev/prn (/dev/null for now)                            */
  238.         sfthead -> sftt_table[4].sft_count = 1;
  239.         sfthead -> sftt_table[4].sft_mode = SFT_MWRITE;
  240.         sfthead -> sftt_table[4].sft_attrib = 0;
  241.         sfthead -> sftt_table[4].sft_flags =
  242.           (nul_dev.dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FNUL;
  243.         sfthead -> sftt_table[4].sft_psp = DOS_PSP;
  244.         fbcopy(
  245.                 (VOID FAR *)"NUL        ",
  246.                 (VOID FAR *)sfthead -> sftt_table[4].sft_name, 11);
  247.         sfthead -> sftt_table[4].sft_dev = (struct dhdr FAR *)&nul_dev;
  248.         /* Log-in the default drive.                                    */
  249.         /* Get the boot drive from the ipl and use it for default.      */
  250.         default_drive = BootDrive - 1;
  251.         /* Initialzie the current directory structures                  */
  252.         for(i = 0; i < NDEVS; i++)
  253.                 scopy("\", blk_devices[i].dpb_path);
  254.         /* Initialze the disk buffer management functions               */
  255.         init_buffers();
  256. }
  257. static VOID signon()
  258. {
  259.         printf("nDOS-C compatibility %d.%02dn%sn",
  260.                 os_major, os_minor, copyright);
  261.         printf(os_release,
  262.          REVISION_MAJOR, REVISION_MINOR, REVISION_SEQ,
  263.          BUILD);
  264. }
  265. static VOID kernel()
  266. {
  267.         seg asize;
  268.         BYTE FAR *ep, *sp;
  269.         COUNT ret_code;
  270. #ifndef KDB
  271.         static BYTE *path = "PATH=";
  272. #endif
  273. #ifdef KDB
  274.         kdb();
  275. #else
  276.         /* create the master environment area                           */
  277.         if(DosMemAlloc(0x20, FIRST_FIT, (seg FAR *)&master_env, (seg FAR *)&asize) < 0)
  278.                 fatal("cannot allocate master environment space");
  279.         /* populate it with the minimum environment                     */
  280.         ++master_env;       
  281.         ep = MK_FP(master_env, 0);   
  282.         
  283.         for(sp = path; *sp != 0; )
  284.                 *ep++ = *sp++;
  285.         *ep++ = '';
  286.         *ep++ = '';
  287.         *((int FAR *)ep) = 0;
  288.         ep += sizeof(int);    
  289. #endif
  290.         ret_code = p_0();
  291.         exit(ret_code);
  292. }
  293. /* process 0                                                            */
  294. static COUNT
  295. p_0(VOID)
  296. {
  297.         exec_blk exb;
  298.         CommandTail Cmd;
  299.         BYTE FAR *szfInitialPrgm = (BYTE FAR *)Config.cfgInit;
  300.         int     rc;
  301.         /* Execute command.com /P from the drive we just booted from    */
  302.         exb.exec.env_seg = master_env;
  303.         strcpy(Cmd.ctBuffer, Config.cfgInitTail);
  304.         
  305.         for (Cmd.ctCount = 0; Cmd.ctCount < 127; Cmd.ctCount++)
  306.             if (Cmd.ctBuffer[Cmd.ctCount] == 'r') break;
  307.         exb.exec.cmd_line = (CommandTail FAR *)&Cmd;
  308.         exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *)0;
  309. #ifdef DEBUG
  310.         printf("Process 0 starting: %snn", (BYTE *)szfInitialPrgm);
  311. #endif 
  312.         if((rc = DosExec(0, (exec_blk FAR *)&exb, szfInitialPrgm)) != SUCCESS)
  313.         {
  314.                 printf("nBad or missing Command Interpreter: %dn", rc);
  315.                 return -1;
  316.         }
  317.         else
  318.         {
  319.                 printf("nSystem shutdown completenReboot now.n");
  320.                 return 0;
  321.         }
  322. }
  323. extern BYTE FAR *lpBase;
  324. /* If cmdLine is NULL, this is an internal driver */
  325. VOID 
  326. init_device (struct dhdr FAR *dhp, BYTE FAR *cmdLine)
  327. {
  328.         request rq;
  329.         ULONG memtop = ((ULONG)ram_top) << 10;
  330.         ULONG maxmem = memtop - ((ULONG)FP_SEG(dhp) << 4);
  331.         if (maxmem >= 0x10000) maxmem = 0xFFFF;
  332.         rq.r_unit = 0;
  333.         rq.r_status = 0;
  334.         rq.r_command = C_INIT;
  335.         rq.r_length = sizeof(request);
  336.         rq.r_endaddr = MK_FP(FP_SEG(dhp), maxmem);
  337.         rq.r_bpbptr = (void FAR *)(cmdLine? cmdLine : "n");
  338.         rq.r_firstunit = nblkdev;
  339.         execrh((request FAR *)&rq, dhp);
  340.         
  341.         if (cmdLine) lpBase = rq.r_endaddr;
  342.         
  343.         /* check for a block device and update  device control block    */
  344.         if(!(dhp -> dh_attr & ATTR_CHAR) && (rq.r_nunits != 0))
  345.         {
  346.                 REG COUNT Index;
  347.                 
  348.                 for(Index = 0; Index < rq.r_nunits; Index++, BlockIndex++)
  349.                 {
  350.                         if (nblkdev)
  351.                             blk_devices[nblkdev - 1].dpb_next = &blk_devices[nblkdev];
  352.                         blk_devices[nblkdev].dpb_unit = nblkdev;
  353.                         blk_devices[nblkdev].dpb_subunit = Index;
  354.                         blk_devices[nblkdev].dpb_device = dhp;
  355.                         blk_devices[nblkdev].dpb_flags = M_CHANGED;
  356.                         
  357.                         ++nblkdev;
  358.                 }
  359.                 blk_devices[nblkdev - 1].dpb_next = (void FAR *)0xFFFFFFFF;
  360.         }
  361.         DPBp = &blk_devices[0];
  362. }
  363.             
  364. struct dhdr FAR *link_dhdr(struct dhdr FAR *lp, struct dhdr FAR *dhp, BYTE FAR *cmdLine)
  365. {
  366.         lp -> dh_next = dhp;
  367.         init_device(dhp, cmdLine);
  368.         return dhp;
  369. }