Re: Compaq Presario "reboot" problems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Friday 18 November 2005 16:15, linux-os (Dick Johnson) wrote:
> On Fri, 18 Nov 2005, Denis Vlasenko wrote:
> 
> > On Thursday 17 November 2005 20:51, linux-os (Dick Johnson) wrote:
> >> It appears as though Linux is still restarting as a "warm boot",
> >> rather than a cold boot (in other words, putting magic in the
> >> shutdown byte of CMOS) so the hardware doesn't get properly
> >> initialized. Would somebody please check this out. When changing
> >> operating systems, you need a cold-boot.
> >
> > Can you check which driver does that? The test would be to
> > boot a special Linux setup which reboots immediately
> > (say, wuth init=/some/reboot_script.sh boot param).
> >
> > Then start removing drivers from kernel until you
> > can boot Win successfully after Linux reboots.
> > --
> > vda
> 
> I booted into a shell from a floppy disk. There were no drivers
> installed, not even the IDE driver. I could not reboot windows
> after linux was up and rebooted. This was Linux-2.6.13.4. Then
> I tried linux-2.4.26 which corresponds to the version when I
> first reported this problem. The same thing happens. Therefore,
> I temporarily modified linux-2.6.13.4 to force a triple-fault
> and processor reset when doing a reboot. With this temporary
> modification it is possible to boot windows after Linux was
> running.
> 
> This is the reboot patch. It is not a "solution", just something
> that shows that the current reboot code doesn't force the BIOS
> to start from scratch, which is essential when changing operating
> systems.
> 
> 
> --- linux-2.6.13.4/arch/i386/kernel/reboot.c.orig	2005-11-18 08:29:12.000000000 -0500
> +++ linux-2.6.13.4/arch/i386/kernel/reboot.c	2005-11-18 08:52:40.000000000 -0500
> @@ -337,6 +337,11 @@
> 
>   void machine_restart(char * __unused)
>   {
> +        for(;;) {
> +	__asm__ __volatile__("\tmovl %cr0, %eax\n"
> +			     "\tandl $~0x80000000,  %eax\n"
> +			     "\tmovl %eax, %cr0\n");
> +        }
>   	machine_shutdown();
>   	machine_emergency_restart();
>   }

Does reboot=cb ('cold', 'thru BIOS') work for you?

I read arch/i386/kernel/reboot.c and it looks like reboot=cb
kernel param will triple fault too:

static int reboot_mode;
static int reboot_thru_bios;

static int __init reboot_setup(char *str)
{
        while(1) {
                switch (*str) {
                case 'w': /* "warm" reboot (no memory testing etc) */
                        reboot_mode = 0x1234;
                        break;
                case 'c': /* "cold" reboot (with memory testing etc) */
                        reboot_mode = 0x0;
                        break;
                case 'b': /* "bios" reboot by jumping through the BIOS */
                        reboot_thru_bios = 1;
                        break;
                case 'h': /* "hard" reboot by toggling RESET and/or crashing the CPU */
                        reboot_thru_bios = 0;
                        break;
                }
                if((str = strchr(str,',')) != NULL)
                        str++;
                else
                        break;
        }
        return 1;
}

__setup("reboot=", reboot_setup);
...
void machine_emergency_restart(void)
{
        if (!reboot_thru_bios) {
                if (efi_enabled) {
                        efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL);
                        load_idt(&no_idt);
                        __asm__ __volatile__("int3");
                }
                /* rebooting needs to touch the page at absolute addr 0 */
                *((unsigned short *)__va(0x472)) = reboot_mode;
                for (;;) {
                        mach_reboot_fixups(); /* for board specific fixups */
                        mach_reboot();
                        /* That didn't work - force a triple fault.. */
                        load_idt(&no_idt);
                        __asm__ __volatile__("int3");
                }
        }
        if (efi_enabled)
                efi.reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, NULL);

        machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
}

void machine_restart(char * __unused)
{
        machine_shutdown();
        machine_emergency_restart();
}


If it does not, try this reboot=tc - this is closely resembles
what you proposed in your mail (pseudo-patch):

static int __init reboot_setup(char *str)
{
        while(1) {
                switch (*str) {
+               case 't': /* "triple fault" reboot */
+                       reboot_thru_bios = 2;
+                       break;
                case 'w': /* "warm" reboot (no memory testing etc) */
                        reboot_mode = 0x1234;
                        break;
...
void machine_emergency_restart(void)
{
+       if (reboot_thru_bios == 2) {
+               *((unsigned short *)__va(0x472)) = reboot_mode;
+               load_idt(&no_idt);
+               __asm__ __volatile__("int3");
+	}
        if (!reboot_thru_bios) {
                if (efi_enabled) {
                        efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL);
--
vda
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux