मैं इंटेल के x86 आर्किटेक्चर के आधार पर एक संरक्षित-मोड ओएस बना रहा हूं, और इस बारे में कुछ जानकारी ढूंढ रहा था कि कंप्यूटर को असेंबली कोड, या ऐसा कुछ कैसे करें। क्या आप इस समस्या में मेरी सहायता करेंगे?एक फ्रीस्टैंडिंग पर्यावरण से कंप्यूटर को कैसे पावर करें?
उत्तर
ACPI बंद तकनीकी रूप से एक बहुत आसान बात की आवश्यकता होती है एक outw (PM1a_CNT, SLP_TYPa | SLP_EN) है, और कंप्यूटर बंद है। समस्या इन मानों को इकट्ठा करने में निहित है, खासकर जब से SLP_TYPa _S5 ऑब्जेक्ट में है जो डीएसडीटी में है और इसलिए एएमएल एन्कोड किया गया है।
नीचे इन फ़ील्ड को खोजने के लिए एक सरल "मानचित्र" है।
"RSD PTR " || RsdtAddress pointer at offset 16 || \/ "RSDT" || pointer at offset 36 + 4 * n (check the target for the sig "FACP" to get the right n) || \/ "FACP" || ||=====\ || || || PM1a_CNT_BLK; offset: 64 (see section 4.7.3.2) || PM1b_CNT_BLK; offset: 68 || || || \/ || SLP_TYPx; bit 10-12 || SLP_EN; bit 13 || DSDT pointer at offset 40 || \/ "DSDT" (export the \_S5 object somehow.)
\_S5
वस्तु एक सामान्य रूप से एक एएमएल दुभाषिया का प्रयोग करेंगे निर्यात करने के लिए, लेकिन यह स्पष्ट रूप से हम एक शौक ओएस का निर्माण कर रहे पर विचार के लिए एक विकल्प नहीं है। सरल समाधान डीएसडीटी को मैन्युअल रूप से स्कैन करना है। एएमएल भाषा निर्दिष्ट करती है कि _... वस्तुओं को केवल एक बार परिभाषित किया जाता है जो \_S5
ऑब्जेक्ट को खोजने के लिए बहुत आसान बनाता है क्योंकि एक सरल memcmp()
पर्याप्त है। एक बार पाया गया कि SLP_TYPx
मान निकाले गए हैं। क्योंकि के बाद कि आप राम का पुन: उपयोग कर सकते हैं और यह भ्रष्ट बारे में चिंता करने की जरूरत नहीं है
bytecode of the \_S5 object ----------------------------------------- | (optional) | | | | NameOP | \ | _ | S | 5 | _ 08 | 5A | 5F | 53 | 35 | 5F ----------------------------------------------------------------------------------------------------------- | | | (SLP_TYPa ) | (SLP_TYPb ) | (Reserved ) | (Reserved ) PackageOP | PkgLength | NumElements | byteprefix Num | byteprefix Num | byteprefix Num | byteprefix Num 12 | 0A | 04 | 0A 05 | 0A 05 | 0A 05 | 0A 05 ----this-structure-was-also-seen---------------------- PackageOP | PkgLength | NumElements | 12 | 06 | 04 | 00 00 00 00
जानकारी की भीड़ सबसे अच्छा ओएस प्रारंभ में किया जाता है।
अब यह सब बनी हुई है outw(PM1a_CNT, SLP_TYPa | SLP_EN);
और आप चले गए हैं। यदि PM1b_CNT != 0
आपको इसे बी के साथ दोहराना होगा।
हैं कि एक छोटे से यहाँ भी सार कुछ कोड
//
// here is the slighlty complicated ACPI poweroff code
//
#include <stddef.h>
#include <print.h>
#include <string.h>
#include <io.h>
#include <time.h>
dword *SMI_CMD;
byte ACPI_ENABLE;
byte ACPI_DISABLE;
dword *PM1a_CNT;
dword *PM1b_CNT;
word SLP_TYPa;
word SLP_TYPb;
word SLP_EN;
word SCI_EN;
byte PM1_CNT_LEN;
struct RSDPtr
{
byte Signature[8];
byte CheckSum;
byte OemID[6];
byte Revision;
dword *RsdtAddress;
};
struct FACP
{
byte Signature[4];
dword Length;
byte unneded1[40 - 8];
dword *DSDT;
byte unneded2[48 - 44];
dword *SMI_CMD;
byte ACPI_ENABLE;
byte ACPI_DISABLE;
byte unneded3[64 - 54];
dword *PM1a_CNT_BLK;
dword *PM1b_CNT_BLK;
byte unneded4[89 - 72];
byte PM1_CNT_LEN;
};
// check if the given address has a valid header
unsigned int *acpiCheckRSDPtr(unsigned int *ptr)
{
char *sig = "RSD PTR ";
struct RSDPtr *rsdp = (struct RSDPtr *) ptr;
byte *bptr;
byte check = 0;
int i;
if (memcmp(sig, rsdp, 8) == 0)
{
// check checksum rsdpd
bptr = (byte *) ptr;
for (i=0; i<sizeof(struct RSDPtr); i++)
{
check += *bptr;
bptr++;
}
// found valid rsdpd
if (check == 0) {
/*
if (desc->Revision == 0)
wrstr("acpi 1");
else
wrstr("acpi 2");
*/
return (unsigned int *) rsdp->RsdtAddress;
}
}
return NULL;
}
// finds the acpi header and returns the address of the rsdt
unsigned int *acpiGetRSDPtr(void)
{
unsigned int *addr;
unsigned int *rsdp;
// search below the 1mb mark for RSDP signature
for (addr = (unsigned int *) 0x000E0000; (int) addr<0x00100000; addr += 0x10/sizeof(addr))
{
rsdp = acpiCheckRSDPtr(addr);
if (rsdp != NULL)
return rsdp;
}
// at address 0x40:0x0E is the RM segment of the ebda
int ebda = *((short *) 0x40E); // get pointer
ebda = ebda*0x10 &0x000FFFFF; // transform segment into linear address
// search Extended BIOS Data Area for the Root System Description Pointer signature
for (addr = (unsigned int *) ebda; (int) addr<ebda+1024; addr+= 0x10/sizeof(addr))
{
rsdp = acpiCheckRSDPtr(addr);
if (rsdp != NULL)
return rsdp;
}
return NULL;
}
// checks for a given header and validates checksum
int acpiCheckHeader(unsigned int *ptr, char *sig)
{
if (memcmp(ptr, sig, 4) == 0)
{
char *checkPtr = (char *) ptr;
int len = *(ptr + 1);
char check = 0;
while (0<len--)
{
check += *checkPtr;
checkPtr++;
}
if (check == 0)
return 0;
}
return -1;
}
int acpiEnable(void)
{
// check if acpi is enabled
if ((inw((unsigned int) PM1a_CNT) &SCI_EN) == 0)
{
// check if acpi can be enabled
if (SMI_CMD != 0 && ACPI_ENABLE != 0)
{
outb((unsigned int) SMI_CMD, ACPI_ENABLE); // send acpi enable command
// give 3 seconds time to enable acpi
int i;
for (i=0; i<300; i++)
{
if ((inw((unsigned int) PM1a_CNT) &SCI_EN) == 1)
break;
sleep(10);
}
if (PM1b_CNT != 0)
for (; i<300; i++)
{
if ((inw((unsigned int) PM1b_CNT) &SCI_EN) == 1)
break;
sleep(10);
}
if (i<300) {
wrstr("enabled acpi.\n");
return 0;
} else {
wrstr("couldn't enable acpi.\n");
return -1;
}
} else {
wrstr("no known way to enable acpi.\n");
return -1;
}
} else {
//wrstr("acpi was already enabled.\n");
return 0;
}
}
//
// bytecode of the \_S5 object
// -----------------------------------------
// | (optional) | | | |
// NameOP | \ | _ | S | 5 | _
// 08 | 5A | 5F | 53 | 35 | 5F
//
// -----------------------------------------------------------------------------------------------------------
// | | | (SLP_TYPa ) | (SLP_TYPb ) | (Reserved ) | (Reserved )
// PackageOP | PkgLength | NumElements | byteprefix Num | byteprefix Num | byteprefix Num | byteprefix Num
// 12 | 0A | 04 | 0A 05 | 0A 05 | 0A 05 | 0A 05
//
//----this-structure-was-also-seen----------------------
// PackageOP | PkgLength | NumElements |
// 12 | 06 | 04 | 00 00 00 00
//
// (Pkglength bit 6-7 encode additional PkgLength bytes [shouldn't be the case here])
//
int initAcpi(void)
{
unsigned int *ptr = acpiGetRSDPtr();
// check if address is correct (if acpi is available on this pc)
if (ptr != NULL && acpiCheckHeader(ptr, "RSDT") == 0)
{
// the RSDT contains an unknown number of pointers to acpi tables
int entrys = *(ptr + 1);
entrys = (entrys-36) /4;
ptr += 36/4; // skip header information
while (0<entrys--)
{
// check if the desired table is reached
if (acpiCheckHeader((unsigned int *) *ptr, "FACP") == 0)
{
entrys = -2;
struct FACP *facp = (struct FACP *) *ptr;
if (acpiCheckHeader((unsigned int *) facp->DSDT, "DSDT") == 0)
{
// search the \_S5 package in the DSDT
char *S5Addr = (char *) facp->DSDT +36; // skip header
int dsdtLength = *(facp->DSDT+1) -36;
while (0 < dsdtLength--)
{
if (memcmp(S5Addr, "_S5_", 4) == 0)
break;
S5Addr++;
}
// check if \_S5 was found
if (dsdtLength > 0)
{
// check for valid AML structure
if ((*(S5Addr-1) == 0x08 || (*(S5Addr-2) == 0x08 && *(S5Addr-1) == '\\')) && *(S5Addr+4) == 0x12)
{
S5Addr += 5;
S5Addr += ((*S5Addr &0xC0)>>6) +2; // calculate PkgLength size
if (*S5Addr == 0x0A)
S5Addr++; // skip byteprefix
SLP_TYPa = *(S5Addr)<<10;
S5Addr++;
if (*S5Addr == 0x0A)
S5Addr++; // skip byteprefix
SLP_TYPb = *(S5Addr)<<10;
SMI_CMD = facp->SMI_CMD;
ACPI_ENABLE = facp->ACPI_ENABLE;
ACPI_DISABLE = facp->ACPI_DISABLE;
PM1a_CNT = facp->PM1a_CNT_BLK;
PM1b_CNT = facp->PM1b_CNT_BLK;
PM1_CNT_LEN = facp->PM1_CNT_LEN;
SLP_EN = 1<<13;
SCI_EN = 1;
return 0;
} else {
wrstr("\\_S5 parse error.\n");
}
} else {
wrstr("\\_S5 not present.\n");
}
} else {
wrstr("DSDT invalid.\n");
}
}
ptr++;
}
wrstr("no valid FACP present.\n");
} else {
wrstr("no acpi.\n");
}
return -1;
}
void acpiPowerOff(void)
{
// SCI_EN is set to 1 if acpi shutdown is possible
if (SCI_EN == 0)
return;
acpiEnable();
// send the shutdown command
outw((unsigned int) PM1a_CNT, SLP_TYPa | SLP_EN);
if (PM1b_CNT != 0)
outw((unsigned int) PM1b_CNT, SLP_TYPb | SLP_EN);
wrstr("acpi poweroff failed.\n");
}
को देखने के लिए अधिक जानकारी के लिए ACPI 1.0a विनिर्देश
9.1.7 Transitioning from the Working to the Soft Off State 7.5.2 \_Sx states 7.4.1 \_S5 4.7.2.3 Sleeping/Wake Control 16.3 AML Byte Streeam Byte Values 16.2.3 Package Length Encoding
यह के सभी पर काम करता है की इसी वर्गों पढ़ा है था मेरी मशीन बोच और क्यूमु। लेकिन मैंने देखा कि पीसी को बिजली के लिए एसीपीआई सक्षम करने की आवश्यकता नहीं है। हालांकि मुझे नहीं पता कि यह हमेशा मामला है या नहीं।
यदि आप बस थोड़ा खेलना चाहते हैं। Bochs के लिए और उस पर qemu-system-i386
2.0.0 Ubuntu 14.04 परीक्षण किया outw(0xB004, 0x0 | 0x2000);
APM विधि है QEMU:
mov $0x5301, %ax
xor %bx, %bx
int $0x15
/* Try to set apm version (to 1.2). */
mov $0x530e, %ax
xor %bx, %bx
mov $0x0102, %cx
int $0x15
/* Turn off the system. */
mov $0x5307, %ax
mov $0x0001, %bx
mov $0x0003, %cx
int $0x15
सटीक संकलन और QEMU पर चल रहे चरणों के लिए, see this repo
osdev.org लेख : http://wiki.osdev.org/Shutdown, http://wiki.osdev.org/APM
ACPI नई, बेहतर विधि है।
- 1. होमब्री पर्यावरण को किसी अन्य कंप्यूटर पर माइग्रेट कैसे करें?
- 2. आप एक फ्रीस्टैंडिंग सी ++ प्रोग्राम कैसे बनाते हैं?
- 3. ए/सी पावर उपलब्ध होने पर स्वचालित रूप से कंप्यूटर चालू करें
- 4. पावर
- 5. तेजी से एक Linux कंप्यूटर
- 6. उपयोगकर्ता के कंप्यूटर से छवि को कैसे लोड करें
- 7. हेड फोन जैक से इलेक्ट्रिक पावर कैसे प्राप्त करें?
- 8. एक कंप्यूटर से दूसरे कंप्यूटर में डेटाबेस की प्रतिलिपि कैसे करें?
- 9. एक कंप्यूटर सेवा में कंप्यूटर का नाम प्राप्त करें?
- 10. ऐप को पावर नेप
- 11. .NET उत्पादकता पावर टूल्स (पीपीटी) को अनइंस्टॉल कैसे करें?
- 12. विंडोज़ और लिनक्स कंप्यूटर के लिए सामान्य इमैक पर्यावरण कैसे स्थापित करें?
- 13. मैं खुद को एक पावर फ़ंक्शन कैसे लिख सकता हूं?
- 14. विकास पर्यावरण सेटअप कैसे स्वचालित करें?
- 15. बैश कमांड को एक कंप्यूटर से दूसरी कंप्यूटर में कॉपी करने के लिए
- 16. एक स्थानीय कंप्यूटर
- 17. किसी अन्य कंप्यूटर से phppgadmin एक्सेस करें?
- 18. रिमोट कंप्यूटर (एसएसएच + पायथन) से कंसोल आउटपुट कैसे प्राप्त करें
- 19. जीसीसी सी ++ पावर सटीकता
- 20. मैं "माइ कंप्यूटर" डायलॉग
- 21. वंडर-ट्विन पावर "आयत से ज़ूम" सक्रिय करें?
- 22. एंड्रॉइड ऐप पावर खपत
- 23. कंप्यूटर के वर्तमान वॉल्यूम स्तर को कैसे प्राप्त करें?
- 24. GoogleTest: एक परीक्षण से पर्यावरण तक पहुंच
- 25. जेट्रांसफॉर्म से पावर स्पेक्ट्रल घनत्व DoubleFFT_1D
- 26. थोड़ी देर के लिए पावर बटन दबाते समय शटडाउन से इनकार कैसे करें?
- 27. एंड्रॉइड एमुलेटर रीबूट/पावर
- 28. पर्यावरण से पहले ईवेंट कैसे कॉल करें। एक्सिट()?
- 29. सिम्बियन कंसोल एप्लिकेशन में पावर ऑफ इवेंट्स कैसे प्राप्त करें?
- 30. टीएफएस पावर टूल्स कैसे खोलें - अलर्ट एक्सप्लोरर
http://osdev.org देखने के लिए एक अच्छी जगह है ... मुझे अपने खुद के शौक ओएस में काम करने के लिए शटडाउन कोड कभी नहीं मिला है, इसलिए मैं एक अच्छा जवाब नहीं दे सकता – Earlz
संभावित डुप्लिकेट [कंप्यूटर को बंद करें असेंबली का उपयोग] [http: // stackoverflow।कॉम/प्रश्न/678458/शटडाउन-द-कंप्यूटर-उपयोग-असेंबली) या बहुत ही समान –
@ कृपया, प्रासंगिक लेकिन मुझे नहीं लगता कि यह एक सटीक डुप्लिकेट है। यह सवाल पूछता है कि इसे अपने ओएस (या एक फ्रीस्टैंडिंग पर्यावरण) से बंद करने के लिए कैसे प्राप्त करें, जहां दूसरा यह नहीं मानता .. और @ कार्लोस, आप किस प्रोसेसर मोड में हैं? रीयल-मोड, संरक्षित-मोड, या लंबी-मोड? (16 बिट, 32 बिट, या 64 बिट) – Earlz