Hard Reboot?

Direkte Linux-Programmierung, POSIX
Antworten
alfred1
Beiträge: 6
Registriert: Mi Jan 05, 2022 12:56 pm

Hard Reboot?

Beitrag von alfred1 » Mi Jan 05, 2022 12:57 pm

Hallo,

wir haben ein Problem mit einem fehlerhaften Bios bei Server zu denen es nicht so einfach ist physikalischen Zugriff zu bekommen.

Es äussert sich darin das nach einer uptime von ca. mehr als 100 Tagen beim Versuch zu rebooten die Kisten komplett tot sind, bis sie physikalisch
ein und ausgeschalten wurden. RLM/iKVM/iLO etc. ist nicht vorhanden. Das Bios können wir remote momentan nicht upgraden.

Bei einem "Kaltstart" durch ein und ausschalten ist das Problem erstmal weg, eben diesen Kaltstart möchte ich nun gerne haben, z.B. als kleinen Programm.


Man kann dem Kernel eine Option mitgeben "reboot=cold" - leider muss der Server dazu gebootet werden, was ja eben nicht funktioniert.

in reboot.c im Kernel Sourcecode steht in etwa sowas:

#define __va(x) ((void *)((unsigned long) (x)))
*((unsigned short *)__va(0x472)) = 0x0000;

Der Wert kann 0x1234 (warm Start) oder 0x0000 (Kaltstart sein).

Eingewickelt in eine main-Funktion kompiliert das Problemlos, beim Versuch es aufzurufen gibt es aber einen Coredump.
Ebenso als kleines Assembler Programm (movw $0x1234,0x0000) kompiliert es und erzeugt einen Coredump.

Ich vermute das ganze ist irgendwie abgesichert vom Linux Kernel aus.

Habt ihr einen Tip das hinzubekommen??

Alfred

mfro
Beiträge: 344
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Hard Reboot?

Beitrag von mfro » Mi Jan 05, 2022 1:15 pm

Das funktioniert so nicht.

Dein Programm läuft nicht im Kernel-Kontext und bekommt deswegen seinen eigenen virtuellen Adressraum zugewiesen, der ganz woanders liegt. Du schreibst also auf eine völlig andere physische Adresse.

Was funktionieren könnte/müsste, wäre ein mmap() auf /dev/mem (das ist der physikalische Adressraum) und anschliessendes Schreiben an den entsprechenden Offset.
Auch möglich: ein ladbares Treiber-Modul (ist aber deutlich komplizierter).
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

alfred1
Beiträge: 6
Registriert: Mi Jan 05, 2022 12:56 pm

Re: Hard Reboot?

Beitrag von alfred1 » Mi Jan 05, 2022 1:27 pm

Hallo mfro,

vielen Dank für deine Antwort.

Genau so was hatte ich vermutet.

Wir hatten mit hexdump mal versucht das aus /dev/mem auszulesen, also ab der Stelle 0x472

Dort stand aber nicht das erwartete. Erwartet hätte ich das dort 0x1234 steht (soll der default sein), es steht aber 00 00 da.

Ich vermute das /dev/mem ebenfalls irgendwie beschränkt ist und manches ausblendet oder so.

Aber möglicherweise kann man die Beschränkung ja aufheben?

alfred1
Beiträge: 6
Registriert: Mi Jan 05, 2022 12:56 pm

Re: Hard Reboot?

Beitrag von alfred1 » Mi Jan 05, 2022 1:53 pm

Also, ich glaube ein Kernel Modul zu bauen ist vielleicht doch machbar, habe momentan einfach mal sowas gemacht in der Art wie unten und das kompiliert und lässt sich einbinden.

Die Frage wäre nur, wie kann ich das vorher und nachher auslesen den Wert um es mit printk zu loggen?

Um sicher zu sein das es wirkt.

Auch noch eine Frage ist wie danach rebootet werden kann, nicht das der reboot das wieder auf 0x1234 setzt...
Ich würde es mit:
echo "b" > /proc/sysrq-trigger
probieren :)



#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>



MODULE_LICENSE("GPL");
MODULE_AUTHOR("AM");
MODULE_DESCRIPTION("Kaltstart Moped");
MODULE_VERSION("0.01");

static int __init lkm_example_init(void) {
printk(KERN_INFO "Kaltstartmodul geladen\n");
//#define __va(x) ((void *)((unsigned long) (x))) Im /include bereits gemacht
*((unsigned short *)__va(0x472)) = 0x0000;
return 0;
}

static void __exit lkm_example_exit(void) {
printk(KERN_INFO "Kaltstart Modul entladen\n");
}

module_init(lkm_example_init);
module_exit(lkm_example_exit);

mfro
Beiträge: 344
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Hard Reboot?

Beitrag von mfro » Mi Jan 05, 2022 2:09 pm

alfred1 hat geschrieben:
Mi Jan 05, 2022 1:27 pm
Dort stand aber nicht das erwartete. Erwartet hätte ich das dort 0x1234 steht (soll der default sein), es steht aber 00 00 da.
Wenn ich mir den Quellcode anschaue (Linux Kernel), dann steht an der Adresse eben nicht defaultmässig 0x1234. Tatsächlich wird der Wert der Kernel-Variable reboot_mode erst bei einem Reboot dort hingeschrieben (und das auch nur, wenn der Kernel mit "reboot=c" gestartet wurde). Wenn Du nur 0x1234 nach 0x472 schreibst, wird dein Wert bei einem Neustart überschrieben.

Was Du also tatsächlich machen willst, ist die Kernel-Variable "reboot_mode" auf 0x1234 setzen. Und das ist deutlich schwieriger, weil Du erstmal rausfinden müsstest, wo die Variable in deinem Kernel eigentlich gelandet ist.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

alfred1
Beiträge: 6
Registriert: Mi Jan 05, 2022 12:56 pm

Re: Hard Reboot?

Beitrag von alfred1 » Mi Jan 05, 2022 2:15 pm

Naja, es würde auch funktionieren am normalen Reboot Prozess vorbei das OS abzuschiessen.

Meine Hoffnung ist das dies mit:
echo "b" > /proc/sysrq-trigger

Einfach so möglich ist...

Oder wird dort die normale Routine doch auch ausgeführt??

alfred1
Beiträge: 6
Registriert: Mi Jan 05, 2022 12:56 pm

Re: Hard Reboot?

Beitrag von alfred1 » Mi Jan 05, 2022 2:35 pm

Wirklich interressant wäre es auch den Wert auslesen zu können.

Aber wenn ich einen unsigned char Zeiger auf den Bereich mache und das über eine Variable versuche auszugeben passiert irgendwie nix und das Modul lässt sich nicht mehr entladen..

mfro
Beiträge: 344
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Hard Reboot?

Beitrag von mfro » Mi Jan 05, 2022 3:52 pm

It's as simple as that. And remember, Beethoven wrote his first symphony in C.

alfred1
Beiträge: 6
Registriert: Mi Jan 05, 2022 12:56 pm

Re: Hard Reboot?

Beitrag von alfred1 » Sa Jan 08, 2022 7:56 am

Also letztenendes hat das mit dem Kernel Modul schon funktioniert, es war alles richtig gesetzt, der Fehler ist dennoch aufgetreten.

Die Lösung hier war nun erstmal einen Kernel ohne reboot neu zu laden mittels kexec.

Das funktioniert, man kann Debian updates machen und so weiter.

Irgendwann muss das Bios dann nach und nach aktualisiert werden, bis dahin geht die Lösung und man kann das OS wenigstens aktuell halten.

Antworten