리눅스 환경에서의 개발은 내가 갖고있는 바이오 노트북에서 이루어지는데, 바이오 노트북이 사실 해상도가 무지 낮다. 게다가 11인치짜리 모델이라…ㅠㅠ 게다가 책상 위가 난잡해지는 게 싫어서 평상시엔 켜놓고 나서 원격으로 이용중이다. 뭐, 이 글과는 관련은 없다. 스샷과는 관련이 좀 있다. ㅠㅠ
규링은 운영체제를 가지고 석사 논문을 쓰고 있다. (여럿 쓴 것도 있다.) 그런 녀석이 운영체제 하나 직접 만들어보는 게 어려울까 싶어서 도전해 보려 해도… 어렵다. ㅇㅅㅇ
자료는 뒤지면 여러모로 나온다. 게다가 여기까지의 부트로더 기술과 32비트 보호보드는 인텔의 메뉴얼과 몇몇 정형화된 코드들이 있어서 어렵지 않게 작업할 수 있긴 하다. 근데 그걸 머릿속에서 막 쥐어짜면서 직접 코드로 짜니깐 안쉽다. (게다가 어셈블리어다.)
근데 막상 만들고 나니 실제로 다른곳에서 만든 것과 거의 유사한 코드들이 나온다. 그래서 그나마 조금은 덜 걸렸을지도 모르겠다.
p.s. 왜 사람들이 이 수준이 되면 비슷한 변수명을 가져다가 막 예시로 만드는지 알겠다. 그게 제일 안전하다. 내 코드스타일 식의 변수명을 붙이고 하는 건 좀 있다가의 작업이 되겠다. ㅇㅅㅇ
운영체제를 개발해 보고 싶다고 맘먹는 사람들은 많아도 실제로 운영체제를 직접 개발해보는 사람은 실제로 많지 않다. 진입장벽 자체가 엄청 어렵다. 대학 학부에서는 솔직히 별 도움도 안되는 수준의 어셈블리어를 가르치는 경우도 많고, C언어도 그닥 잘 배워서 오지 않는 경우도 많다.
그런데 운영체제의 개발에 대한 자료는 많다. 그리고 자작 운영체제에 대한 것들도 사실 엄청 많이 존재한다. 우리가 주로 쓰는 운영체제의 숫자가 그렇게 많지 않을 뿐이지, 개개인이 직접 만들어보겠다고 하면서 자작으로 만드는 운영체제의 숫자는 연간 몇 백 에서 몇 천 단위가 된다고 할 정도로 많이 존재한다. 홈브류 컴퓨터 만들어보겠다고 여러모로 취미로 굴려보는 사람들하고 같다고 보면 된다.
게다가 직접 동작하고자 하는 운영체제는 x86 기반이라면 자료가 진짜로 넘치고 넘친다. 요즘은 ARM 보드에서 동작하는 것들도 자료 보고 많이 만들고 하는 거 같다만, ARM쪽은 내가 모르는 게 아직 많아서… 게다가 자료 올려주는 사람들이 뭔 특정 수치를 주고 거기에 입력을 하는데, 그 값들이 뭔지 정확하게 알고 적는 사람이 은근 없어서 되게 불편하다. (운영체제 개발에는 그것들이 엄청 중요하다.)
그런 대표적인 자료를 올려놓은 위키가 바로 이번 제목에 있는 위키이다. 운영체제에 조금이라도 관심이 있는 사람들은 아마 여기 있는 자료를 한번도 보지 않은 사람은 없을 것이다. 아주 기초적인 개발 환경 뿐만 아니라 부트로더부터 시작해서 운영체제 이론에 등장하는 여러 내용들, 그리고 각종 장치 드라이버 및 레퍼런스 북까지…
시간 정보를 여러 형식으로 변환할 수 있는데, localtime과 gmtime은 time_t 형 시간 정보를 struct tm형으로 변환한다. 이 형을 한번 살펴보자.
struct tm {
int tm_sec; //초 (0~59)
int tm_min; //분 (0~59)
int tm_hour; //시간 (0~23)
int tm_mday; //일 (1~31)
int tm_mon; //월 (0~11)
int tm_year; //연도(1990~)
int tm_wday; //요일 (0~6)
int tm_yday; //1월 1일 이후의 날짜
int tm_isdst; //썸머타임(양수일 때 유효, 0일때 무효, 음수일 때 사용 불가)
}
함수 이름 | 기능
localtime | time_t형 시간 정보를 struct tm형 지역 시간으로 변환한다.
gmtime | time_t형 시간 정보를 struct tm형 세계 표준 시간으로 변환한다.
기능에 보면 시간 표기의 차이가 있다는 것을 볼 수 있다. 리눅스 설치 시에 지정한 로컬 타임존에 따라서 지역 시간으로 변환하느냐 아니면 글로벌 시간으로 변환하느냐의 차이다. 사용법은 아래의 예시를 확인하자.
이와 반대로 struct tm 형 시간을 time_t형으로 변환하는 함수 또한 존재한다.
함수 이름 | 기능
mktime | struct tm형 시간 정보를 time_t형으로 변환한다.
또한 struct tm형의 시간 정보를 사용자가 알아보기 쉽게 문자열로 변환해주는 함수 또한 존재한다. 기본적으로 제공되는 서식 형태로도 만들 수 있지만, 개발자가 직접 서식을 지정할 수 잇는 함수 또한 존재한다.
함수 이름 | 기능
asctime | struct tm 형 시간 정보를 문자열로 변환한다.
strftime | struct tm형 시간 정보를 서식을 갖춘 시간 정보로 변환한다.
변환에 필요한 변환 형식은 변환 문자열을 확인하여 직접 작성하면 된다. 두 번째에 변환 포맷을 지정할 수 있고, 변환 문자열은 다음과 같다.
변환 문자열 | 의미
%a | 요일 이름의 약자
%A | 요일 이름
%b | 월 이름의 약자
%B | 월 이름
%c | 지역 날짜와 시간
%d | 날짜
%H | 시간 (24시간)
%I | 시간 (12시간)
%j | 1월 1일 이후의 날짜
%m | 월
%M | 분
%p | AM, PM
%S | 초
%w | 요일
%x | 지역 날짜
%X | 지역 시간
%y | 연도
%Y | 연도(4자리수)
%% | 퍼센트 기호
어기까지의 내용만 가지고 예제를 확인해보자. 함수 여럿 좀 써보겠다고 해서 자잘하게 해봤다.
리눅스 시스템 앞에 앉아 있다면 시계가 없어도 date 명령어를 이용하여 현재의 시간을 정확히 알 수 있다. 라이브러리에서는 이렇게 날짜와 시간 관련 함수를 제공하고 있으므로 이를 이용하면 date 명령어와 같이 시스템의 현재 시간을 알아내는 프로그램을 간단하게 구현할 수 있다.
또한 이러한 날짜와 시간 함수를 이용하면 현재 시간을 알 수 있을 뿐만 아니라 사용자들이 보기 좋게 변환하거나 시간차를 구할 수도 있다.
날짜와 시간은 프로그램에서 여러모로 관리되는 기능이기 때문에 날짜와 시간 함수가 사용되는 경우는 많이 존재한다.
수학 함수는 몇몇 특정한 성질이 있는 함수가 아닌 경우에는 그냥 직접 보고 실행해 보면 되는 함수들이 많이 있다. 게다가 기초적인 수학을 할 줄 안다는 전재로 있기 때문에 별도로 수학에 대한 설명은 더 이상 필요가 없다. 따라서 수학 함수 중에서도 좀 자주 이용되는 몇 가지 함수들에 대해서 이름과 기능만 좀 적어보겠다.
난수 함수에 대해서는 여러곳에서 말들이 많아서 그런지 다들 그냥 들어봤다라고 해서 유명하다. rand 함수에 대해서 주로 그렇게 이야기를 하는데, 난수 함수를 쓰는데 있어서 주의해야 할 점이 있다.
기본적으로 난수를 만들기 위해서는 rand와 srand 함수를 사용하면 된다. rand함수는 0과 RAND_MAX 사이의 난수를 생성하고 srand는 해당되는 seed를 초기화 하기 때문에 rand함수가 생성하는 난수가 달라지게 된다.
함수 이름 | 기능
rand | 난수를 생성한다.
srand | rand를 초기화한다.
가장 기본적인 예시부터 살펴보겠다. srand로 처음 seed를 정해서 생성한 다음, 난수를 생성해서 100으로 나눈 나머지를 출력해서 0~99까지 출력한다.
여기서 보면 프로그램을 여러 번 실행해도 똑같은 난수를 계속 생성하는 것을 볼 수 있다. 즉, seed가 고정된 상태에서는 동일한 난수밖에 생성되지 않는다.
이를 해결하기 위해서는 시간과 연동을 해야 한다. 시스템 타이머는 클락 단위로 세세하게 처리되기 때문에 프로그램 실행 때마다 항상 다른 seed로 만들어 낼 수 있다. 그래서 seed값을 유용하게 만들어서 이용할 수 있고, 이렇게 하면 실행할 때마다 rand 함수가 전부 다른 난수를 생성하게 된다.