본문 바로가기
코스웨어/11년 내장형하드웨어

[내장형]황세선_2011.11.29 일일보고서

by 알 수 없는 사용자 2011. 11. 30.
728x90
반응형

시작!

아래는 뭐하는 소스인가. 음식으로 따지자면 내가 만든 스파게티? 내가 만든 스파게티는 분명 반드시~(2%) 부족한 스파게티가 될것이다. 그렇다. 아래는 내가 만든 동적할당. 역시나 ~(2%)부족하다.
이 아래 부터는 우리가 최초로 시작한 손코딩 부터 오늘까지의 소스를 단계 적으로 나누어 보았다. 지극히 개인 적인 분할이라 그 성능은 보증 할 수 없겠다. 소스의 끝에는 ~(2%) 부족한 부분의 문제점을 잠깐 짚고 넣어 간다. 자 우리 모두 스크롤을 힘차게 굴려보자.

손코딩 소스(원본?)

#include <stdio.h>

#define MAX 10

// 블럭 구조체
typedef struct _Node
{
char data[96];
struct _Node* next;
} NODE;

unsigned int num;
NODE DATA[MAX];
NODE* empty;

void MM_Init();
void* MM_malloc(unsigned int k);

int main()
{
return 0;
}

// 밭으로 따지면 땅 개간 작업
void MM_Init()
{
int cnt;

// 링크 만들기
for(cnt = 0 ; MAX - 1 > cnt ; ++cnt )
{
DATA[cnt].next = &(DATA[cnt + 1]);
}
DATA[cnt].next = 0;

empty = DATA;
num = MAX;
}

void* MM_malloc(unsigned int k)
{
NODE* temp;
int cnt;

// 용량 설정
k = (k / 97) + 1;
// 용량 한계 체크
if(k > num)
{
return 0;
}
temp = empty;
// 사용한 용량 만큼 empty 이동
for(cnt = 0 ; k > cnt ; ++cnt)
{
empty = empty->next;
}
num = num - k;

return temp;
}

손코딩 + 추가(main 코드 작성)
#include <stdio.h>

#define MAX 10

// 블럭 구조체
typedef struct _Node
{
char data[96];
struct _Node* next;
} NODE;

unsigned int num;
NODE DATA[MAX];
NODE* empty;

void MM_Init();
void* MM_malloc(unsigned int k);

int main()
{
char* h;

MM_Init();
h = (char*)MM_malloc(96);
sprintf(h, "%08X 안녕하세요\n", 100);
printf(h);
return 0;
}

// 밭으로 따지면 땅 개간 작업
void MM_Init()
{
int cnt;

// 링크 만들기
for(cnt = 0 ; MAX - 1 > cnt ; ++cnt )
{
DATA[cnt].next = &(DATA[cnt + 1]);
}
DATA[cnt].next = 0;

empty = DATA;
num = MAX;
}

void* MM_malloc(unsigned int k)
{
NODE* temp;
int cnt;

// 용량 설정
k = (k / 97) + 1;
// 용량 한계 체크
if(k > num)
{
return 0;
}
temp = empty;
// 사용한 용량 만큼 empty 이동
for(cnt = 0 ; k > cnt ; ++cnt)
{
empty = empty->next;
}
num = num - k;

return temp;
}

이 소스의 유일한 실행화면.. 별 볼것 없다.



손코딩 + 추가 + 추가(MM_free 함수 구현)
#include <stdio.h>

#define MAX 10

// 블럭 구조체
typedef struct _Node
{
char data[96];
struct _Node* next;
} NODE;

unsigned int num;
NODE DATA[MAX];
NODE* empty;

void MM_Init();
void* MM_malloc(unsigned int k);
void MM_free(void* p);


int main()
{
char* h;

MM_Init();
h
= (char*)MM_malloc(96);
sprintf(h,
"%08X 안녕하세요\n", 100);
printf(h);
MM_free(h);

return 0;
}

// 밭으로 따지면 땅 개간 작업
void MM_Init()
{
int cnt;

// 링크 만들기
for(cnt = 0 ; MAX - 1 > cnt ; ++cnt )
{
DATA[cnt].next = &(DATA[cnt + 1]);
}
DATA[cnt].next = 0;

empty = DATA;
num = MAX;
}

void* MM_malloc(unsigned int k)
{
NODE* temp;
int cnt;

// 용량 설정
k = (k / 97) + 1;
// 용량 한계 체크
if(k > num)
{
return 0;
}
temp = empty;
// 사용한 용량 만큼 empty 이동
for(cnt = 0 ; k > cnt ; ++cnt)
{
empty = empty->next;
}
num = num - k;
*((unsigned int*)temp) = k;

return (unsigned int*)temp + 1;

}

void MM_free(void* p)
{
int cnt;
NODE* temp;

p = (int*)p - 1;
temp = p;
num = num + *((unsigned int*)p);

// 반환된 블럭 연결
for(cnt = 0 ; *((int*)p) - 1 > cnt ; ++cnt)
{
temp->next = temp + 1;
++temp;
}
temp->next = empty;
empty = temp - cnt;
}


손코딩 + 추가 + 추가 + 추가(num 변수가 사라짐, 블럭 갯수 카운터)
#include <stdio.h>

#define MAX 10

// 블럭 구조체
typedef struct _Node
{
char data[96];
struct _Node* next;
} NODE;

unsigned int num;
NODE DATA[MAX];
NODE* empty;

void MM_Init();
void* MM_malloc(unsigned int k);
void MM_free(void* p);

int main()
{
char* h;

MM_Init();
h = (char*)MM_malloc(96);
sprintf(h, "%08X 안녕하세요\n", 100);
printf(h);
MM_free(h);

return 0;
}

// 밭으로 따지면 땅 개간 작업
void MM_Init()
{
int cnt;

// 링크 만들기
for(cnt = 0 ; MAX - 1 > cnt ; ++cnt )
{
DATA[cnt].next = &(DATA[cnt + 1]);
}
DATA[cnt].next = 0;

empty = DATA;
*((unsigned int*)empty) = MAX;
//num = MAX; 삭제!필요없음
}

void* MM_malloc(unsigned int k)
{
NODE* temp;
int cnt;

// 용량 설정
k = (k / 97) + 1;
// 용량 한계 체크
if( k > *((unsigned int*)empty) )
{
return 0;
}
temp = empty;
// 사용한 용량 만큼 empty 이동
for(cnt = 0 ; k > cnt ; ++cnt)
{
empty = empty->next;
}
//num = num - k; // 삭제!필요없음
// 위 코드의 대체 코드
*((unsigned int*)empty) = *((unsigned int*)temp) - k;

// 블럭 갯수를 최상위 에 저장(4byte)
*((unsigned int*)temp) = k;
return (unsigned int*)temp + 1;
}

void MM_free(void* p)
{
int cnt;
NODE* temp;

p
= (int*)p - 1;
temp
= p;
//num = num + *((unsigned int*)p); 삭제!필요없음

// 반환된 블럭 연결
for(cnt = 0 ; *((int*)p) - 1 > cnt ; ++cnt)
{
temp->next = temp + 1;
++temp;
}
temp->next = empty;
// 총 블럭 갯수 갱신
*((unsigned int*)p) = *((unsigned int*)p) + *((unsigned int*)empty);
empty = temp - cnt;
}

스크롤 굴리신다고 수고하셨습니다.;
혹시나 소스를 보신 분들은 아셨을까 모르겠지만 소스의 분홍색 부분이 위 소스에서 바뀐 점을 강조 해 놓은 부분이다.

그럼 문제점을 짚고 넘어가자. 그림부터 보자.



문제 되는 부분은 강력하게 표시해 두었다. 처음에는 동적 할당이 잘된다. 그러다가 첫번째 해제가 일어나고, 그 후 두 블럭의 동적할당 요구가 들어 온다. 바로 이 상황이 문제가 된다. 중간에 동적할당된 공간이 하나 끼어 있어 부득이 하게 그 아래의 블럭까지가 동적 할당되었다. 이제 동적 할당을 받은 프로그램은 중간의 동적할당된 공간을 자기것인양 사용하게 될것이고, 그렇게 된다면 중간에 동적할당을 한 프로그램은 엉망이 되어 버린다.
그럼 해결책은 무엇이냐?? 그것은 우리들의 숙제....음....도움 될만한 내용이 없네? 죄성합니다ㅜ;

BrickOS! 이것은 무엇인가? 어디선가 불쑥 나타나 우리들을 괴롭히고 있다. 그럼 다시.. BrickOS 란 무엇인가? 역시나 먼저 그림 부터 보자.



Brick 의 사전적 의미는 벽돌! 그렇다. 벽돌 OS? 다. 그리고 위 그림은? 그렇다. 레고 마인드 스톰이다. 그럼 BrickOS는 무엇인가? 레고 마인드 스톰에 답재되는 OS(운영체제)라는 말이다. 저런 조그만한 장난감에도 OS 가 탑재 되다니! 놀랍지는 않지만 놀라워 해주자.; 그림을 보면 우리가 오~래전에 열심히 조립하다 지쳐버린 부품들이 보인다. 이런 부품들을 Brick(브릭) 이라 부른다고 한다. 그리고 BrickOS 가 들어가는 것은 컴퓨터 브릭 이라고 한다고 한다. 으흠 그렇쿤.

BrickOS 의 등장과 함께 우리는 소스인사이틀를 열어야만 했다. 이래저래 기억도 가물가물 하고 소스인사이트 사용법을 배웠는지도 의심이 가지만.. 의심은 뒤로하고 아래 그림을 좀 보자.



무엇을 설명하는 것인지 알것이다. 이것은 소스인사이트의 맨 왼쪽 에 나오는 창이다. 이 창에서는 위와 같은 정보를 알 수 있다. 자세한 설명은 생략.....;

아차..요거 하기 전에 뭔가를 설치하고 컴파일을 했었다. 그 부분을 좀 정리 해 봐야겠다.
우리가 받은 파일은 아래와 같다. 그중 저 빨간 동그라미 파일들을 압축해제 하면 위의 실행파일 하나가 나온다. 참고로 요 이상한 압축 파일은 알집으로 안풀렸다는 것을 알것이다. 그럴때는 안철수님의 압축해제 프로그램 또는 반디집(춘우님의 소개로) 압축해제 프로그램을 사용하면 된다.



이제 실행 파일을 실행하면 설치가 진행되는데 별것 없다. 그냥 next 만 누르자. 그래서? 그림은 생략....;
다 설치되면 저 위 파일 그림의 brickos-0.9.0.tar.gz 의 압축을 풀고, 나온 폴더를 몽땅 설치된 폴더의 home 폴더 안에 집어 넣으면 된다.



다음 조금전 설치한 프로그램을 실행하자. 그러면 Cygwin 창이 뜬다. 기거서 조금전 압축 풀고 옮겨놓은 bickos-0.9.0 폴더로 이동하자. 그리고 아래와 같은 명령을 입려한 후 make 를 누르자.



위의 ./configure 명령은 make 파일을 다시 만들어 주는데 시스템에 알맞는 make 파일로 만들어 준다고 한다. 이제 make 가 실행되면 막 컴파일이 될것이다. 난 안되던데 ㅠ; 그런데 우리는 무엇을 컴파일 했을까? 아마도 BrickOS 를 컴파일 했을 것이다.;;

다시 소스인사이트로 돌아가서 그 다음 우린 무엇을 했던가? 음.. 아마 main을 찾아 봤지 싶다. main 을 찾고난 다음의 결론은?



우리가 알던 main 이 우리가 생각했던 main 이 아니라는것! 말이 참 어렵네. 우리는 main 이라 함은 프로그램에 있어서 가장 먼저 실행되는 함수였다. 그래서 우린 main 만 찾으면 프로그램의 시작 부분을 알수 있을 것이라 생각했지만 오산! BrickOS 는 kmain 이 프로그램의 시작 부분이라는 깜찍한 사실을 알게 되었다. 참고로 kmain 은 커널 main 이라는 뜻이다.

소스인사이트를 이래저래 뒤지다 우리는 두 파일을 보게 되었다. 그 첫 번재 파일은.. 그림을 통해 보자.



H8300.rcx 파일! 이 파일의 정체는 잘모르겠다. 이 파일 이름은 H8300 으로 이것은 MCU 이름 이라고 한다. 히타치 사의 MCU. 위 그림을 보면 빨간 글로 적어 두었다. 죄송한 말이지만 위에 적어 놓은것 이상으로 아는것이 없다.ㅜ 아.. ram (r) 에서 맨앞 0x0000 는 주소고 뒤의 0x8000 는 크기라고 했었다.ㅎ 아래도 마찬가지 일것이다.

다음 두 번째 파일은 ... 그림을 보자.



mm.h 파일! 요 파일에는 중요한 우리의 숙제가 들어가 있다. 바로 빨간 원 부분! 이부분에 대해서 해석해 오는 것이 숙제 였다. 이것은 매크로 함수다. 라고 주석에 표시되어 있다. 또한 mm_init() 함수를 위한 매크로 라고 되어 있다. 그외 해석....ㅠ;
이쯤 에서 숙제로 미루어 두고 그냥 끝내긴 아쉬우니 위 숙제에 조금은 도움이 될것 같은 기분이 드는 블로그 링크 하나 달아 두겠다. 자..파이팅!

http://blog.naver.com/kjhun1201?Redirect=Log&logNo=20016738293
728x90