中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-09-14 22:30
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 有没有研究 FDAPM 关机的朋友。 查看 3,605 回复 7
楼 主 有没有研究 FDAPM 关机的朋友。 发表于 2010-08-17 16:28 ·  中国 北京 联通
高级用户
★★
积分 506
发帖 187
注册 2005-12-04 22:41
20年会员
UID 46500
性别 男
状态 离线
由于这次遇到了 在dos下无法关机的现象。
最终找到了 FDAPM。是可以用ACPI关机的(我我想应该是这样的)
想把他的那些搞明白。
可惜我的汇编能力较弱。有很多地方看的迷迷糊糊。
有愿意搞这个的,我们一起研究他的代码。
源代码我这里有。

愿意的跟帖啊。
2 发表于 2010-08-24 17:44 ·  中国 北京 联通
高级用户
★★
积分 506
发帖 187
注册 2005-12-04 22:41
20年会员
UID 46500
性别 男
状态 离线
我一边看代码,一般尝试用C写代码。

目前遇到的一个难题是。

我需要读取线性地址为 3FF40000 处的值。
但是用int 0x15 ,ah = 0x87,用int86x()来读取,确读到的值是0.

有什么更好的方法没啊??

谢谢!
3 发表于 2010-08-24 23:33 ·  中国 北京 联通
高级用户
★★
积分 506
发帖 187
注册 2005-12-04 22:41
20年会员
UID 46500
性别 男
状态 离线
unsigned char TheBuffer[50];
unsigned char Buffer[20];

//参数seg在这里是高16位,offset是低16位,需要取得值在他们表示的后16字节后。
int fetch_high(unsigned int seg,unsigned int offset)
{
unsigned int i;
union REGS in,out;
struct SREGS segregs;

//GDT的前16字节和后16字节。
for(i=0;i<16;i++)
{
TheBuffer[i] = 0;
TheBuffer[0x20 + i] = 0;
}

TheBuffer[0x10]=16;
TheBuffer[0x11]=0;
TheBuffer[0x12]=peekb(seg,offset + 0x10);//低16位中的低8位 值00
TheBuffer[0x13]=peekb(seg,offset + 0x11);//低16位中的高16位 值00
TheBuffer[0x14]=peekb(seg,offset + 0x12);//高16位中的低8位 值FF
TheBuffer[0x15]=0x93;//权限
TheBuffer[0x16]=0;
TheBuffer[0x17]=peekb(seg,offset + 0x13);//高16位中的高8位 值03

TheBuffer[0x18]=16;
TheBuffer[0x19]=0;
i = FP_OFF(Buffer);//想把高端的内存数值复制到本地的数组内
TheBuffer[0x1A]=i & 0xFF;
TheBuffer[0x1B]=i & 0xFF00;

i = FP_SEG(Buffer);
TheBuffer[0x1C]=i & 0xFF;

TheBuffer[0x1D]=0x93;
TheBuffer[0x1E]=0;
TheBuffer[0x1F]=i & 0xFF00;

segregs.es = FP_SEG(TheBuffer);
in.x.si = FP_OFF(TheBuffer);
in.h.ah = 0x87;
in.x.cx = 8;

//以下显示信息为了校验测试。
for(i=0;i<16;i++)
printf("%2x ",TheBuffer[i]);
printf("\n");
for(i=0;i<16;i++)
printf("%2x ",TheBuffer[0x10 + i]);
printf("\n");
for(i=0;i<16;i++)
printf("%2x ",TheBuffer[0x20 + i]);
printf("\n");


int86x(0x15, &in, &out, &segregs);

if(out.x.cflag == 1)
{
printf("fetch_high error \n");
return 0;//error
}

for(i=0;i<16;i++)
printf("%2x ",Buffer[i]);

return 1;

}
4 发表于 2010-08-25 09:33 ·  中国 北京 联通
高级用户
★★
积分 506
发帖 187
注册 2005-12-04 22:41
20年会员
UID 46500
性别 男
状态 离线
问题已经解决:
谢谢各位!
5 发表于 2010-09-07 14:42 ·  中国 北京 门头沟区 光环新网联通数据中心
高级用户
★★
积分 506
发帖 187
注册 2005-12-04 22:41
20年会员
UID 46500
性别 男
状态 离线
今天遇到了惠普 400 wrokstation

居然 fdapm 都不能关。

郁闷啊。。。。。。
6 发表于 2010-09-16 12:08 ·  中国 广东 汕头 电信
银牌会员
★★★
积分 1,451
发帖 446
注册 2002-10-20 00:00
23年会员
UID 29
性别 男
状态 离线
现在不少主板fdapm都不能关了,所以现在比较好用的方法是直接按电源开关。希望楼主能够改造出一个更好用的关机软件。
7 发表于 2010-09-28 16:22 ·  中国 北京 联通
高级用户
★★
积分 506
发帖 187
注册 2005-12-04 22:41
20年会员
UID 46500
性别 男
状态 离线
嗯,我相信会解决的。

我现在正在致力于此。
8 就当水一贴 发表于 2023-08-08 19:04 ·  中国 北京 华为云
初级用户
积分 34
发帖 15
注册 2018-12-28 19:36
7年会员
UID 183309
性别 男
状态 离线
GRUB4DOS 的 halt 是能关机的。但是它毕竟是启动器而不是电源管理程序。虽然可以在 DOS 下用命令行运行,但是颇有些杀鸡用牛刀的感觉。

在源代码中 sage2/asm.S 找 grub_halt 是关机代码。

然而我不会汇编(逃)

传言正常靠谱操作 ACPI 需要写虚拟机什么的,但 GRUB4DOS 的不像有这类东西。

希望 fdapm 更新。

[ Last edited by asdfq on 2023-8-8 at 19:07 ]
论坛跳转: