아래 코드는 제 나름대로 코드를 보고 온도정보만 알아내려 시도해보았습니다. 잘 안될꺼 같다고 예상은 했지만 역시 안되는군요 :oops:
i8k_smm(SMMRegisters *regs) 함수까지는 잘들어가집니다만
asm(.....)에서 세그멘테이션 오류가 납니다.
어떤 부분을 알아보면 좋을까요? 제가 급하기도 하고 허접하기도 해서요....그저 난감하기만 합니다 무엇을 보아야 할지도 모르겠네요....그리고 에러가 나는 이유는 무엇일까요?
환경은 다음과 같습니다.
cpu : 펜티엄 4
os : 레드햇 9
gcc : gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
#include <stdio.h>
//#include "uaccess.h"
#include <asm/io.h>
#define I8K_SMM_GET_TEMP 0x10a3
#define I8K_MAX_TEMP 127
typedef struct {
unsigned int eax;
unsigned int ebx __attribute__ ((packed));
unsigned int ecx __attribute__ ((packed));
unsigned int edx __attribute__ ((packed));
unsigned int esi __attribute__ ((packed));
unsigned int edi __attribute__ ((packed));
} SMMRegisters;
static int i8k_smm(SMMRegisters *regs)
{
int rc;
int eax = regs->eax;
printf("hi\n");
asm("pushl %%eax\n\t" \
"movl 0(%%eax),%%edx\n\t" \
"push %%edx\n\t" \
"movl 4(%%eax),%%ebx\n\t" \
"movl 8(%%eax),%%ecx\n\t" \
"movl 12(%%eax),%%edx\n\t" \
"movl 16(%%eax),%%esi\n\t" \
"movl 20(%%eax),%%edi\n\t" \
"popl %%eax\n\t" \
"out %%al,$0xb2\n\t" \
"out %%al,$0x84\n\t" \
"xchgl %%eax,(%%esp)\n\t"
"movl %%ebx,4(%%eax)\n\t" \
"movl %%ecx,8(%%eax)\n\t" \
"movl %%edx,12(%%eax)\n\t" \
"movl %%esi,16(%%eax)\n\t" \
"movl %%edi,20(%%eax)\n\t" \
"popl %%edx\n\t" \
"movl %%edx,0(%%eax)\n\t" \
"lahf\n\t" \
"shrl $8,%%eax\n\t" \
"andl $1,%%eax\n" \
: "=a" (rc)
: "a" (regs)
: "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) {
return 0;
printf("hi2\n");
}
return 0;
}
static int i8k_get_cpu_temp(void)
{
SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
int rc;
int temp;
#ifdef I8K_TEMPERATURE_BUG
static int prev = 0;
#endif
regs.eax = I8K_SMM_GET_TEMP;
if ((rc=i8k_smm(®s)) < 0) {
return rc;
}
temp = regs.eax & 0xff;
#ifdef I8K_TEMPERATURE_BUG
/*
* Sometimes the temperature sensor returns 0x99, which is out of range.
* In this case we return (once) the previous cached value. For example:
# 1003655137 00000058 00005a4b
# 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
# 1003655139 00000054 00005c52
*/
if (temp > I8K_MAX_TEMP) {
temp = prev;
prev = I8K_MAX_TEMP;
} else {
prev = temp;
}
#endif
return temp;
}
int main()
{
int test=0;
test = i8k_get_cpu_temp();
printf("%d",test);
return 0;
}
BIOS는 H/W Monitor을 조작해서 얻은 정보를 뿌려주는 것이니까
ACPI를 통하여 이용하시거나
H/W Monitor를 직접 조작해서
정보를 얻는 방법 외에는 없을 것 같은데요 ^^
Dell Laptop에서 CPU 온도 및 Fan을 제어하기 위해, BIO
Dell Laptop에서 CPU 온도 및 Fan을 제어하기 위해, BIOS 정보를 이용합니다. kernel의 drivers/char/i8k.c를 참고하면 도움이 될 것 같습니다.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
안타깝게도 SMM의 SMRAM 아랫쪽에는 ACPI Table가 있는 경우가
바이오스마다 SMM에 대한 구현이 서로 달라서
잘못하면 시스템을 재부팅할 가능성도 있을것 같아요 ㅠ.ㅠ
답변에 감사드립니다.
답변에 정말 감사드립니다..
하지만 저의 능력이 너무 낮아서 이해하기가 너무 힘드네요.
아래 코드는 제 나름대로 코드를 보고 온도정보만 알아내려 시도해보았습니다. 잘 안될꺼 같다고 예상은 했지만 역시 안되는군요 :oops:
i8k_smm(SMMRegisters *regs) 함수까지는 잘들어가집니다만
asm(.....)에서 세그멘테이션 오류가 납니다.
어떤 부분을 알아보면 좋을까요? 제가 급하기도 하고 허접하기도 해서요....그저 난감하기만 합니다 무엇을 보아야 할지도 모르겠네요....그리고 에러가 나는 이유는 무엇일까요?
환경은 다음과 같습니다.
cpu : 펜티엄 4
os : 레드햇 9
gcc : gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
좋은 하루되세용~~
May The Force Be With You
irdeal
댓글 달기