사용자:다메즈마/GeekOS: 두 판 사이의 차이

(→‎a: 새 문단)
123번째 줄: 123번째 줄:
</source>
</source>


== a ==
=== Project2 ===
 
이 프로젝트는 다음과 같은 구현을 해야 한다.
a
* 유저 프로세스를 생성한다.
* 어드레스 스페이스의 교환
* 시스템콜의 구현

2017년 4월 4일 (화) 09:29 판

GeekOS는 컴퓨터공학에서 운영체제 이론을 적용하여 실습하기 위해 제작된 소형 x86 운영체제다. 최신버전은 0.3.0이다.

각 프로젝트 풀이법

Project1

ELF파일을 로딩하여 메모리에 올린 후 프로그램을 실행를 하는 프로젝트다. 하지만 실제 프로젝트는 ELF파일을 파싱을 하면 된다.

elf.c

/*
 * ELF executable loading
 * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
 * Copyright (c) 2003, David H. Hovemeyer <daveho@cs.umd.edu>
 * $Revision: 1.29 $
 * 
 * This is free software.  You are permitted to use,
 * redistribute, and modify it as specified in the file "COPYING".
 */

#include <geekos/errno.h>
#include <geekos/kassert.h>
#include <geekos/ktypes.h>
#include <geekos/screen.h>  /* for debug Print() statements */
#include <geekos/pfat.h>
#include <geekos/malloc.h>
#include <geekos/string.h>
#include <geekos/elf.h>
const char  ELF_MAGIC_NUMBER[] = {0x7F,'E','L','F'};
enum ElfLoaderErrorCode
{
    ELF_LOADER_ERROR_NONE = 0,
    ELF_LOADER_ERROR_IS_WRONG_MAGINUMBER = -1,
    ELF_LOADER_ERROR_IS_NOT_ENOUGH_FILE_SIZE = -2,
    ELF_LOADER_ERROR_IS_WRONG_HEADER = -3,
    ELF_LOADER_ERROR_NOT_SUPPORT_64BIT = -4,
    ELF_LOADER_ERROR_FILE_NOT_EXISTS = -5,
    ELF_LOADER_ERROR_LOADER_NULL_POINTER = -6,
    ELF_LOADER_ERROR_NOT_SUPPORTED_ARCH = -7,
    ELF_LOADER_ERROR_FILE_IS_NOT_EXECUTABLE = -8
};

enum ElfFileHeaderClass
{
    ELF_FILE_HEADER_CLASS_32BIT = 1,
    ELF_FILE_HEADER_CLASS_64BIT = 2
};
typedef struct TAG_ELF32bitELFHeader
{
    unsigned int m_mg;//EI_MAG 4
    unsigned char m_class;//EI_CLASS 1
    unsigned char m_endianType;//EI_DATA 1
    unsigned char m_ientVersion;//EI_VERSION 1
    unsigned char m_os;//EI_OSABI 1
    
    unsigned char/*uint64_t*/ m_reserved[8];//EI_ABIVERSION AND EI_PAD 8
    unsigned short m_type;//e_type
    unsigned short m_machine;//e_machine
    unsigned int m_version;//e_version
    unsigned int m_entry;
    unsigned int m_phoff;
    unsigned int m_shoff;
    unsigned int m_flags;
    unsigned short m_ehsize;
    unsigned short m_phentsize;
    unsigned short m_phnum;
    unsigned short m_shentsize;
    unsigned short m_shnum;
    unsigned short m_shstrndx;
} ELFHeader;
/**
 * From the data of an ELF executable, determine how its segments
 * need to be loaded into memory.
 * @param exeFileData buffer containing the executable file
 * @param exeFileLength length of the executable file in bytes
 * @param exeFormat structure describing the executable's segments
 *   and entry address; to be filled in
 * @return 0 if successful, < 0 on error
 */
int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength,
    struct Exe_Format *exeFormat)
{
    
    ELFHeader * fileHeader = (ELFHeader*) exeFileData;
    programHeader * ph = NULL;
    int i = 0;
    //First, Check Magic Word, is first 4byte 0xE7 'E' 'L' 'F'
    if(fileHeader->m_mg != *(const int*)ELF_MAGIC_NUMBER)
    {
        return ELF_LOADER_ERROR_IS_WRONG_MAGINUMBER;
    }
    if(fileHeader->m_class == ELF_FILE_HEADER_CLASS_64BIT)
    {
        return ELF_LOADER_ERROR_NOT_SUPPORT_64BIT;
    }
    else if(fileHeader->m_class != ELF_FILE_HEADER_CLASS_32BIT)
    {
        return ELF_LOADER_ERROR_IS_WRONG_HEADER;
    }

    if(fileHeader->m_machine != 0x03)
    {
        return (ELF_LOADER_ERROR_NOT_SUPPORTED_ARCH);
    }
    //Second, Parse Program Header, Program Table count is phnum in File Header  
    ph = (programHeader*)(exeFileData + fileHeader->m_phoff);
    
    for(i = 0; i < fileHeader->m_phnum;i++)
    {
        struct Exe_Segment segment;
        segment.offsetInFile = ph->offset;
        segment.lengthInFile = ph->fileSize;
        segment.startAddress = ph->vaddr;
        segment.sizeInMemory = ph->memSize;
        segment.protFlags = ph->flags;
        
        exeFormat->segmentList[i] = segment;
        ph++;
    }
    exeFormat->numSegments = fileHeader->m_phnum;
    exeFormat->entryAddr =fileHeader->m_entry;
    //TODO("Parse an ELF executable image");
    return ELF_LOADER_ERROR_NONE;
}

Project2

이 프로젝트는 다음과 같은 구현을 해야 한다.

  • 유저 프로세스를 생성한다.
  • 어드레스 스페이스의 교환
  • 시스템콜의 구현