(→a: 새 문단) |
(→a) |
||
123번째 줄: | 123번째 줄: | ||
</source> | </source> | ||
== | === Project2 === | ||
이 프로젝트는 다음과 같은 구현을 해야 한다. | |||
* 유저 프로세스를 생성한다. | |||
* 어드레스 스페이스의 교환 | |||
* 시스템콜의 구현 |
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
이 프로젝트는 다음과 같은 구현을 해야 한다.
- 유저 프로세스를 생성한다.
- 어드레스 스페이스의 교환
- 시스템콜의 구현