본문 바로가기
Research/SystemProg

커널에서 double형의 연산이 가능한가요?

by sunnyan 2002. 12. 4.
728x90
출처 : http://linuxkernel.net 게시판


--------------------------------------------------------------------------------

2002/09/19 (16:35) from 211.38.3.65' of 211.38.3.65'  Article Number : 5920  
  정지호  Access : 18 , Lines : 31  
커널에서 double형의 연산이 가능한가요?  
혹시 시도해 보신분 안계세요?
커널 소스에서 double형을 사용한곳을 찾아 보니깐..
드라이버 쪽에서 몇개가 나오고 나머지는 없더군요...
아래 코드의 수행 결과가 이상합니다.

=============================================
double dd = 100.0;
double dd2 = 33.3;
int ii;

if (dd <= 0.0)
printk("dd is zeron");
else
printk("dd is not zeron");

ii = dd/dd2;

printk("res=%dn", ii);
===============================================
수행결가
===============================================
dd is zero  
res=0      


결과를 보면 double형 연산이 안됩니다.

혹시 아시는분 좀 알려 주세요...

감사합니다.




--------------------------------------------------------------------------------

2002/09/19 (16:40) from 211.38.3.65' of 211.38.3.65'  Article Number : 5921  
  정지호  Access : 26 , Lines : 7  
[내용추가]  커널에서 double형의 연산이 가능한가요?  
Makefile에 아래의 내용을 넣어야 컴파일이 되더군요..

LIBGCC := $(shell $(CROSS_COMPILE)gcc --print-libgcc-file-name)

$(LIBGCC)를 적당한 위치에 추가하면 됩니다.




--------------------------------------------------------------------------------

2002/09/20 (02:44) from 63.220.67.67' of 63.220.67.67'  Article Number : 5923  
  이호 (flyduck@linuxkernel.net)  Access : 38 , Lines : 53  
Re: 커널에서 double형의 연산이 가능한가요?  

원칙적으로 커널에서 floating point 연산을 할 수 없습니다. 이것은
규칙입니다. 요새는 모든 CPU에 실수연산을 담당하는 FPU가 있고,
floating point 연산은 이 FPU를 이용합니다. 그리고 이런 연산이
일어날 때마다 FPU register를 조작하게 됩니다. 문제는 커널에서
mode switching이 일어날 때 이 레지스터를 저장하지 않습니다.

따라서 user process에서 실수 연산을 하는 도중에 시스템 콜이나
인터럽트 등으로 커널 모드에 진입을 하고, 커널에서 FPU 레지스터를
바꾼후 그냥 사용자 모드로 되돌아왔다면 사용자 프로그램은 엉뚱한
결과를 낳을 수 있습니다. 눈으로 확인하기는 쉽지 않겠지만요.
그래서 실수 연산과 관련해서는...

- init_module() 처럼 전혀 위험이 없는 곳에 사용하거나 (insmod
프로그램이 실수 연산을 사용하지 않으므로)
- 실수연산후 FPU 레지스터의 값을 복구하거나
- software emulation (FPU를 사용하지 않고 소프트웨어적인 실수계산)

을 해야 합니다. MMX 명령어도 마찬가지죠.



--------------------------------------------------------------------------------

2002/09/23 (17:48) from 211.38.3.65' of 211.38.3.65'  Article Number : 5931  
  정지호  Access : 30 , Lines : 93  
해결...했습니다.  
답변감사합니다.

질문의 코드는 커널 컴파일 할때 -msoft-float 옵션을 켜고
컴파일 할때의 결과 입니다.
그리고 CPU가 FPU가 없는 임베디드 CPU(IBM405GP) 였습니다.
(정보가 정확하지 않았죠 ^^)

원인을 추적하던중 gcc 컴파일러의 컴파일러 소스에 버그인지 아닌지 모르겠는
문제의 코드가 있어 수정을 했습니다.

문제의 코드는 libgcc.a를 만드는 소스(soft-float emulation 코드)
floatlib.c파일의 double형의 equal(not equal)연산을 하는 코드

int
__eqdf2 (double a1, double a2)
{
   //return *(long long *) &a1 == *(long long *) &a2;
   return (__cmpdf2 ((float) a1, (float) a2) != 0);
}

였습니다.

막힌 부분이 원래 코드 입니다.

수정하고 나니...
원래의 코드가 다른 CPU에서는 동작하는지 궁금한데..
여유가 없어서 테스트를 못해본 상태 입니다.
(이상타....혹시 i386계열에서는 문제가 없는거 아닌지..
.. 아~~~ 인텔은 위의 코드를 사용안한다.. 왜~~ FPU가 있으니깐... ^^)
여튼 이렇게 처리하니 문제가 없더군요...

수고하세요..

728x90

'Research > SystemProg' 카테고리의 다른 글

가상 메모리  (0) 2004.06.07
커널 디버깅 기능 활성화과정  (0) 2004.06.06
압축 해제 이후 커널 패치 과정  (0) 2004.06.06
[Q] relocation of bss and data  (0) 2003.12.10
Glabl변수의 초기화 및 영역  (0) 2003.12.01