VYRESENO: Shutdown pres ACPI
Ladislav Vaiz
ziav na adela.fel.zcu.cz
Čtvrtek Říjen 4 08:31:34 CEST 2001
Ahoj všem,
protože se vyskytlo více zájemců ohledně vypínání počítače přes ACPI,
posílám své zkušenosti také do konference.
Nejprve se ale omluvám za týdenní zpoždění zaviněné chřipkou.
Aby bylo od začátku jasno, nejsem žádný odborník na ACPI, nečetl jsem
ACPI-HOWTO a nevím co znamená S0 nebo S5. Dále uvedené informace jsou
pouze postup, jak jsem dosáhl toho, že se počítač downuje POWER
tlačítkem.
Mám desku Microstar K7T Pro2, procesor Duron, zdroj ATX, výrobce neznámý.
V nastavemí BIOSu jsem nic neměnil, důvod viz výše. Je tam:
ACPI Sleep Type S1(POS)
PM Control by APM Yes
Soft Off by PWRBTN Instant-Off
Poslední řádka je zajímavá, počítač se opravdu okamžitě vypne. Pokud se
načte linux, tak se vypne až po několika sekundách.
Konfigurace jádra.
grep -iE 'acpi|apm' /usr/src/linux-2.4.9/.config :
CONFIG_ACPI=y
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_BUSMGR=y
CONFIG_ACPI_SYS=y
# CONFIG_ACPI_CPU is not set
CONFIG_ACPI_BUTTON=y
# CONFIG_ACPI_AC is not set
# CONFIG_ACPI_EC is not set
CONFIG_APM=m
# CONFIG_APM_IGNORE_USER_SUSPEND is not set
# CONFIG_APM_DO_ENABLE is not set
# CONFIG_APM_CPU_IDLE is not set
# CONFIG_APM_DISPLAY_BLANK is not set
# CONFIG_APM_RTC_IS_GMT is not set
# CONFIG_APM_ALLOW_INTS is not set
# CONFIG_APM_REAL_MODE_POWER_OFF is not set
modul apm není zaveden.
Dále grep -i 'acpi' /var/log/dmesg :
BIOS-e820: 0000000007ff0000 - 0000000007ff3000 (ACPI NVS)
BIOS-e820: 0000000007ff3000 - 0000000008000000 (ACPI data)
Kernel command line: root=/dev/hda5 vga=4 acpi=no-idle
ACPI: Core Subsystem version [20010615]
ACPI: Subsystem enabled
ACPI: System firmware supports S0 S1 S5
a ještě:
Power Button: found
Power Button: found (fakt, 2x)
Sleep Button: found
Výpis 'tree -a /proc/acpi' :
/proc/acpi
|-- button
| |-- power
| |-- power :-)
| `-- sleep
|-- dsdt
|-- event
`-- info
Příkaz 'cat /proc/acpi/event' se zablokuje a čeká na události. Po
stisknutí POWER tlačítka se objeví jedna řádka s popisem události.
Přesný text neuvedu, protože mám jádro patchnuté tak, že nic
nevypisuje a patchovat, konfigurovat a kompilovat nové se mi nechce.
Tlačítko RESET provede okamžitě tvrdý reset.
A dostáváme se k initu - zajímavá část manuálové stránky je:
SIGHUP
Init looks for /etc/initrunlvl and /var/log/initrun
lvl. If one of these files exist and contain an
ASCII runlevel, init switches to the new runlevel.
This is for backwards compatibility only! . In the
normal case (the files don't exist) init behaves like
telinit q was executed.
SIGINT
Normally the kernel sends this signal to init when
CTRL-ALT-DEL is pressed. It activates the ctrlaltdel
action.
Takže do /etc/rc.d/rc.local (platí pro RedHat, jiné distribuce mohou mít
umístění jiné) jsem přidal:
echo '0' >/etc/initrunlvl
protože init tento soubor po přečtení smaže. Nula je runlevel Halt.
Teď po 'kill -SIGHUP 1' dojde k vypnití počítače. Pokud to
nefunguje, asi nemá cenu pokračovat dál. Osobně mi v RedHatu 7.1 nefunguje
vypnutí příkazem halt, musím použít poweroff. Přitom v 6.0 halt vypínal.
Zbývá upravit jádro, aby poslalo SIGHUP initu. To jsem ve verzi 2.4.9
udělal takto:
diff -u linux.orig/drivers/acpi/ospm/button/bn_osl.c linux/drivers/acpi/ospm/button/bn_osl.c
--- linux.orig/drivers/acpi/ospm/button/bn_osl.c Thu Jun 21 02:47:40 2001
+++ linux/drivers/acpi/ospm/button/bn_osl.c Fri Sep 14 23:33:10 2001
@@ -29,6 +29,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
+#include <linux/sched.h>
#include <acpi.h>
#include "bn.h"
@@ -152,8 +153,10 @@
case BN_TYPE_POWER_BUTTON:
case BN_TYPE_POWER_BUTTON_FIXED:
- status = bm_osl_generate_event(button->device_handle,
- BN_PROC_ROOT, BN_PROC_POWER_BUTTON, event, 0);
+
+ /* status = bm_osl_generate_event(button->device_handle,
+ BN_PROC_ROOT, BN_PROC_POWER_BUTTON, event, 0);*/
+ kill_proc(1,SIGHUP,1);
break;
case BN_TYPE_SLEEP_BUTTON:
Pine to přeformátoval, ale vyznat se v tom podle mě dá. Otázka je,
jestli se v tom vyzná program patch. Lepší bude asi ruční práce.
Pro 2.4.4 vypadá patch takto:
diff -u linux.orig/drivers/acpi/events/evevent.c linux/drivers/acpi/events/evevent.c
--- linux.orig/drivers/acpi/events/evevent.c Fri Feb 9 20:45:58 2001
+++ linux/drivers/acpi/events/evevent.c Tue May 29 09:20:11 2001
@@ -24,6 +24,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/sched.h>
#include "acpi.h"
#include "achware.h"
#include "acevents.h"
@@ -197,6 +198,7 @@
if ((status_register & ACPI_STATUS_POWER_BUTTON) &&
(enable_register & ACPI_ENABLE_POWER_BUTTON))
{
+ kill_proc(1,SIGHUP,1);
int_status |= acpi_ev_fixed_event_dispatch
(ACPI_EVENT_POWER_BUTTON);
}
Poznámka: poslat signál lze i uvnitř obsluhy přerušení - lze downovat
počítač třeba signálem na sériovém portu. Takto mám uděláno také downování
infračerveným dálkovým ovladačem, kterým normálně ovládám xmms.
Druhá možnost, jak sdělit initu, že má zastavit počítač je démon, který
čte /proc/acpi/event a pokud objeví text o stisknutí POWER buď killne
init nebo spustí powerdown nebo ............
Výhoda tohoto řešení je nepotřeba patchování jádra, nevýhoda je, že démona
je třeba nejprve napsat. Já ho nepsal, funguje mi první verze k naprosté
spokojenosti. V dokumentaci k jádru je:
This driver registers for events based on buttons, such as the power,
sleep, and lid switch. In the future, a daemon will read
/proc/acpi/event and perform user-defined actions such as shutting
down the system. Until then, you can cat it, and see output when
a button is pressed.
Takže démona zřejmě někdo napíše a výše popsané řešení bude k ničemu.
To je asi tak vše, snad to někomu pomůže.
Láďa
--
__... ...__ _.. . ___ _._ .____ __.. .. ._
(__) vv vv
(oo) ||----|| *
/-------\/ || | /
/ | || /\-------/
* ||----|| (oo)
^^ ^^ (~~)
American Cow Australian Cow
Další informace o konferenci Linux