[comp.sys.ibm.pc.programmer] How to do a warm-boot from a C program

pingpong@milton.acs.washington.edu (jimmy) (02/20/90)

Does anyone know how to do a boot from a C program?

What I really want is whenever something goes wrong in my C program, (e.g. Null
pointer reference, etc.) instead of going back to DOS, do a ctrl-alt-del.

I am using Quick C.

Thanks in advance.

-Jimmy.

mcintyre@turing.cs.rpi.edu (David McIntyre) (02/20/90)

jimmy writes:
>Does anyone know how to do a boot from a C program?

Yes, just do an Interrupt 25 (which is 19h).  That will do it nicely.

One minor comment: rebooting a computer is a pretty harsh way to recover
from a program error.  In fact, with today's windowing systems, by rebooting
the system you could cause a nasty problem for another program.

A Scenario:
	a) I am in Lotus, and decide to run your program.

	b) I do a shell escape.  Then run your program.

	c) Your program crashes, and causes a reboot!

	d) All my Lotus data is lost, since I didn't save it before
	   shelling out.

Just a friendly point.

				-Dave

Dave "mr question" McIntyre     |      "....say you're thinking about a plate
mcintyre@turing.cs.rpi.edu      |       of shrimp.....and someone says to
office : 518-276-8633		|	you 'plate,' or 'shrimp'......"

JXS118@psuvm.psu.edu (Jeff Siegel, Op from Atherton Hall) (02/20/90)

In article <something or other, I don't know>
>
>jimmy writes:
>>Does anyone know how to do a boot from a C program?
>
>Yes, just do an Interrupt 25 (which is 19h).  That will do it nicely.

Sorry, but my first reaction is NO ! NO ! NO ! <Emphatically!>

This is a seems to be a common misconception. Int 19h is too buggy on
most machines that I've seen. It won't reset any hardware registers
that may have been mucked with. It alsowill fail (mostly) if you have
multiple-page-tracking-type EMM drivers installed. Your best bet for a reboot
is to far jump to addresss FFFF:0000. This will cause the almost-equivalent
of pressing the resest button (provided you have one.) However, this invokes
the memory test (usually lengthy). To exactly mimick a CTRL-ALT-DEL, you must
write hex word 1234 into some special address in the bios data areas (it is
listed in Norton, i don't remeber what the address is.) and then do the far
jump.


+-----------------------------------------------------------------------+
| Jeff Siegel                   |  "Penn State ---                      |
| 24 Atherton Hall              |       Where the men are men and the   |
| 862-5124                      |       sheep are nervous. "            |
| JXS118 @ PSUVM.BITNET         |                     - Ray Wolfgang    |
+-------------------------------+---------------------------------------+

mbt@bridge2.ESD.3Com.COM (Brad Turner) (02/20/90)

JXS118@psuvm.psu.edu (Jeff Siegel, Op from Atherton Hall) writes:

>In article <something or other, I don't know>
>>
>>jimmy writes:
>>>Does anyone know how to do a boot from a C program?
>>
>>Yes, just do an Interrupt 25 (which is 19h).  That will do it nicely.

>Sorry, but my first reaction is NO ! NO ! NO ! <Emphatically!>

>This is a seems to be a common misconception. Int 19h is too buggy on
>most machines that I've seen. It won't reset any hardware registers
>that may have been mucked with. It alsowill fail (mostly) if you have
>multiple-page-tracking-type EMM drivers installed. Your best bet for a reboot
>is to far jump to addresss FFFF:0000. This will cause the almost-equivalent
>of pressing the resest button (provided you have one.) However, this invokes
>the memory test (usually lengthy). To exactly mimick a CTRL-ALT-DEL, you must
>write hex word 1234 into some special address in the bios data areas (it is
>listed in Norton, i don't remeber what the address is.) and then do the far
>jump.

feed the following lines to debug:
-------------------cut here-----------------------
a
mov dx,0
mov ds,dx
mov ax,1234
mov [472],ax
jmp ffff:0000

r cx
10
w
q
------------------cut here-------------------------
Note the blank line is required (that tells the mini-assembler to quit
assembling)

Make sure to invoke debug with a filename (eg C:\>debug reboot.com)
otherwise the write command will bomb.

Ideally you should save whats between the above ---cut here--- lines
and feed it to debug (i.e. C:\>debug reboot.com < infile )

By moving 0x1234 into ax you will avoid the memory test. If you want to
do the memory test move 0 into ax rather than 0x1234

-brad-
-- 
v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v
Brad Turner |2081 Shoreline Blvd.|(415) 969-2099 ext 217  | I speak for myself
3Com Corp.  |Mtn. View, CA 94043 |mbt@bridge2.ESD.3Com.Com| NOT for my employer

w8sdz@smoke.BRL.MIL (Keith Petersen) (02/21/90)

The following message recently appeared in the Info-IBMPC digest.

[---forwarded message---]
Date: Thu Feb 15 18:05:39 GMT 1990
To: Info-IBMPC@WSMR-SIMTEL20.ARMY.MIL
From: Mike O'Carroll <lena!mike@relay.EU.net>
Subject: Reboot of PC

The program below works in TurboC (or MS C).  In some compilers, you
have to fold the address to 20 bits, but here the segment and offset
are separate.

Mike O'Carroll, Microsystems Unit, University of Leeds, LS2 9JT, UK
E-mail: @ukc.ac.uk:mike@ee.leeds.ac.uk
UUCP:   ...!mcsun!ukc!lena!mike or mike@lena.uucp

---cut-here---

#define MAGIC           0               /* for cold restart */
/* #define MAGIC           0x1234          /* for warm restart */

#define BOOT_SEG	0xffffL
#define BOOT_OFF	0x0000L
#define BOOT_ADR	((BOOT_SEG << 16) | BOOT_OFF)

#define DOS_SEG		0x0040L
#define RESET_FLAG	0x0072L
#define RESET_ADR	((DOS_SEG << 16) | RESET_FLAG)

main()
{
	void ((far *fp)()) = (void (far *)()) BOOT_ADR;

	*(int far *)RESET_ADR = MAGIC;
	(*fp)();
	return 0;	/* never gets here, but keeps compiler happy */
}

[---end forwarded message---]

Keith
-- 
Keith Petersen
Maintainer of SIMTEL20's CP/M, MSDOS, & MISC archives [IP address 26.2.0.74]
Internet: w8sdz@WSMR-SIMTEL20.Army.Mil, w8sdz@brl.arpa  BITNET: w8sdz@NDSUVM1
Uucp: {ames,decwrl,harvard,rutgers,ucbvax,uunet}!wsmr-simtel20.army.mil!w8sdz

mjh@cs.vu.nl (Maarten J Huisjes) (02/21/90)

In article <90050.231645JXS118@psuvm.psu.edu>,
	JXS118@psuvm.psu.edu (Jeff Siegel, Op from Atherton Hall) writes:
> In article <something or other, I don't know>
> >
> >jimmy writes:
> >>Does anyone know how to do a boot from a C program?
> >
> >Yes, just do an Interrupt 25 (which is 19h).  That will do it nicely.
> 
> Sorry, but my first reaction is NO ! NO ! NO ! <Emphatically!>
> 
> This is a seems to be a common misconception. Int 19h is too buggy on
> most machines that I've seen. It won't reset any hardware registers

Nop, It's not buggy it's just misunderstood. Int 19H is NOT a 'reboot my
computer'-interupt. It is the bootstrap loader. The bootstrap loader
loads the boot sector of either floppy or hard disk into memory and gives
it control. It is done in a reboot but at the and of all POST routines
(if you have a ROM listing you will see that it realy does a 'INT 19H')
As noted by Jeff it will only bootstrap not reboot, so it will not initialize
hardware. Also it will not initialize BIOS data area and Interrupt Table.
(When you had drivers or TSR's hooked to one of the interupts the vectors
will not be reset !!). Using Int 19H to reboot is a sure way to lock up your
machine. Write 1234H to 0:472H then do a long jump to FFFF:0H to do a
warm reboot (As noted in +- 20 messages last month). Even this will not
work on all clones. (If it doesn't work for you try with debug to trace
Cntrl-Alt-Del :-) )
--

Maarten Huisjes.		mjh@cs.vu.nl (..!uunet!mcsun!botter!mjh)

mathrich@mthvax.cs.miami.edu (Rich Winkel) (02/21/90)

In article <90050.231645JXS118@psuvm.psu.edu> JXS118@psuvm.psu.edu (Jeff Siegel, Op from Atherton Hall) writes:

>In article <something or other, I don't know>
>>
>>jimmy writes:
>>>Does anyone know how to do a boot from a C program?
>>
>>Yes, just do an Interrupt 25 (which is 19h).  That will do it nicely.

>Sorry, but my first reaction is NO ! NO ! NO ! <Emphatically!>

>This is a seems to be a common misconception. Int 19h is too buggy on
>most machines that I've seen. It won't reset any hardware registers
>that may have been mucked with. It alsowill fail (mostly) if you have
>multiple-page-tracking-type EMM drivers installed. Your best bet for a reboot
>is to far jump to addresss FFFF:0000. This will cause the almost-equivalent
>of pressing the resest button (provided you have one.) However, this invokes
>the memory test (usually lengthy). To exactly mimick a CTRL-ALT-DEL, you must
>write hex word 1234 into some special address in the bios data areas (it is
>listed in Norton, i don't remeber what the address is.) and then do the far
>jump.

The address is 0x40:0x72.  INT 19h isn't buggy .. it wasn't designed to do a
reset.  All it's supposed to do is load the boot sector off the first disk
it can find and put it at an absolute location (0:7C00, I think) in memory.
It doesn't know anything about TSR's, re-directed int vectors or anything
else that could trip it up.  It's supposed to be called by the system reset
routine, which has already taken care of all that stuff.  There is no
interrupt vector which points to the system reset routine.  As mentioned
above, the way to do a reset is to jump to FFFF:0000.  This is in fact what
the cpu is wired to do at power on.

Rich

jrh@mustang.dell.com (James R. Howard) (02/21/90)

In article <2028@milton.acs.washington.edu>,
pingpong@milton.acs.washington.edu (jimmy) writes:
> Does anyone know how to do a boot from a C program?
> 
> What I really want is whenever something goes wrong in my C program,
(e.g. Null
> pointer reference, etc.) instead of going back to DOS, do a ctrl-alt-del.
> 
> I am using Quick C.
> 
> Thanks in advance.
> 
> -Jimmy.


Well, if it is an AT system (IBM compatible) you can write 0xFE to port
64h on the 
keyboard controller to perform a hard reset.   See the IBM AT Tech Ref,
pg 1-54 
for the details.  The 0xFE is a mask value, leaving everything high
except for bit 0.
Bit 0 of the kbd controller's output is connected to system reset.  

So,  a quickc routine to do that would be:

#include <conio.h>

main()
{
int	port, mask;

port = 0x64;
mask=0xfe;

outp(port,mask)
}


That will do the trick....

--------------------------------------------------------------
James Howard
..cs.utexas.edu!dell!mustang!jrh   or    jrh@mustang.dell.com

"I've got a firm policy on gun control, if there's a gun       
around, I want to be the one controlling it."          
-- Clint Eastwood 
--------------------------------------------------------------

jrh@mustang.dell.com (James R. Howard) (02/21/90)

In article <P#$#92_@rpi.edu>, mcintyre@turing.cs.rpi.edu (David
McIntyre) writes:
> jimmy writes:
> >Does anyone know how to do a boot from a C program?
> 
> Yes, just do an Interrupt 25 (which is 19h).  That will do it nicely.
> 
  [ rest deleted ]

That will work, but there are some cases were TSR's and varying machine BIOS
will lock up on an int 19h call.  This of course "should" work, but there are
numerous machines floating around that will lock when trying this with the
right combination in autoexec/config.



--------------------------------------------------------------
James Howard
..cs.utexas.edu!dell!mustang!jrh   or    jrh@mustang.dell.com

"I've got a firm policy on gun control, if there's a gun       
around, I want to be the one controlling it."          
-- Clint Eastwood 
--------------------------------------------------------------

pipkins@qmsseq.imagen.com (Jeff Pipkins) (02/21/90)

In article <P#$#92_@rpi.edu> mcintyre@turing.cs.rpi.edu (David McIntyre) writes:
>jimmy writes:
>>Does anyone know how to do a boot from a C program?
>
>Yes, just do an Interrupt 25 (which is 19h).  That will do it nicely.

No, you should never do that.  If you do, sometimes it will work, but much
of the time it will hang.  The proper way to simulate Ctrl-Alt-Del is to
use the same technique that the keyboard handler uses when it detects the
Ctrl-Alt-Del sequence.

Try something like this:

void warm_boot()
{
   unsigned int far *reset_flag = (unsigned int far *) 0x00400072L;
   void (far *boot)() = 0xFFFF0000L;

   *reset_flag = 0x1234;
   (*boot)();
}

void cold_boot()
{
   [same definitions]

   *reset_flag = 0;
   (*boot)();
}


>One minor comment: rebooting a computer is a pretty harsh way to recover
>from a program error.  In fact, with today's windowing systems, by rebooting
>the system you could cause a nasty problem for another program.
>[example deleted]

Good point.  It is also not a very user-friendly kind of thing to do
anyway.  If you want to create a robust, bullet-proof program, you can't
do it by barfing and leaving the user at the mercy of an MS-DOS prompt.

>Dave "mr question" McIntyre     |      "....say you're thinking about a plate
>mcintyre@turing.cs.rpi.edu      |       of shrimp.....and someone says to
>office : 518-276-8633		|	you 'plate,' or 'shrimp'......"

                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
					Would you please explain the shrimp
					thing?

Jeff Pipkins
pipkins@imagen.com