[syslinux] reboot from com32

Miguel mth at mth.com
Tue Aug 14 08:18:04 PDT 2007


HPA wrote:
>
> The easiest way is to use __farcall() to call to 0xf000:0xfff0:
>
> __noreturn syslinux_reboot(int warm)
> {
>   static com32sys_t dummy_regs;
>   uint16_t * const reboot_flag = (uint16_t *)0x472;
>
>   *reboot_flag = warm ? 0x1234 : 0;
>   __farcall(0xf000, 0xfff0, &dummy_regs, NULL);
> }
>
> I just added syslinux_reboot() to the git tree.
>
> 	-hpa

I have been unable to get this to work properly.

On an HP DL360G2 it returns from syslinux_reboot, independent of whether
it is warm or cold.

On a Dell PE850 it hangs (but will respond to Ctl-Alt-Del), independent of
whether it is warm or cold.

The code that I am using is below in its entirety. It is a tweaked version
of samples/hello.c that responds to 'warm' or 'cold'.

My only thought is:

Q: Does __farcall switch out of 32 bit mode and back into 16 bit mode?

The standard BIOS reset entry point probably is expecting the processor to
be in 16 bit mode.

If that is not the problem, then I have no idea.


Miguel

----

/*
 * com32 hello.c modified to test syslinux_reboot
 */

#include <string.h>
#include <stdio.h>
#include <console.h>
#include <com32.h>

__noreturn syslinux_reboot(int warm)
{
  static com32sys_t dummy_regs;
  printf("syslinux_reboot(%d)\n", warm);
  memset(&dummy_regs, 0, sizeof dummy_regs);

  uint16_t * const reboot_flag = (uint16_t *)0x472;

  *reboot_flag = warm ? 0x1234 : 0;
  __farcall(0xf000, 0xfff0, &dummy_regs, &dummy_regs);
  printf("Why am I still here?\n");
}

int main(void)
{
  char buffer[1024];

  openconsole(&dev_stdcon_r, &dev_stdcon_w);

  printf("Hello, World!\n");

  for (;;) {
    printf("> ");
    fgets(buffer, sizeof buffer, stdin);
    if ( !strncmp(buffer, "exit", 4) )
      break;
    elseif ( !strncmp(buffer, "cold", 4))
      syslinux_reboot(0);
    else if (! strncmp(buffer, "warm", 4))
      syslinux_reboot(1);
    printf(": %s", buffer);
  }

  return 0;
}

----




More information about the Syslinux mailing list