2007년 11월 24일 - LILO External Parameter
LKSAS
김기태
test byte ptr [prompt](bp),#FLAG_MAP_ON_BOOT
우선 위 문법은 우리가 해석했던게 맞다고 하네요. ( http://kldp.org/node/88608 ) 그런데 제가 한가지 햇갈린 점이 있습니다.
- (prompt + bp)
위 문장이 prompt의 주소(여기선 0x07DB가 되겠죠? 0x07C0 + 27일테니까요..)에 bp(여기선 0)를 더한 주소(0x07DB)의 값을 나타내기 때문에 결국엔 prompt의 값이 되겠죠. 0을 더한거니까요. 그래서 결과는 prompt가 0으로 선언되어있기 때문에 0이 나올테고요. 그런데 저는 이것을 prompt의 값에 bp를 더한 주소의 값을 가져온다고 햇갈렸습니다. 그래서 *(0x07DB + 0)으로 해석해야 하는것을 *(0 + 0)으로 해석하는 실수를 한것같네요.
아무튼 위 결과대로 해석을 하면 아래 문장은 jmp를 하지않게 됩니다.
! map is on boot device for RAID1, and if so marked; viz.,
test byte ptr [prompt](bp),#FLAG_MAP_ON_BOOT jnz use_boot ! as passed in from BIOS or MBR loader
test 인스트럭션은 0과 64를 and 연산하기 때문에 결과는 0이 나오고 그래서 jnz 인스트럭션은 실행이 안되고요. 그런데 여기서 또 하나 궁금한 점은 그냥 prompt 값을 가져다 쓰면 될것 같은데 왜 복잡하게 [prompt](bp)라는 연산을 쓰는지 이해가 안되네요.
그럼 이제 start: 라벨이 시작되는 부분에서 dx, bx, es, si 레지스터에 어떤값이 들어왔는지에 대한 의문만 해결하면 될것같네요. 오늘 보셨듯이 소스 뒷 부분에서 이들 레지스터에 저장된 값에 따라 동작을 달리하는 부분이 있기 때문에 뭐가 들어있는 상태로 실행되는지 알아내는게 다음 주 스터디의 성패(?)를 좌우할것 같습니다. ^^;;
external parameter라는게 뭔지 집중적으로 조사해보면 될듯하네요.
최희욱
예.. 21버전 관련문서들만 계속 읽고 스터디 갔다가 22버전을 분석하게 되었는데, 크게 차이없을 거라 생각하고 시작했지만 21버전에는 없었던 문법이 22버전 와서는 사용하는 바람에 당황했었습니다. 그게 예상했던 것보다 오늘 진도가 많이 못 나가게 된 원인이 아니었나 싶네요..ㅋ.. ^^
김기태
정말 찾기가 힘드네요. 아마도 BIOS에 의해서 LILO 전달되는 어떠한 값들을 사용하기 위해 external parameter라는걸 사용하게 아닌가 싶습니다. 그리고 DL 레지스터가 0xFE 값을 가지고 있으면 external parameter가 있는것으로 간주해서 나머지 3개의 레지스터에서 값을 읽어서 사용하구요.
그리고 boot parameter 부분이요. _main에서 jump하는 코드 바로 다음부터 start: 라벨이 나오기까지 정의되는 데이터들이요. 이게 컴파일 타임에서는 그냥 공간만 할당하고 실제 값은 LILO가 설치될때 들어간다고 하네요.
그래서 실제 들어가는 값을 보고 분석을 하려면 LILO를 실제로 설치한 시스템의 MBR을 아래와 같이 빼내서 분석해야할것 같습니다.
- dd if=/dev/hda of=/tmp/mbr.txt bs=1 count=512
혹시 LILO가 설치된 시스템 가지고 계신분 있나요? 없으면 vmware에 하나 설치해서 해봐야겠네요. 가장 최근에 나온 우분투 것시(?)인가요? 이놈도 GRUB 대신 LILO 설치가 가능한가요?
신철수
리눅스 배포판 중에 slackware 라는 배포판에 쓰이는 기본적인 부트로더가 lilo 입니다. 제가 지금 잠시 확인한 결과 slackware 배포판 최신 버젼인 slackware-12 버젼의 시디 이미지 안의 lilo 버젼이 22.8 인걸로 보아 slackware-12를 설치하면 저희가 원하는 것에 조금 더 가까이 가질 수 있을 것 같습니다.
집에서 가상으로 slackware-12 설치해서 좀 봐야겠네요. 슬렉웨어 공식 주소는 "http://www.slackware.org/" 입니다.
ps: 개인적으로 좀 깨작거려 볼려는 장비에 slackware 설치해야하는데 새로 산 노트북 hdd가 제대로 맛이 가버렸네요. 스팀 팍팍 ㅜ_ㅜ
이동원
아래 링크를 보시면,
! external parameter와의 인터페이스를 위한 register저장 영역 ! DL -> 0xFE 로 설정되어 external parameter이 유무파악에 사용 ! ES:SI -> "LILO" 스트링에 대한 포인터 ! ES:BS -> external command line에 대한 포인터
이런 내용이 있는데요. 바이오스에서 0xFE가 자동으로 넘어와서 DX에 들어간다는 뜻인거 같기도 한데, 저는 읽어봐도 무슨 뜻인지 잘 모르겠습니다. -_-ㅋ
http://sikiprog.tistory.com/tag/LILO
최희욱
제가 lilo 분석 시작하고 나름대로 이리저리 머리 굴려서 결론내렸습니다..ㅋ.. 앞으로 쓸 글을 보실때는 정확한 답이 아닐 수 있으니 다시 말씀드리면 저만의 생각일지도 모르니 감안하고 "참고만 해야지" 하는 생각으로 읽어주세요..ㅋㅋ
LILO 소스에 보시면 처음부분에 인터럽트 금지시켰다가 해제하고 PUSH DX, PUSH BX, PUSH ES, PUSH SI하는 부분이 있습니다. 이 두 동작 사이에 external parameter가 들어옵니다 (잠시 사설로 말씀드리면, external parameter 설명은 john코푸만 아저씨가 배포하는 http://lilo.go.dyndns.org/ 의 21version doc폴더의 tech.pdf라는 문서의 7~8페이지에 configuration parameter절에 나온 정도의 얘기가 다인 거 같습니다.) DX는 Configuration parameter 형태를 구분짓는 레지스터구요, (DL이 fe값을 가지고 있으면 External parameter죠) BX는 들어온 순서를 구분짓기 위해 푸시하는 레지스터입니다. 그리고 ES와 SI가 현재 동작하고 있는 디바이스(예를 들면 하드)의 주소 즉, Operand segment와 offset이 되어서 그때 그때 필요한 동작이 있는 주소를 알려주게 됩니다. 그때 그때 필요한 동작의 예를 들면, 21.7버전에서는 lilo 문자열 비교라든지 22.8버전에서는 정상동작(매직넘버 5a5a로 확인)하는 second.s의 코드가 들어있는 디바이스의 주소등을 나타내는 거죠, 다른분들이 분석하신 내용은 아마도 21.7버전을 분석한 내용으로 보입니다. 그러니 주석에도 lilo 스트링에 대한 포인터라고 사용한 것으로 보이고요, 22.8버전에서는 scasb라는 명령을 사용해서 lilo 스트링에 문자열 비교를 했네요. 그리고 second.s로 분기할 때도 jmpi를 사용한 것이 아니라 retf를 사용했습니다..^^;
p.s INTEL 매뉴얼에 오자가 있어서 retf로 찾다가 완전 낭패봤어요.. 이눔의 삽질은 ..--;
김기태
LILO 분석이 끝난 시점에서 생각해보면 external parameter는 커널로 전달할 option parameter가 LILO 코드 상에서 사용자에 의해 입력된 값이 아니라, LILO 시작 전 단계에서 넘어온 값을 커널로 전달하기 위해 사용하는것 같습니다. 어떤 경우에 이런게 사용되는지는 모르겠지만 LILO의 전 단계라하면 BIOS인데, BIOS가 직접 커널에 어떤 값을 전달하는 경우가 있을까요?
