2016년 11월 28일 월요일

FLT_STREAM_CONTEXT vs FLT_STREAMHANDLE_CONTEXT

몇년만에 드라이버코드를 작성할 일이 있어서 공부중입니다.
파일시스템이나 미니필터는 바닥부터 작성해본적이 없어서 공부하기가 쉽지 않네요.
FLT_STREAM_CONTEXT 가 FLT_STREAMHANDLE_CONTEXT 뭐가 다른건지 헤깔려서 찾아보다가 정리했습니다.


FLT_STREAM_CONTEXT vs FLT_STREAMHANDLE_CONTEXT

STREAM_CONTEXT


  • file stream 마다 붙일 수 있는 context.
  • FILE_OBJECT.FsContext 를 추적하는데 사용.

STREAMHANDLE_CONTEXT


  • 개개의 file open 시 생성되는 file object (I/O 서브시스템이 생성하는)마다 붙일 수 있는 context.
  • FILE_OBJECT 를 추적하는데 사용.



File Streams, Stream Contexts, and Per-Stream Contexts (MSDN 원문)


File Stream


파일 데이터를 저장하는데 사용되는 바이트 시퀀스이다.
보통 파일은 하나의 file stream 을 가지는데, 요걸 파일의 default data stream 이라고 한다.
그러나 multiple data stream 을 지원하는 파일시스템에서는 각각의 파일은 여러개의 file stream 을 가질 수 있다.
그 중 하나는 default data stream 이고, 얘는 unnamed 이다.
다른 놈들은 alternate data stream 이다. 파일을 열면, 실제로는 해당 파일의 스트림을 여는 것이다.


file system 이 최초로 파일을 열때, file control block(FCB) 이나 stream control block (SCB) 같은
file-system-specific stream context 구조체를 생성하고, 이 구조체의 주소를 file object 의 FsContext 멤버에 저장한다.


로컬 파일시스템에서, 이미 열려있는 file streeam 이 다시 열리면 (shared read access 같은 경우로 인해),
I/O 서브시스템은 새로운 file object 를 생성하지만, file system 은 새로운 stream context 를 생성하지는 않는다.
따라서 로컬 파일시스템에서는 stream context pointer 는 file stream 을 식별하는 유니크한 값으로 사용될 수 있다.


per-stream context 를 지원하는 네트워크 파일시스템에서는 이미 열려있는 file stream 이 동일한 network share name 이나 IP 주소 등을
이용해서 다시 열린다면 로컬 파일시스템과 동일하게 동작한다.
I/O 서브시스템은 새로운 file object 를 생성하지만 file system 은 새로운 stream context 를 생성하지 않고,
두 file object 에 동일한 FsContext 포인터를 할당한다.


그러나 file stream 이 서로 다른 경로로 열리는 경우 (다른 share name 또는 IP 가 다른 경우), file system 은
새로운 file stream context 를 생성한다.
그러므로 per-stream context 를 지원하는 네트워크 파일시스템에서는 FsContext 는 file stream 을 구분하는
유일한 값으로 사용될 수 없다.


per-stream contextFSRTL_PER_STREAM_CONTEXT 구조체를 멤버로 포함하는
filter-defined 구조체이다. 필터드라이버는 이 구조체를 file system 이 열어놓은 각각의 file stream 에 대한 정보를 추적하는데 사용한다.


File Sytem Support for Per-Stream Contexts


Microsoft Windows XP 이후, per-stream context 를 지원하는 파일시스템은 FSRTL_ADVANCED_FCB_HEADER구조체를 포함하는
stream context 구조체를 사용해야 한다.


특정 file stream 에 연관된 per-stream context 의 global list 는 file system 이 관리한다.
file system 이 file stream 을 위한 새 stream context (FSRTL_ADVANCED_FCB_HEADER object)를 생성할 때, 이 list 를 초기화하기 위해
FsRtlSetupAdvancedHeader 를 호출한다.
file system filter 드라이버가 FsRtlInsertPerStreamContext 함수를 호출하면, filter 가 생성한 per-steram context 는
그 global list 에 추가된다.


file system 이 file stream 에 대한 stream context 를 삭제하때, filter 가 가진 file stream 에 연관된 모든 per-stream context 를
제거하기 위해 FsRtlTeardownPerStreamContexts 를 호출한다.
이 루틴은 global list 에 있는 각각의 per-stream context 에 대해서 FreeCallback루틴을 호출한다.
FreeCallback 루틴은 file stream 과 연관된 file object 가 이미 소멸되었음을 인지하고 있어야 한다.


file system 이 file object 로 대표되는 file stream 에 대해서 per-stream context 를 지원하는지 확인하려면, 해당 file object 를 통해서
FsRtlSupportsPerStreamContexts를 호출할 수 있다. file system 은 어떤 파일 타입에 대해서는 per-stream context 를 지원할 수 도 있고,
그렇지 않을 수도 있다. 예를들어 NTFS 와 FAT 는 paging file 에 대해서 per-stream context 를 지원하지 않는다.
따라서 FsRtlSupportsPerStreamContexts 함수는 하나의 file stream 에 대해서는 TRUE 를 리턴하지만, 모든 file stream 에 대해서
TRUE 를 리턴하지는 않을것이다.

2016년 10월 11일 화요일

하이퍼바이저 구현을 위한 공부 방법

howto_study_hypervisor

Hypervisor 구현 방법을 공부하기 위한 가이드


레퍼런스, 메뉴얼


당연히 인텔/AMD 메뉴얼입니다. 무식하게 읽으면 어려워서, 중간에 포기하기 십상입니다만, 어느정도 개념이 잡히면 가장 먼저 보게 되는게 메뉴얼입니다. 경험상 인텔메뉴얼 만큼 좋은 자료는 없었습니다. (전 AMD SVM 은 안봐서 모릅니다. 동작 방식은 거의, 완전히 비슷합니다.)
개인적인 경험으로는 인텔메뉴얼의 Virtual Machine Extension 챕터를 세번정도 읽어보니, 머리속에 들어오기 시작하더군요.


온라인 자료



강추! 개인적으로 가장 추천하는 자료입니다. 엔텔메뉴얼과 같이 보면서 공부하셔야 할것입니다. 최소한 여기 나오는 내용을 확실히 다 숙지해야 합니다.



제가 예전에 만들었던 자료입니다. 마지막에 하이퍼바이저를 통해 안티키로거
제품 우회하는 시연영상도 있습니다.



서승현님 이 정리해두신 글입니다. KVM 코드 분석을 시작하시는 분들께 많이 도움될것 같습니다.



  • Series 1 Xen으로 배우는 가상화 기술의 이해 - CPU 가상화
  • Series 2 Xen으로 배우는 가상화 기술의 이해 - 메모리 가상화
  • Series 3 Xen으로 배우는 가상화 기술의 이해 - I/O 가상화

한빛리얼타임에서 PDF 로 구매하실 수 있습니다. Xen 하이퍼바이저 소스코드를 분석하면서 공부한 내용을 정리해서 책으로 출판했네요.
대단하신분들인듯, 하지만 가상머신의 기본 개념이나 VT-x 스펙에 대한 기초지식이 없으면 이해하기 쉽지 않을 것 같네요.


코드



Windows Interernals 의 저자중 한명인 Alex Ionescue 가 만든 하이퍼바이저입니다. 최소한의 어셈블리코드로 엄청나게 간결하게 작성된 멋진 하이퍼바이저입니다. 공부를 위해서라면 최고의 선택이라고 생각합니다.



또다른 멋진 오픈소스 구현입니다.


  • Xen, KVM, VirtualBox

제품이니 당연히 매우 높은 완성도를 보이죠. 개인적으로는 VirtualBox 소스코드가 가장 읽기 편했습니다만, 기본 개념을 이해하지 못한상태에서는 해독 불가능한 암호로 보일겁니다.


  • 기타

요즘은 다양한 하이퍼바이저 구현코드들을 쉽게 찾을 수 있더군요. 검색검색~~


도움이 될만 한 잔소리


아키텍처(x86, x64 같은)/운영체제를 공부해야 합니다


인터럽트 처리, 가상메모리 구현 같은, 리얼모드/보호모드 같은 운영체제 구현에 대한 기초 지식은 필수입니다. 어차피 하이퍼바이저는 운영체제가 직접 다루는 CPU 나 메모리를 가상화 하는 코드를 구현하는 작업입니다. 따라서 컨트롤 레지스터나 인터럽트들을 운영체제들이 어떻게 다루는지 정확히 알아야 제대로 구현하고, 트러블 슈팅이 가능하겠죠.


공부하기 쉽지는 않지만 꽤 재밌는 것들을 할 수 있습니다.


Full Virtualization vs Para-Virtualzation


가상머신을 구현하는 방법에는 Full virtualization 과 Para-Virtualization 으로 나눌 수 있습니다.
Vmware 나 Qemu 가 대표적인 Full Virtualization 제품에 속하고, Xen 이 대표적인 Para-Virtualization 제품에 속했습니다(과거형입니다).


전자는 모든 명령어를 가상화 하는겁니다. 모든 CPU 명령어를 에뮬레이트하기때문에 완전히 새로운 명령어 체계를 사용하는 아키텍처라 해도 가상화 할 수 있겠죠. 하지만 당연히 느립니다.


후자는 꼭 필요한 명령어만 가상화 합니다. 예를들어 아래와 같은 명령어가 있다고 가정합니다.


xor eax, eax
mov cr0, eax

첫번째 명령어는 그냥 범용 레지스터를 다르는 명령어이기 때문에 가상화 하지 않아도 됩니다. 실제 하드웨어를 그대로 사용하기 때문에 당연히 100% 하드웨어 성능을 냅니다. 하지만 두번째 명령어는 컨트롤 레지스터를 갱신해야 하기 때문에 반드시 가상화 해야 합니다.


첫번째 명령어 처럼 하드웨어를 직접 활용하는 걸 Direct execution 이라고 합니다. 이렇게 꼭 필요한 중요한 명령어만 가상화 하는 것을 Para-Virtualization 이라고 합니다. 당연히 Full Virtualization 보다 성능이 좋아지겠죠?


Para-Virtualization 을 구현하기 위해서는 결국 꼭 가상화해야 하는 명령어와 그렇지 않은 명령어를 구분할 수 있어야 합니다. 그래서 커널을 직접 수정하는 방식을 활용했습니다. mov cr0, eax 같은 명령어를 찾아서 가상머신에게 가상화해달라고 요청하도록 커널코드를 직접 수정했습니다. 응용프로그램은 어차피 반드시 가상화 해야 하는 명령어를 사용하지 않으니 별 문제 없겠죠.


이렇게 가상머신에게 해당 명령어를 가상화해달라고 요청하는것을 하이퍼 콜(hyper call) - vm 과 host 간 호출 이라고 합니다.
그래서 Xen 에서 리눅스 올리려면, 전용 리눅스 커널을 사용해야 했습니다.


그런데 Windows 같은 운영체제는 커널을 직접 수정할 수 없기때문에, VT-x/SVM 기술이 나오기 전까지는 Para-Virtualization 방식의 가상머신 제품은 Windows 운영체제를 지원하지 못했습니다. 재밌는건 Vmware 같은 경우 Full Virtualization 방식임에도 불구하고 Xen 같은 제품보다 더 빨랐다는...


아무튼 옛날엔 그랬고, VT-x/SVM 이 나온 이후 가상머신을 만드는 방식이 매우 간편해졌습니다. 간편해 진게 아니라, 간편하게 만든것이죠.
앞에서 얘기했던 반드시 가상화 해야 하는 명령어와 그렇지 않은 명령어를 CPU, 즉 아키텍처에서 알아서 구분해줍니다. 가상머신 개발자는 CPU 가 알려주는 반드시 가상화하라고 통지하는 이벤트를 상황에 맞게 알아서 잘 처리해주면 됩니다. 이걸 VMExit 이라고 합니다.
저는 하이퍼바이저 구현은 VM Exit handler/callback 작성 이라고 표현하곤 합니다.


따라서 하드웨어 가상화 기술이 나온 이후에는 Para-Virtualization 이니 뭐니 하는게 필요가 없죠. 그렇기 때문에 이제는 Xen 도 Windows 를 가상화할 수 있게 된겁니다. 개발하기도 훨씬 쉬워졌죠. 만세~


Nested VM ?


가상머신 안에 또 가상머신 안에 또 가상머신?


무지막지하게 느릴까요? 당연히 느려지기야 하겠지만, 앞에서 얘기한 direct execution 때문에 그렇게 미친듯이 느려지지는 않을것입니다. 하이퍼바이저 개발자 입장에서는 관리할 자료구조가 훨씬 복잡해지고, 메모리 변환등으로 인해 복잡하긴 하겠지만요.


QEMU 에 대해서


QEMU 는 원래 에뮬레이터입니다.
에뮬레이터이기 때문에 호스트가 x86 이라도 x64, ARM 등의 명령어를 에뮬레이트 할 수 있기때문에 다양한 아키텍처를 지원할 수 있죠. 다양한 CPU를 소프트웨어로 에뮬레이트 할 수 있으니까요. 세상에 있는 모든 cpu 를 지원한다죠? 그렇기 때문에 엄청 느렸습니다.


하드웨어 가상화(VT-x, SVM 같은) 기술이 나온 이후, CPU 에뮬레이트는 하드웨어 가상화 기능을 활용하기 시작했습니다. 그게 바로 KVM 이구요. 나머지 하드웨어들은 소프트웨어로 에뮬레이팅 합니다. 다른 Vmware, Virttual Box 같은 가상머신 제품도 마찬가지 입니다.


만일 QEMU로 호스트의 아키텍처와 다른 아키텍처를 가상머신으로 돌리고자 한다면, VT-x 같은 기술을 활용 할 수 없기때문에 100% 에뮬레이팅에 의존 할 수 없을 겁니다. 느리겠죠?


간략히 얘기하자면, QEMU 는 다양한 디바이스/하드웨어에 대한 에뮬레이팅을 담당하고, KVM 은 CPU/Memory 가상화를 담당한다고 보시면 됩니다. 따라서 VT-x/SVM 구현에 관심있는 분이라면 QEMU 코드를 살펴보기보다는 리눅스 커널에 포함된 KVM 구현 코드를 분석하셔야 합니다.

2014년 12월 27일 토요일

boost::asio timer 사용하기

오늘은 boost::asio 예제코드를 보다가 (몰라서) 헤멧던 내용을 공유할까 합니다.
c++ 이나 boost 같은 라이브러리에 익숙하지 않은 저 같은 c++ 초보자들에게 도움이 되길 바라며 :-)
오늘은 그냥… 괜히… Windows 의 타이머 객체를 사용하고 싶지 않아서, boost::asio 의 timer 예제코드 를 조금 수정해서 아래와 같은 코드를 작성했습니다. 간단히 설명하자면 정해진 시간(1초)이 지나면 callback 함수(print(…))를 5번만 호출하는 코드입니다.
void print(const boost::system::error_code& e, boost::asio::steady_timer* timer, int* count)
{
    if (*count < 5)
    {
        std::cout << *count << "\n";
        ++(*count);

        timer->expires_from_now(boost::chrono::seconds(1));
        timer->async_wait(boost::bind(print, boost::asio::placeholders::error, timer, count));
    }
}


int main()
{
    boost::asio::io_service io_service;

    int count = 0;
    boost::asio::steady_timer timer(io_service);
    timer.async_wait(boost::bind(
                                print,
                                boost::asio::placeholders::error,
                                &timer,
                                &count));
    io_service.run();

    std::cout << "count = " << count << std::endl;
    return true;
}
timer.async_wait() 함수는 아래와 같은 함수 포인터 또는 함수객체를 파라미터로 받습니다. 여기에 자세한 내용이 있습니다.
void handler(
  const boost::system::error_code& error // Result of operation.
);
예제에서는 부가적인 파라미터를 전달 받는 print() 함수를 async_wait() 의 파라미터로 사용하기 위해서 아래의 코드 처럼 boost::bind() 를 이용했습니다.
    timer.async_wait(boost::bind(
                                print,
                                boost::asio::placeholders::error,
                                &timer,
                                &count));
저는 print() 함수에 전달되는 파라미터로 boost::asio::deadline_timer 와 count 의 포인터 타입이 사용되는것이 그냥 맘에 안들어서 참조자로 바꾸고 싶었습니다.
boost::asio::placeholders::error 는 boost::bind() 를 사용할 때 _1 같은 역할을 하는 placeholder argument 이므로, boost::bind(print, _1, timer, count) 와 같으므로, timer 와 count 를 참조자로 넘겨도 아무 문제 없을 것 같았습니다.
void
print(
    const boost::system::error_code& /*e*/,
    boost::asio::deadline_timer& t,
    int& count
    )
print() 함수 파라미터를 참조자를 받도록 변경하고 컴파일하면 아래처럼 복잡한 에러가 발생합니다.
1>  All outputs are up-to-date.
1>  _test_boost_asio_timer.cpp
1>c:\Boost_x64\include\boost-1_56\boost/asio/basic_waitable_timer.hpp(514): error C2248: 'boost::asio::basic_io_object<IoObjectService>::basic_io_object' : cannot access private member declared in class 'boost::asio::basic_io_object<IoObjectService>'
1>          with
1>          [
1>              IoObjectService=boost::asio::waitable_timer_service<boost::chrono::steady_clock,boost::asio::wait_traits<boost::chrono::steady_clock>>
1>          ]
1>          c:\Boost_x64\include\boost-1_56\boost/asio/basic_io_object.hpp(163) : see declaration of 'boost::asio::basic_io_object<IoObjectService>::basic_io_object'
1>          with
1>          [
1>              IoObjectService=boost::asio::waitable_timer_service<boost::chrono::steady_clock,boost::asio::wait_traits<boost::chrono::steady_clock>>
1>          ]
1>          This diagnostic occurred in the compiler generated function 'boost::asio::basic_waitable_timer<Clock>::basic_waitable_timer(const boost::asio::basic_waitable_timer<Clock> &)'
1>          with
1>          [
1>              Clock=boost::chrono::steady_clock
1>          ]
1>
1>Build FAILED.
찬찬히 읽어보니 boost::asio::basic_io_object<IoObjectService> 클래스에 정의된 private member 에 접근하지 못한다는 에러입니다. 대체 이런 에러는 어디서 나는걸까 고민하다가 boost::bind 문서를 다시 한번 읽어보니 해답이 보이더군요.
a copy of the value of i is stored into the function object. boost::ref and boost::cref can be used to make the function object store a reference to an object, rather than a copy:
boost::bind 는 고정된 변수값을 call by value 로 넘기는게 기본인가 봅니다. (미루어 보건데 - 소스를 보지 않았으니 - boost::bind 는 함수 객체를 생성하는것으로 구현했는가 보네요.)
결국 boost::bind 호출시 사용된 timer 객체가 call by value 로 넘어가면서 복사 생성자나 대입 연산자가 호출되는 시점에 오류가 발생한 것 같습니다.
/// Base class for all I/O objects.
/**
 * @note All I/O objects are non-copyable. However, when using C++0x, certain
 * I/O objects do support move construction and move assignment.
 */
#if !defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
template <typename IoObjectService>
#else
template <typename IoObjectService,
    bool Movable = detail::service_has_move<IoObjectService>::value>
#endif
class basic_io_object
{
public:
...
protected:
  /// Construct a basic_io_object.
  /**
   * Performs:
   * @code get_service().construct(get_implementation()); @endcode
   */
  explicit basic_io_object(boost::asio::io_service& io_service)
    : service(boost::asio::use_service<IoObjectService>(io_service))
  {
    service.construct(implementation);
  }

private:
  basic_io_object(const basic_io_object&);
  basic_io_object& operator=(const basic_io_object&);
};
코드를 따라가 보니 class basic_waitable_timer 템플릿 클래스는 public basic_io_object 를 상속받았고, basic_io_object 템플릿 클래스의 복사 생성자와 대입연산자가 private 으로 선언되어있음을 확인 할 수 있었습니다. 클래스 자체가 복사하지 않도록 디자인된 녀석이었습니다!
포인터를 사용하지 않고, 참조자를 사용하도록 수정한 코드는 아래와 같습니다.
void print(const boost::system::error_code& e, boost::asio::steady_timer& timer, int& count)
{
    if (count < 5)
    {
        std::cout << count << "\n";
        ++(count);

        timer.expires_from_now(boost::chrono::seconds(1));
        timer.async_wait(boost::bind(print, boost::asio::placeholders::error, boost::ref(timer), boost::ref(count)));
    }
}

bool test_boost_asio_timer_3()
{
    boost::asio::io_service io_service;

    int count = 0;
    boost::asio::steady_timer timer(io_service);
    timer.async_wait(boost::bind(
                                print,
                                boost::asio::placeholders::error,
                                boost::ref(timer),
                                boost::ref(count)));
    io_service.run();

    std::cout << "count = " << count << std::endl;
    return true;
}
오늘도 하나 배웠습니다. :-)

2014년 9월 16일 화요일

Windows 에서 UEFI 빌드 환경 구성하기

Windows 에서 UEFI 빌드 환경 구성하기


요약

UDK2014 를 Windows 개발환경에서 빌드하는 방법을 설명합니다. UDK 패키지 파일내의 2014-ReleaseNotes-MyWorkSpace.txt 를 참고했습니다.

시작

  1. 개발 환경
    • windows 7, x64
    • visual studio 2010
  2. 소스코드 압축 풀기
    • UDK2014.MyWorkSpace.zip -> d:\work.uefi\MyWorkSpace
    • BaseTools(Windows).zip -> d:\work.uefi\MyWorkSpace\BaseTools\
  3. 빌드 환경 셋업 하기
    • d:\work.uefi\MyWorkSpace 에서 command prompt 하나 띄우고,
    • EDK_TOOLS_PATH 환경 변수 설정해주고
    • edksetup.bat --nt32 실행하면 준비 완료
        d:\work.uefi\MyWorkSpace>set EDK_TOOLS_PATH=d:\work.uefi\MyWorkSpace\BaseTools\BaseTools
      
        d:\work.uefi\MyWorkSpace>edksetup.bat --nt32
                  PATH      = d:\work.uefi\MyWorkSpace\BaseTools\BaseTools\Bin;d:\work.uefi\MyWork
        Space\BaseTools\BaseTools\Bin\Win32;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VS
        TSDB\Deploy;...[skip]
      
             WORKSPACE      = d:\work.uefi\MyWorkSpace
        EDK_TOOLS_PATH      = d:\work.uefi\MyWorkSpace\BaseTools\BaseTools
      
        copying ... target.template to d:\work.uefi\MyWorkSpace\Conf\target.txt
        copying ... tools_def.template to d:\work.uefi\MyWorkSpace\Conf\tools_def.txt
        copying ... build_rule.template to d:\work.uefi\MyWorkSpace\Conf\build_rule.txt
      
        Rebuilding of tools is not required.  Binaries of the latest,
        tested versions of the tools have been tested and included in the
        EDK II repository.
      
        If you really want to build the tools, use the ForceRebuild option.
      
        !!! WARNING !!! No CYGWIN_HOME set, gcc build may not be used !!!
      
        d:\work.uefi\MyWorkSpace>
      
  4. 빌드하기
    • build -t <tool chain name> 명령으로 빌드
    • tool chain 을 변경하려면
      • Conf/target.txt : TOOL_CHAIN_TAG = VS2010x86 으로 변경하거나
      • build -t <tool chain name>
    • x64 머신에서 x86 버전 vs 를 사용하므로 VS2010x86 tool chain 을 사용
    • vs 는 x86 버전밖에 없다는 건 함정
    • tool chain 정보는 Conf/tools_def.txt 참고 (edksetup 에서 동적으로 생성해 주는 파일 임)
        d:\work.uefi\MyWorkSpace>build -t VS2010x86
        ..........
        ..........
        Generate Region at Offset 0x28E000
           Region Size = 0x2000
           Region Name = DATA
      
        Generate Region at Offset 0x290000
           Region Size = 0x10000
           Region Name = None
      
        GUID cross reference file can be found at d:\work.uefi\myworkspace\Build\NT32IA32\DEBUG_VS
        2010x86\FV\Guid.xref
      
        FV Space Information
        FVRECOVERY [66%Full] 2621440 total, 1733424 used, 888016 free
      
        - Done -
        Build end time: 23:37:28, Sep.16 2014
        Build total time: 00:02:12
        d:\work.uefi\MyWorkSpace>
      
  5. 하드웨어의 기능을 이용하는 빌드 옵션들
    • build -D <option> 을 이용해서 기능 추가 할 수 있음
    • build -D SECURE_BOOT_ENABLE <- 요렇게!
    • SECURE_BOOT_ENABLE
      • Provides access for generic authentication information
      • associated with specific device path.
    • TPM_UID_ENABLE
      • Provides TCG-defined service, and user identification feature.
    • IP6_NETWORK_ENABLE
      • Provides Ipv6 network stack support.
    • DUAL_NETWORK_ENABLE
      • Provides both Ipv4 and Ipv6 network stacks support.
    • SOURCE_DEBUG_ENABLE
      • Provides source debugging feature.
  6. visual studio 에서 빌드하려면?
  7. 실행은?
    • make 의 run 타겟을 이용할 수도 있고
    • d:\work.uefi\MyWorkSpace\Build\NT32IA32\DEBUG_VS2010x86\IA32\SecMain.exe 를 실행해도 됨
  8. 끝!

2014년 9월 12일 금요일

VMWARE 에서 UEFI 모드로 windows 8 설치하기

Enable efi mode in vmware


  1. vmware 로 새로운 가상머신을 생성
    • windows 8 x64 이미지 생성
    • ‘install os later’ 를 선택해서 vmx 파일만 만들고, 실제 OS 를 설치하지는 않음
  2. 가상머신 설정 수정
    • VM Tweaker 다운로드
    • VM Teaker -> EFI BIOS Tweaks -> Enable ‘efi’ BIOS boot type 체크
  3. CD rom 을 win8 x64 iso 파일로 지정하고, OS 설치
  4. OS 설치 완료 후 EFI system partition 이 있으면 ㅇㅋ!
  5. vmware tools 설치해주고, 스냅샷 떠 놓으면 끝!

2014년 8월 21일 목요일

boost build summary

Build and Install boost

  1. download boost library at http://www.boost.org/
  2. extract library to d:\work.lib\boost_1_56_0\
  3. build build tool
     d:\work.lib\boost_1_56_0>bootstrap.bat
     Building Boost.Build engine
    
     Bootstrapping is done. To build, run:
    
         .\b2
    
     To adjust configuration, edit 'project-config.jam'.
     Further information:
    
         - Command line help:
         .\b2 --help
    
         - Getting started guide:
         http://boost.org/more/getting_started/windows.html
    
         - Boost.Build documentation:
         http://www.boost.org/boost-build2/doc/html/index.html
    
     d:\work.lib\boost_1_56_0>
    
  4. build and install boost library at c:\Boost_x86\, c:\Boost_x64\
     d:\work.lib\boost_1_56_0>b2.exe toolset=msvc-10.0 --build-type=complete --build-dir=d:\work.lib\boost_1_56_0\build_dir_x86 --prefix=c:\Boost_x86 install
    
     d:\work.lib\boost_1_56_0>b2.exe toolset=msvc-10.0 address-model=64 --build-type=complete --build-dir=d:\work.lib\boost_1_56_0\build_dir_x64 --prefix=c:\Boost_x64 install
    
  5. If you want boost::python, install python before build boost. :-)

2014년 5월 21일 수요일

hypervisor 구현 세미나 자료

hypervisor 구현 관련 세미나 자료입니다.
vmware 같은 가상머신을 어떻게 만드는지에 대한 내용입니다.

재 작년인가에 세미나할때 만든 거 같은데 :-)
동영상도 있습니다. 음하하하


[slide share]