⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task.c

📁 DOS操作系统源代码,研究操作系统用. 包括了dos的所有源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
        iregs FAR *irp;
        long j;

        /* restore parent                                       */
        p = MK_FP(cu_psp, 0);

        /* When process returns - restore the isv               */
        setvec(0x22, p -> ps_isv22);
        setvec(0x23, p -> ps_isv23);
        setvec(0x24, p -> ps_isv24);

        /* And free all process memory if not a TSR return      */
        if(!tsr)
        {
                for(i = 0; i < p -> ps_maxfiles; i++)
                {    
                        DosClose(i);
                }
                FreeProcessMem(cu_psp);
        }

        cu_psp = p -> ps_parent;
        q = MK_FP(cu_psp, 0);
        dta = q -> ps_dta;

        irp = (iregs FAR *)q -> ps_stack;

        irp -> CS = FP_SEG(p -> ps_isv22);
        irp -> IP = FP_OFF(p -> ps_isv22);
        
        if (InDOS)
        	--InDOS;
        exec_user((iregs FAR *)q -> ps_stack);
}
#endif

static COUNT 
DosExeLoader (BYTE FAR *namep, exec_blk FAR *exp, COUNT mode)
{
        COUNT rc, env_size, i, nBytesRead;
        UWORD mem, env, asize, start_seg;
        ULONG image_size;
        ULONG image_offset;
        BYTE FAR *sp, FAR * dp;
        psp FAR *p;
        psp FAR *q = MK_FP(cu_psp, 0);
        mcb FAR *mp, FAR *envp = 0;
        iregs FAR *irp;
        UWORD reloc[2];
        seg FAR *spot;
        LONG exe_size;

#ifdef IPL
        BYTE szNameBuffer[64];
#endif

#ifndef IPL
        /* Clone the environement and create a memory arena     */
        if(mode != OVERLAY)
        {
                if((rc = ChildEnv(exp, &env, namep)) != SUCCESS)
                        return rc;
        }
        else
                mem = exp -> load.load_seg;

        envp = MK_FP(env, 0);
#endif

        /* compute image offset from the header                 */
#ifdef IPL
        fscopy(namep, (BYTE FAR *)szNameBuffer);
        printf("\nEXE loader loading: %s", szNameBuffer);
#endif
        image_offset = (ULONG)header.exHeaderSize * 16l;

        /* compute image size by removing the offset from the   */
        /* number pages scaled to bytes plus the remainder and  */
        /* the psp                                              */
        /*  First scale the size                                */
        image_size = (ULONG)(header.exPages) * 512l;
        /* remove the offset                                    */
        image_size -= image_offset;

#if 0
        /* add in the remainder bytes                           */
        if(header.exExtraBytes != 0)
                image_size -= (ULONG)(512 - header.exExtraBytes);
#endif
        /* and finally add in the psp size                      */
        if(mode != OVERLAY)
                image_size += (ULONG)long2para((LONG)sizeof(psp));

#ifndef IPL
        
        if(mode != OVERLAY)
        {
                
                /* Now find out how many paragraphs are available       */
                if((rc = DosMemLargest((seg FAR *)&asize)) != SUCCESS)
                {         
                        return rc;
                }
                else
                {
                        exe_size = (LONG)long2para(image_size) + header.exMinAlloc + long2para((LONG)sizeof(psp));
                        if(exe_size > asize)
                                return DE_NOMEM;
                        else if(((LONG)long2para(image_size) + header.exMaxAlloc + long2para((LONG)sizeof(psp))) < asize)
                                exe_size = (LONG)long2para(image_size) + header.exMaxAlloc + long2para((LONG)sizeof(psp));
                        else
                                exe_size = asize;
                }

                /* Allocate our memory and pass back any errors         */
                /* We can still get an error on first fit if the above  */
                /* returned size was a bet fit case                     */
                if((rc = DosMemAlloc((seg)exe_size, FIRST_FIT, (seg FAR *)&mem, (UWORD FAR *)&asize)) < 0)
                {
                        if(rc == DE_NOMEM)
                        {
                                if((rc = DosMemAlloc(0, LARGEST, (seg FAR *)&mem, (UWORD FAR *)&asize)) < 0)
                                {
                                        if(env != 0)
                                                DosMemFree(env);
                                        return rc;
                                }
                                /* This should never happen, but ...    */
                                if(asize < exe_size)
                                {
                                        if(env != 0)
                                                DosMemFree(env);
                                        DosMemFree(mem);
                                        return rc;
                                }
                        }
                        else
                        {
                                if(env != 0)
                                        DosMemFree(env);
                                return rc;
                        }
                }
                else
                /* with no error, we got exactly what we asked for      */
                        asize = exe_size;
        }
#else
        mem = KERNSEG;
#endif
#ifndef IPL
        if(mode != OVERLAY)
        {
#endif
                /* memory found large enough - continue processing      */
                mp = MK_FP(mem, 0);
                ++mem;
#ifndef IPL
        }
        else
                mem = exp -> load.load_seg;
#endif

#ifdef IPL
        printf(".");
#endif
        /* create the start seg for later computations          */
        if(mode == OVERLAY)
                start_seg = mem;
        else
        {
                start_seg = mem + long2para((LONG)sizeof(psp));
	}

        /* Now load the executable                              */
        /* If file not found - error                            */
        /* NOTE - this is fatal because we lost it in transit   */
        /* from DosExec!                                        */
        if((rc = dos_open(namep, 0)) < 0)
        {        
                fatal("(DosExeLoader) exe file lost in transit");
        }
#ifdef IPL
        printf(".");
#endif
        /* offset to start of image                             */
        if (dos_lseek(rc, image_offset, 0) != image_offset)
        {
#ifndef IPL
                if(mode != OVERLAY)
                {
                        DosMemFree(--mem);
                        if(env != 0)
                                DosMemFree(env);
                }
#endif
                return DE_INVLDDATA;
        }

#ifdef IPL
        printf(".");
#endif
        /* read in the image in 32K chunks                      */
        if(mode != OVERLAY)
        {
                exe_size = image_size - long2para((LONG)sizeof(psp));
        }
        else
                exe_size = image_size;
        sp = MK_FP(start_seg, 0x0);

        if(mode != OVERLAY)
	{
		if((header.exMinAlloc == 0) && (header.exMaxAlloc == 0))
		{
			sp = MK_FP(start_seg + mp -> m_size
			 - (image_size + 15) /16, 0);
		}
	}

        while(exe_size > 0)
        {
                nBytesRead = dos_read((COUNT)rc, (VOID FAR *)sp, (COUNT)(exe_size < CHUNK ? exe_size : CHUNK));
                sp = add_far((VOID FAR *)sp, (ULONG)CHUNK);
                exe_size -= nBytesRead;
                if(nBytesRead == 0 || exe_size <= 0)
                        break;
#ifdef IPL
                printf(".");
#endif
        }

#if 0
        /* Error if we did not read the entire image            */
        if(exe_size != 0)
                fatal("Broken exe loader (exe_size != 0)");
#endif

        /* relocate the image for new segment                   */
        dos_lseek(rc, (LONG)header.exRelocTable, 0);
        for (i=0; i < header.exRelocItems; i++)
        {
                if (dos_read(rc, (VOID FAR *)&reloc[0], sizeof(reloc)) != sizeof(reloc))
                {
                        return DE_INVLDDATA;
                }
                if(mode == OVERLAY)
                {
                        spot = MK_FP(reloc[1] + mem, reloc[0]);
                        *spot = *spot + exp -> load.reloc;
                }
                else
                {
                /*      spot = MK_FP(reloc[1] + mem + 0x10, reloc[0]);*/
                        spot = MK_FP(reloc[1] + start_seg, reloc[0]);
                        *spot = *spot + start_seg;
                }
        }

#ifdef IPL
        printf(".");
#endif
        /* and finally close the file                           */
        dos_close(rc);

        /* exit here for overlay                                */
        if(mode == OVERLAY)
                return SUCCESS;

        /* point to the PSP so we can build it                  */
        p = MK_FP(mem, 0);   
        setvec(0x22, (VOID (INRPT FAR *)(VOID))MK_FP(user_r -> CS, user_r -> IP));
        new_psp(p, mem + asize);

#ifndef IPL
        p -> ps_environ = env == 0 ? 0 : env + 1;
#else
        p -> ps_environ = 0;
#endif

        /* complete the psp by adding the command line          */
        p -> ps_cmd_count = exp -> exec.cmd_line -> ctCount;
        fbcopy(exp -> exec.cmd_line -> ctBuffer, p -> ps_cmd, 127);
#if 0        
        /* stick a new line on the end for safe measure         */
        p -> ps_cmd[p -> ps_cmd_count] = '\r';
#endif
        /* identify the mcb as this functions'                  */
        /* use the file name less extension - left adjusted and */
        /* space filled                                         */
        mp -> m_psp = mem;
        if (envp) envp -> m_psp = mem;

        for(i = 0; i < 8; i++)
        {
                if(namep[i] != '.')
                        mp -> m_name[i] = namep[i];
                else
                        break;
        }
        for(; i < 8; i++)
                        mp -> m_name[i] = ' ';

        /* build the user area on the stack                     */
        irp = MK_FP(header.exInitSS + start_seg, ((header.exInitSP - sizeof(iregs)) & 0xffff));

#ifdef IPL
        printf(".\n");
#endif
        /* start allocating REGs                                */
        /* Note: must match es & ds memory segment              */
        irp -> ES = irp -> DS = mem;
        irp -> CS = header.exInitCS + start_seg;
        irp -> IP = header.exInitIP;
        irp -> AX = 0xffff; /* for now, until fcb code is in    */
#ifdef IPL
        irp -> BX = BootDrive;
        irp -> CX = NumFloppies;
#else
        irp -> BX =
        irp -> CX =
#endif
        irp -> DX =
        irp -> SI =
        irp -> DI =
        irp -> BP = 0;
        irp -> FLAGS = 0x200; 
                                        
        /* Transfer control to the executable                   */
        p -> ps_parent = cu_psp;
        p -> ps_prevpsp = (BYTE FAR *)MK_FP(cu_psp, 0);
        q -> ps_stack = (BYTE FAR *)user_r;
        user_r -> FLAGS &= ~FLG_CARRY;

#ifdef IPL
        printf("Starting kernel ...\n");
#endif
        
        switch(mode)
        {
        case LOADNGO:
                cu_psp = mem;
                dta = p -> ps_dta;
                if (InDOS) --InDOS;
                exec_user(irp);
                /* We should never be here                      */
                fatal("KERNEL RETURNED!!!");
                break;

#ifndef IPL
        case LOAD:
                cu_psp = mem;
                exp -> exec.stack = (BYTE FAR *)irp;
                exp -> exec.start_addr = MK_FP(irp -> CS, irp -> IP);
                return SUCCESS;
#endif
        }

        return DE_INVLDFMT;
}

COUNT 
DosExec (COUNT mode, exec_blk FAR *ep, BYTE FAR *lp)
{
        COUNT rc;
        exec_blk leb = *ep;
        BYTE FAR *cp;
	BOOL bIsCom = FALSE;

        /* If file not found - free ram and return error        */
#ifdef IPL
        printf(".");
#endif

        if((rc = dos_open(lp, 0)) < 0)
        {
                return DE_FILENOTFND;
        }
        
        if(dos_read(rc, (VOID FAR *)&header, sizeof(exe_header))
         != sizeof(exe_header))
        {
#ifdef IPL
                printf("Internal IPL error - Read failure");
                return DE_INVLDDATA;
#else
		bIsCom = TRUE;
#endif
        }
        dos_close(rc);

#ifdef IPL
        printf(".");
#endif
        if(bIsCom || header.exSignature != MAGIC)

#ifndef IPL
        {
                rc = DosComLoader(lp, &leb, mode);
        }
#else
        {
                char szFileName[32];

                fmemcpy((BYTE FAR *)szFileName, lp);
                printf("\nFile: %s (MAGIC = %04x)", szFileName, header.exSignature);
                fatal("IPL can't load .com files!");
        }
#endif
        else
        {
                rc = DosExeLoader(lp, &leb, mode);
        }
        if (mode == LOAD && rc == SUCCESS)
                *ep = leb;

        return rc;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -