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