Why is the maximum boot.ini delay 11 million seconds?


I mentioned in passing that the maximum delay you can specify in boot.ini is about 11 million seconds. I'm disappointed but sadly not surprised that everybody focused on that number and completely missed the point of the article.

First of all, the value of 11 million was not a conscious limitation. It's just an artifact of other limitations. The delay is specified in seconds in boot.ini, but internally it is converted to BIOS clock ticks. (Remember, this is a boot loader; there's not much infrastructure available yet.) The conversion is done in 32-bit arithmetic, and 4 billion BIOS clock ticks at 18.2 ticks per second is about 110 million seconds.

Wait, but you said 11 million seconds, not 110 million seconds.

Well, yes, but the conversion is done in 32-bit integer arithmetic: BiosTicks = BootIniSeconds * 182 / 10. A value for BootIniSeconds larger than about 11 million will result in a signed integer overflow in the intermediate product.

That's why the limit is 11 million seconds. It's a storage limitation, not an arbitrary cutoff. And it is indeed the limit of a natural data type, just hidden behind some other computations. (SB figured this out, though I fear that this shout-out will only serve to encourage people to speculate even more wildly than they already do in the hopes of earning a future shout-out.)

Now you'd think this would be plenty enough of a boot delay. I mean, it's already much longer than the maximum amount you can delay with a single call to Sleep or WaitForSingleObject. And who would ever need a computer to pause four months before booting? Yet there's one commenter who thought 11 million seconds wasn't enough: "What if I want a timeout of 129 days?" If you need a timeout of 129 days, then go buy a custom hardware timer device that waits 129 days after the onset of power before allowing current to flow. This same commenter has difficulty comprehending that just because you're capable of delaying something for a specific length of time and you're capable of never doing it at all, that doesn't mean that you are also capable of delaying something for an arbitrary length of time.

One commenter suggested that the problem could be solved by using a bignum library. Before you solve a problem, you first have to be sure that what you have really is a problem in the first place. I have yet to hear of any customers who are running into the 11 million second limit. Using bignums here would be a solution in search of a problem. "Hey, let's consume valuable developer and tester resources in order to add a bunch of code to a tightly-constrained environment to cover a case that nobody cares about." (And I failed to live up to my promise to Ulric merely to incorporate this lecture by reference in the future.)

Comments (32)
  1. Morten says:

    Erm… wouldn’t that be ~2e9 BIOS clock ticks? As in 2^31?

  2. Michael Stum says:

    Ha, i’d like to see QA testing if a timeout for more than 4 months really work :D

    But yeah, I am puzzled as well why anyone would ever really need a timeout longer than a few Minutes, if even that long. But then again, people are weird.

  3. Neil says:

    Strange that the boot loader should be limited to a 32-bit dividend, when the 80386 is capable of generating a 64-bit intermediate result and dividing that by 10.

    Or you could multiply by 91 and divide by 5 to gain a whole extra bit of magnitude. And if you used unsigned arithmetic you could get up to a whopping 47 million seconds, almost a year and a half!

  4. Jonathan Gilbert says:

    As you mentioned in 2004:

     http://blogs.msdn.com/oldnewthing/archive/2004/12/02/273721.aspx

    ..the clock rate is a result of picking a frequency based on a decimation of the CPU clock rate of the original IBM PC. That original clock rate was itself related to the NTSC colorburst frequency, defined to be 39375 / 11 kHz. The IBM PC’s frequency was 4/3 of that, and the BIOS clock rate was 1/4 of the IBM PC’s frequency, giving a clock rate of 1193181 Hz. The chip on the motherboard in charge of raising timer interrupts counts up to a configurable trigger value between 1 and 65536 between each interrupt. The default trigger is 65536 (represented as all zeroes in a 16-bit register). This means that the clock rate is 1193181 / 65536 = 18.2064971924.

    The code you showed approximates this to 18.2 exactly, which means that it introduces inaccuracy at a rate of a bit over one second every hour. Specifically, if you set the delay to one hour, 3600 seconds, you will actually get a delay of only 3598.715 seconds. Is this acceptable?!

    Well, yes. Yes, it is. :-)

  5. mvadu says:

    @Neil

    Strange that the boot loader should be limited to a 32-bit dividend

    Are you sure you read the linked blog entry..

    People like you who Raymond mentioned when he said "I’m disappointed but sadly not surprised that everybody focused on that number and completely missed the point of the article."

    In the days of 80386, 32 bit number (signed integer) was good enough with 4 months of boot delay. No one needed to work on solving/designing some thing which no will ever use.

    Remember, when Microsoft says some thing like this they need to test it. I am pretty sure some one tested 4 months limit just to make sure it works. Think about your 64 bit scenario.. Why do you think they need to test by waiting till it reaches maximum limit for 64 bit and see if Windows actually boots, just for the heck of the fact that 80386 can generate 64 bit integers.

    No one is facing any issues with the current 32 bit design, whole Windows user community is happy with currently boot delay limits. Please don’t try to show off your engineering capabilities.

  6. a storage limitation?

    are you sure?

    I’m pretty sure you guys know about bit manipulation, let’s see

    111011 seconds

    111011 minutes…

    J

  7. mvadu says:

    And to add more, if any one needs more than few minutes of boot delay, you better spend 10$ to get a digital timer switch. That way you can save energy.. Think Green.. You should not be wasting valuable energy.. Remember.. while booting, CPU is running at full power, so you are wasting almost 100W of power (or may be more) while boot timer ticks.. Do you really want more than 4 months?

  8. Dan says:

    This like asking why 32-bit signed integers only go up to 2 billion.

  9. DWalker says:

    Someone said that the "problem" could be solved by using a Bignum library DURING BOOT?  Are they crazy?

    Wow, people sure do think that weird things are "problems".  Heck, limit it to one day.

  10. You could easily allow very long boot delays by specifying the logarithm of the boot delay instead of the boot delay directly.  You would also get very good granularity at the "short" end of the spectrum.  (You’d lose the current good granularity at the "long" end, but who really cares?)

    Or you could go the whole hog and implement an RFC 2550-compliant solution.

  11. spoink says:

    And so, Neil begins the cycle anew…

  12. njkayaker says:

    "What if I want a timeout of 129 days?"

    People who make these kinds of statements should use their real names so they can be disqualified as hires more easily.

    If you want something patently ridiculous, you are obligated to give a -reason- why it makes sense to support.

  13. courage_dog says:

    You should be able to predict that some trolls will pop up when you say things like that. The upper limit was nowhere to be found until 2007/10/16, it was irrelevant for the described problem, and it turned against you.

  14. Mark (The other Mark) says:

    I wonder if any of the people who are looking at ways to solve this "problem" can came up with a scenerio where it would matter.

    What the limit is, and why it is= Interesting Geek Trivia.

    Whining about the limit without a real world use-case= Not Interesting

  15. dude says:

    Did no one read the very FIRST sentence?

    the article very plainly points out that this limit materialized as a side effect of the calculation. No limit was chosen, it just is.

    Raymond goes on to cite two examples that miss the point completely and try to solve a problem that "nobody cares about."

    Raymond should turn off the comments on this particular article, since the comments are likely to be trolls, or someone who missed the point yet again.

  16. "No limit was chosen, it just is."

    I disagree

  17. Zilla says:

    I thought the point of this post was that the limit didn’t matter… Then again, if you’re not intelligent enough to read this post correctly, I’d have to assume most of your ‘solutions’ are incorrect.

  18. DrkMatter says:

    Software developers are a type of engineers. Engineers like puzzles. Figuring out why the limit is 11 millions seconds, or how to set it higher, is a puzzle. Hence, software developers will tend to try to answer those questions. It’s not so much nitpicking as enjoying a mental exercise.

  19. Nick says:

    I prefer the question, Why does the shutdown program included with XP have a delay limit of 315359999 seconds?  What if I want to shut my computer down in 3650 days, not 3649?  Microsoft is intentionally limiting my creativity, productivity, and many other ivities!

  20. Ulric says:

    you have an elephant’s memory…

    most of what I say, unfortunately, is really best forgotten :P :(

  21. mikeb says:

    I thought it was clear that the maximum delay was 11 million seconds because who would want to wait 11,000,001 seconds?  

    *That’s* just too damn long!

  22. SuperKoko says:

    > One commenter suggested that the problem could be solved by using a bignum library.

    I couldn’t refrain my laugh…

    If bignums are to be used in the most memory constrained (the first boot record is 512 bytes of memory) assembly code in the world, when the limit they remove has never been met, then, I would expect bignums to be used everywhere else.. File pointers… Memory pointers (great, Windows would handle up to 2**4294967295 bytes of RAM)…!

    Why would I limit bignums representations to 4294967296 bytes… Bignums byte arrays should be indexed by bignums…

    And, of course:

    typedef bignum_t BOOL;

  23. Mark (yet another) says:

    SuperKoko: I agree in principle, but the boot loader screen isn’t implemented in the boot record, or assembly.  It’s written into ntldr/bootmgr, which is likely written in C.  So in theory bignum could be used.  Hell, why not put BASIC in there, too?

  24. Mark (The other Mark) says:

    @DrkMatter

    Fair enough. My solution would still be "What is the use case for this?", as the desired result is probably best served via a different method. If the job is too big for the tool you are using, it’s time to find a new tool- Much like you wouldn’t use a spoon to dig an olympic sized swimming pool.

    But then again, my job is to solve production problems quickly- I’ve lost the thought process that lets me enjoy using an over complicated method when a much simpler one exists.

  25. Neil says:

    It’s written into ntldr/bootmgr, which is likely written in C.

    OK, that’s a logical explanation of the 2^31 intermediate result limitation.

  26. J 2 says:

    128 days is unreasonable.  Limit it to 10 minutes, please.

  27. Of course, you could go the whole hog. The bootmgr is written in C – why not put everything in there? Windows, IE, Office, Mac OS X, Linux, DosBox, Firefox, Flash, a full collection of Beatles music etc.

    The answer is that you don’t want any component to do too much – 11 million seconds is sufficiently large for a boot menu delay to count as "effectively infinite". The theory of the boot menu delay is that, in the event you need to choose a non-default option, you have enough time to do so.

    Now, I know that some people are a bit slow when it comes to computer usage, but 129 days should be enough time to choose a boot option. If it’s not, *then* you file a request to Microsoft.

  28. mikeb says:

    Raymond:  

    There’s a corollary to this question that I hope you’ll address in a future topic:  why are we limited to a resolution of seconds when specifying the delay? Since the 55ms BIOS timer is used to implement the delay, why can’t I specify my delay in millisecond units (or at least tenths of seconds)?

    I want a short delay so I can override my boot options; something like 5.650 seconds would be great.  But 6 seconds is just a bit unbearable.

  29. steveg says:

    str = "No one will ever need more than 640kb"

    str =~ s/640kb/11 million seconds/

  30. England not UK says:

    @steveg

    You’re right. People can never imagine that in the future resource limits will have to increase beyond what we have now.

    “But why would you want to have more than 128 days?” Just because you can’t imagine it doesn’t mean it won’t happen. (See memory limits and processor speeds in the past.)

    Mark my words. One day this problem or something very similar will hit us hard. Everybody will be doing stuff that requires to go past these hard limits – they won’t be able to and the whole house of cards will come crashing down…

    [And there’s already a solution: The hardware timer. -Raymond]
  31. @Jonathan Gilbert:

    "…This means that the clock rate is 1193181 / 65536 = 18.2064971924…"

    I got to wrestle with the exact definition of this long ago (http://www.delorie.com/djgpp/mail-archives/browse.cgi?p=djgpp/2007/01/09/04:02:48), trying to rewrite the gettimeofday() function for DJGPP’s C runtime library so that it didn’t have to do two DOS INT21h call for each go… there’s a very detailed commend at the top of the file, followed by a bunch of ugly integer math to do successive approximations of the "real" value.

    The amount of digging it took to determine *exactly* what that value was, and why… *shudder*

  32. Rikard says:

    I’m guessing (or at least hoping) that the comments in question were intended as jokes.

Comments are closed.

Skip to main content