summaryrefslogtreecommitdiff
path: root/usr/src/grub/grub-0.97/docs/multiboot.info
blob: cb6009c09bcbabc997959f5acee3d1c50bba96af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
This is ../../docs/multiboot.info, produced by makeinfo version 4.7
from ../../docs/multiboot.texi.

INFO-DIR-SECTION Kernel
START-INFO-DIR-ENTRY
* Multiboot Specification: (multiboot).		Multiboot Specification.
END-INFO-DIR-ENTRY

   Copyright (C) 1995, 96 Bryan Ford <baford@cs.utah.edu> Copyright (C)
1995, 96 Erich Stefan Boleyn <erich@uruk.org> Copyright (C) 1999, 2000,
2001, 2002 Free Software Foundation, Inc.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the entire resulting derived work is distributed under the terms
of a permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions.


File: multiboot.info,  Node: Top,  Next: Overview,  Up: (dir)

Multiboot Specification
***********************

This file documents Multiboot Specification, the proposal for the boot
sequence standard. This edition documents version 0.6.93.

* Menu:

* Overview::
* Terminology::
* Specification::
* Examples::
* History::
* Index::


File: multiboot.info,  Node: Overview,  Next: Terminology,  Prev: Top,  Up: Top

1 Introduction to Multiboot Specification
*****************************************

This chapter describes some rough information on the Multiboot
Specification. Note that this is not a part of the specification itself.

* Menu:

* Motivation::
* Architecture::
* Operating systems::
* Boot sources::
* Boot-time configuration::
* Convenience to operating systems::
* Boot modules::


File: multiboot.info,  Node: Motivation,  Next: Architecture,  Up: Overview

1.1 The background of Multiboot Specification
=============================================

Every operating system ever created tends to have its own boot loader.
Installing a new operating system on a machine generally involves
installing a whole new set of boot mechanisms, each with completely
different install-time and boot-time user interfaces. Getting multiple
operating systems to coexist reliably on one machine through typical
"chaining" mechanisms can be a nightmare. There is little or no choice
of boot loaders for a particular operating system -- if the one that
comes with the operating system doesn't do exactly what you want, or
doesn't work on your machine, you're screwed.

   While we may not be able to fix this problem in existing commercial
operating systems, it shouldn't be too difficult for a few people in the
free operating system communities to put their heads together and solve
this problem for the popular free operating systems. That's what this
specification aims for. Basically, it specifies an interface between a
boot loader and a operating system, such that any complying boot loader
should be able to load any complying operating system. This
specification does _not_ specify how boot loaders should work -- only
how they must interface with the operating system being loaded.


File: multiboot.info,  Node: Architecture,  Next: Operating systems,  Prev: Motivation,  Up: Overview

1.2 The target architecture
===========================

This specification is primarily targeted at PC, since they are the most
common and have the largest variety of operating systems and boot
loaders. However, to the extent that certain other architectures may
need a boot specification and do not have one already, a variation of
this specification, stripped of the x86-specific details, could be
adopted for them as well.


File: multiboot.info,  Node: Operating systems,  Next: Boot sources,  Prev: Architecture,  Up: Overview

1.3 The target operating systems
================================

This specification is targeted toward free 32-bit operating systems
that can be fairly easily modified to support the specification without
going through lots of bureaucratic rigmarole. The particular free
operating systems that this specification is being primarily designed
for are Linux, FreeBSD, NetBSD, Mach, and VSTa. It is hoped that other
emerging free operating systems will adopt it from the start, and thus
immediately be able to take advantage of existing boot loaders. It would
be nice if commercial operating system vendors eventually adopted this
specification as well, but that's probably a pipe dream.


File: multiboot.info,  Node: Boot sources,  Next: Boot-time configuration,  Prev: Operating systems,  Up: Overview

1.4 Boot sources
================

It should be possible to write compliant boot loaders that load the OS
image from a variety of sources, including floppy disk, hard disk, and
across a network.

   Disk-based boot loaders may use a variety of techniques to find the
relevant OS image and boot module data on disk, such as by
interpretation of specific file systems (e.g. the BSD/Mach boot loader),
using precalculated "block lists" (e.g. LILO), loading from a special
"boot partition" (e.g. OS/2), or even loading from within another
operating system (e.g. the VSTa boot code, which loads from DOS).
Similarly, network-based boot loaders could use a variety of network
hardware and protocols.

   It is hoped that boot loaders will be created that support multiple
loading mechanisms, increasing their portability, robustness, and
user-friendliness.


File: multiboot.info,  Node: Boot-time configuration,  Next: Convenience to operating systems,  Prev: Boot sources,  Up: Overview

1.5 Configure an operating system at boot-time
==============================================

It is often necessary for one reason or another for the user to be able
to provide some configuration information to an operating system
dynamically at boot time. While this specification should not dictate
how this configuration information is obtained by the boot loader, it
should provide a standard means for the boot loader to pass such
information to the operating system.


File: multiboot.info,  Node: Convenience to operating systems,  Next: Boot modules,  Prev: Boot-time configuration,  Up: Overview

1.6 How to make OS development easier
=====================================

OS images should be easy to generate. Ideally, an OS image should simply
be an ordinary 32-bit executable file in whatever file format the
operating system normally uses. It should be possible to `nm' or
disassemble OS images just like normal executables. Specialized tools
should not be required to create OS images in a _special_ file format.
If this means shifting some work from the operating system to a boot
loader, that is probably appropriate, because all the memory consumed
by the boot loader will typically be made available again after the
boot process is created, whereas every bit of code in the OS image
typically has to remain in memory forever. The operating system should
not have to worry about getting into 32-bit mode initially, because mode
switching code generally needs to be in the boot loader anyway in order
to load operating system data above the 1MB boundary, and forcing the
operating system to do this makes creation of OS images much more
difficult.

   Unfortunately, there is a horrendous variety of executable file
formats even among free Unix-like PC-based operating systems --
generally a different format for each operating system. Most of the
relevant free operating systems use some variant of a.out format, but
some are moving to ELF. It is highly desirable for boot loaders not to
have to be able to interpret all the different types of executable file
formats in existence in order to load the OS image -- otherwise the
boot loader effectively becomes operating system specific again.

   This specification adopts a compromise solution to this problem.
Multiboot-compliant OS images always contain a magic "Multiboot header"
(*note OS image format::), which allows the boot loader to load the
image without having to understand numerous a.out variants or other
executable formats. This magic header does not need to be at the very
beginning of the executable file, so kernel images can still conform to
the local a.out format variant in addition to being Multiboot-compliant.


File: multiboot.info,  Node: Boot modules,  Prev: Convenience to operating systems,  Up: Overview

1.7 Boot modules
================

Many modern operating system kernels, such as those of VSTa and Mach, do
not by themselves contain enough mechanism to get the system fully
operational: they require the presence of additional software modules at
boot time in order to access devices, mount file systems, etc. While
these additional modules could be embedded in the main OS image along
with the kernel itself, and the resulting image be split apart manually
by the operating system when it receives control, it is often more
flexible, more space-efficient, and more convenient to the operating
system and user if the boot loader can load these additional modules
independently in the first place.

   Thus, this specification should provide a standard method for a boot
loader to indicate to the operating system what auxiliary boot modules
were loaded, and where they can be found. Boot loaders don't have to
support multiple boot modules, but they are strongly encouraged to,
because some operating systems will be unable to boot without them.


File: multiboot.info,  Node: Terminology,  Next: Specification,  Prev: Overview,  Up: Top

2 The definitions of terms used through the specification
*********************************************************

"must"
     We use the term "must", when any boot loader or OS image needs to
     follow a rule -- otherwise, the boot loader or OS image is _not_
     Multiboot-compliant.

"should"
     We use the term "should", when any boot loader or OS image is
     recommended to follow a rule, but it doesn't need to follow the
     rule.

"may"
     We use the term "may", when any boot loader or OS image is allowed
     to follow a rule.

"boot loader"
     Whatever program or set of programs loads the image of the final
     operating system to be run on the machine. The boot loader may
     itself consist of several stages, but that is an implementation
     detail not relevant to this specification. Only the _final_ stage
     of the boot loader -- the stage that eventually transfers control
     to an operating system -- must follow the rules specified in this
     document in order to be "Multiboot-compliant"; earlier boot loader
     stages may be designed in whatever way is most convenient.

"OS image"
     The initial binary image that a boot loader loads into memory and
     transfers control to start an operating system. The OS image is
     typically an executable containing the operating system kernel.

"boot module"
     Other auxiliary files that a boot loader loads into memory along
     with an OS image, but does not interpret in any way other than
     passing their locations to the operating system when it is invoked.

"Multiboot-compliant"
     A boot loader or an OS image which follows the rules defined as
     "must" is Multiboot-compliant. When this specification specifies a
     rule as "should" or "may", a Multiboot-complaint boot loader/OS
     image doesn't need to follow the rule.

"u8"
     The type of unsigned 8-bit data.

"u16"
     The type of unsigned 16-bit data. Because the target architecture
     is little-endian, u16 is coded in little-endian.

"u32"
     The type of unsigned 32-bit data. Because the target architecture
     is little-endian, u32 is coded in little-endian.

"u64"
     The type of unsigned 64-bit data. Because the target architecture
     is little-endian, u64 is coded in little-endian.


File: multiboot.info,  Node: Specification,  Next: Examples,  Prev: Terminology,  Up: Top

3 The exact definitions of Multiboot Specification
**************************************************

There are three main aspects of a boot loader/OS image interface:

  1. The format of an OS image as seen by a boot loader.

  2. The state of a machine when a boot loader starts an operating
     system.

  3. The format of information passed by a boot loader to an operating
     system.

* Menu:

* OS image format::
* Machine state::
* Boot information format::


File: multiboot.info,  Node: OS image format,  Next: Machine state,  Up: Specification

3.1 OS image format
===================

An OS image may be an ordinary 32-bit executable file in the standard
format for that particular operating system, except that it may be
linked at a non-default load address to avoid loading on top of the
PC's I/O region or other reserved areas, and of course it should not
use shared libraries or other fancy features.

   An OS image must contain an additional header called "Multiboot
header", besides the headers of the format used by the OS image. The
Multiboot header must be contained completely within the first 8192
bytes of the OS image, and must be longword (32-bit) aligned. In
general, it should come _as early as possible_, and may be embedded in
the beginning of the text segment after the _real_ executable header.

* Menu:

* Header layout::               The layout of Multiboot header
* Header magic fields::         The magic fields of Multiboot header
* Header address fields::
* Header graphics fields::


File: multiboot.info,  Node: Header layout,  Next: Header magic fields,  Up: OS image format

3.1.1 The layout of Multiboot header
------------------------------------

The layout of the Multiboot header must be as follows:

Offset  Type    Field Name     Note
0       u32     magic          required
4       u32     flags          required
8       u32     checksum       required
12      u32     header_addr    if flags[16] is set
16      u32     load_addr      if flags[16] is set
20      u32     load_end_addr  if flags[16] is set
24      u32     bss_end_addr   if flags[16] is set
28      u32     entry_addr     if flags[16] is set
32      u32     mode_type      if flags[2] is set
36      u32     width          if flags[2] is set
40      u32     height         if flags[2] is set
44      u32     depth          if flags[2] is set

   The fields `magic', `flags' and `checksum' are defined in *Note
Header magic fields::, the fields `header_addr', `load_addr',
`load_end_addr', `bss_end_addr' and `entry_addr' are defined in *Note
Header address fields::, and the fields `mode_type', `width', `height'
and `depth' are defind in *Note Header graphics fields::.


File: multiboot.info,  Node: Header magic fields,  Next: Header address fields,  Prev: Header layout,  Up: OS image format

3.1.2 The magic fields of Multiboot header
------------------------------------------

`magic'
     The field `magic' is the magic number identifying the header,
     which must be the hexadecimal value `0x1BADB002'.

`flags'
     The field `flags' specifies features that the OS image requests or
     requires of an boot loader. Bits 0-15 indicate requirements; if the
     boot loader sees any of these bits set but doesn't understand the
     flag or can't fulfill the requirements it indicates for some
     reason, it must notify the user and fail to load the OS image.
     Bits 16-31 indicate optional features; if any bits in this range
     are set but the boot loader doesn't understand them, it may simply
     ignore them and proceed as usual. Naturally, all as-yet-undefined
     bits in the `flags' word must be set to zero in OS images. This
     way, the `flags' fields serves for version control as well as
     simple feature selection.

     If bit 0 in the `flags' word is set, then all boot modules loaded
     along with the operating system must be aligned on page (4KB)
     boundaries. Some operating systems expect to be able to map the
     pages containing boot modules directly into a paged address space
     during startup, and thus need the boot modules to be page-aligned.

     If bit 1 in the `flags' word is set, then information on available
     memory via at least the `mem_*' fields of the Multiboot information
     structure (*note Boot information format::) must be included. If
     the boot loader is capable of passing a memory map (the `mmap_*'
     fields) and one exists, then it may be included as well.

     If bit 2 in the `flags' word is set, information about the video
     mode table (*note Boot information format::) must be available to
     the kernel.

     If bit 16 in the `flags' word is set, then the fields at offsets
     8-24 in the Multiboot header are valid, and the boot loader should
     use them instead of the fields in the actual executable header to
     calculate where to load the OS image. This information does not
     need to be provided if the kernel image is in ELF format, but it
     _must_ be provided if the images is in a.out format or in some
     other format. Compliant boot loaders must be able to load images
     that either are in ELF format or contain the load address
     information embedded in the Multiboot header; they may also
     directly support other executable formats, such as particular
     a.out variants, but are not required to.

`checksum'
     The field `checksum' is a 32-bit unsigned value which, when added
     to the other magic fields (i.e. `magic' and `flags'), must have a
     32-bit unsigned sum of zero.


File: multiboot.info,  Node: Header address fields,  Next: Header graphics fields,  Prev: Header magic fields,  Up: OS image format

3.1.3 The address fields of Multiboot header
--------------------------------------------

All of the address fields enabled by flag bit 16 are physical addresses.
The meaning of each is as follows:

`header_addr'
     Contains the address corresponding to the beginning of the
     Multiboot header -- the physical memory location at which the
     magic value is supposed to be loaded. This field serves to
     "synchronize" the mapping between OS image offsets and physical
     memory addresses.

`load_addr'
     Contains the physical address of the beginning of the text
     segment. The offset in the OS image file at which to start loading
     is defined by the offset at which the header was found, minus
     (header_addr - load_addr). load_addr must be less than or equal to
     header_addr.

`load_end_addr'
     Contains the physical address of the end of the data segment.
     (load_end_addr - load_addr) specifies how much data to load.  This
     implies that the text and data segments must be consecutive in the
     OS image; this is true for existing a.out executable formats.  If
     this field is zero, the boot loader assumes that the text and data
     segments occupy the whole OS image file.

`bss_end_addr'
     Contains the physical address of the end of the bss segment. The
     boot loader initializes this area to zero, and reserves the memory
     it occupies to avoid placing boot modules and other data relevant
     to the operating system in that area. If this field is zero, the
     boot loader assumes that no bss segment is present.

`entry_addr'
     The physical address to which the boot loader should jump in order
     to start running the operating system.


File: multiboot.info,  Node: Header graphics fields,  Prev: Header address fields,  Up: OS image format

3.1.4 The graphics fields of Multiboot header
---------------------------------------------

All of the graphics fields are enabled by flag bit 2. They specify the
preferred graphics mode. Note that that is only a _recommended_ mode by
the OS image. If the mode exists, the boot loader should set it, when
the user doesn't specify a mode explicitly. Otherwise, the boot loader
should fall back to a similar mode, if available.

   The meaning of each is as follows:

`mode_type'
     Contains `0' for linear graphics mode or `1' for EGA-standard text
     mode. Everything else is reserved for future expansion. Note that
     the boot loader may set a text mode, even if this field contains
     `0'.

`width'
     Contains the number of the columns. This is specified in pixels in
     a graphics mode, and in characters in a text mode. The value zero
     indicates that the OS image has no preference.

`height'
     Contains the number of the lines. This is specified in pixels in a
     graphics mode, and in characters in a text mode. The value zero
     indicates that the OS image has no preference.

`depth'
     Contains the number of bits per pixel in a graphics mode, and zero
     in a text mode. The value zero indicates that the OS image has no
     preference.


File: multiboot.info,  Node: Machine state,  Next: Boot information format,  Prev: OS image format,  Up: Specification

3.2 Machine state
=================

When the boot loader invokes the 32-bit operating system, the machine
must have the following state:

`EAX'
     Must contain the magic value `0x2BADB002'; the presence of this
     value indicates to the operating system that it was loaded by a
     Multiboot-compliant boot loader (e.g. as opposed to another type of
     boot loader that the operating system can also be loaded from).

`EBX'
     Must contain the 32-bit physical address of the Multiboot
     information structure provided by the boot loader (*note Boot
     information format::).

`CS'
     Must be a 32-bit read/execute code segment with an offset of `0'
     and a limit of `0xFFFFFFFF'. The exact value is undefined.

`DS'
`ES'
`FS'
`GS'
`SS'
     Must be a 32-bit read/write data segment with an offset of `0' and
     a limit of `0xFFFFFFFF'. The exact values are all undefined.

`A20 gate'
     Must be enabled.

`CR0'
     Bit 31 (PG) must be cleared. Bit 0 (PE) must be set. Other bits are
     all undefined.

`EFLAGS'
     Bit 17 (VM) must be cleared. Bit 9 (IF) must be cleared. Other bits
     are all undefined.

   All other processor registers and flag bits are undefined. This
includes, in particular:

`ESP'
     The OS image must create its own stack as soon as it needs one.

`GDTR'
     Even though the segment registers are set up as described above,
     the `GDTR' may be invalid, so the OS image must not load any
     segment registers (even just reloading the same values!) until it
     sets up its own `GDT'.

`IDTR'
     The OS image must leave interrupts disabled until it sets up its
     own `IDT'.

   However, other machine state should be left by the boot loader in
"normal working order", i.e. as initialized by the BIOS (or DOS, if
that's what the boot loader runs from). In other words, the operating
system should be able to make BIOS calls and such after being loaded,
as long as it does not overwrite the BIOS data structures before doing
so. Also, the boot loader must leave the PIC programmed with the normal
BIOS/DOS values, even if it changed them during the switch to 32-bit
mode.


File: multiboot.info,  Node: Boot information format,  Prev: Machine state,  Up: Specification

3.3 Boot information format
===========================

FIXME: Split this chapter like the chapter "OS image format".

   Upon entry to the operating system, the `EBX' register contains the
physical address of a "Multiboot information" data structure, through
which the boot loader communicates vital information to the operating
system. The operating system can use or ignore any parts of the
structure as it chooses; all information passed by the boot loader is
advisory only.

   The Multiboot information structure and its related substructures
may be placed anywhere in memory by the boot loader (with the exception
of the memory reserved for the kernel and boot modules, of course). It
is the operating system's responsibility to avoid overwriting this
memory until it is done using it.

   The format of the Multiboot information structure (as defined so far)
follows:

             +-------------------+
     0       | flags             |    (required)
             +-------------------+
     4       | mem_lower         |    (present if flags[0] is set)
     8       | mem_upper         |    (present if flags[0] is set)
             +-------------------+
     12      | boot_device       |    (present if flags[1] is set)
             +-------------------+
     16      | cmdline           |    (present if flags[2] is set)
             +-------------------+
     20      | mods_count        |    (present if flags[3] is set)
     24      | mods_addr         |    (present if flags[3] is set)
             +-------------------+
     28 - 40 | syms              |    (present if flags[4] or
             |                   |                flags[5] is set)
             +-------------------+
     44      | mmap_length       |    (present if flags[6] is set)
     48      | mmap_addr         |    (present if flags[6] is set)
             +-------------------+
     52      | drives_length     |    (present if flags[7] is set)
     56      | drives_addr       |    (present if flags[7] is set)
             +-------------------+
     60      | config_table      |    (present if flags[8] is set)
             +-------------------+
     64      | boot_loader_name  |    (present if flags[9] is set)
             +-------------------+
     68      | apm_table         |    (present if flags[10] is set)
             +-------------------+
     72      | vbe_control_info  |    (present if flags[11] is set)
     76      | vbe_mode_info     |
     80      | vbe_mode          |
     82      | vbe_interface_seg |
     84      | vbe_interface_off |
     86      | vbe_interface_len |
             +-------------------+

   The first longword indicates the presence and validity of other
fields in the Multiboot information structure. All as-yet-undefined
bits must be set to zero by the boot loader. Any set bits that the
operating system does not understand should be ignored. Thus, the
`flags' field also functions as a version indicator, allowing the
Multiboot information structure to be expanded in the future without
breaking anything.

   If bit 0 in the `flags' word is set, then the `mem_*' fields are
valid. `mem_lower' and `mem_upper' indicate the amount of lower and
upper memory, respectively, in kilobytes. Lower memory starts at
address 0, and upper memory starts at address 1 megabyte. The maximum
possible value for lower memory is 640 kilobytes. The value returned for
upper memory is maximally the address of the first upper memory hole
minus 1 megabyte. It is not guaranteed to be this value.

   If bit 1 in the `flags' word is set, then the `boot_device' field is
valid, and indicates which BIOS disk device the boot loader loaded the
OS image from. If the OS image was not loaded from a BIOS disk, then
this field must not be present (bit 3 must be clear). The operating
system may use this field as a hint for determining its own "root"
device, but is not required to. The `boot_device' field is laid out in
four one-byte subfields as follows:

     +-------+-------+-------+-------+
     | drive | part1 | part2 | part3 |
     +-------+-------+-------+-------+

   The first byte contains the BIOS drive number as understood by the
BIOS INT 0x13 low-level disk interface: e.g. 0x00 for the first floppy
disk or 0x80 for the first hard disk.

   The three remaining bytes specify the boot partition. `part1'
specifies the "top-level" partition number, `part2' specifies a
"sub-partition" in the top-level partition, etc. Partition numbers
always start from zero. Unused partition bytes must be set to 0xFF. For
example, if the disk is partitioned using a simple one-level DOS
partitioning scheme, then `part1' contains the DOS partition number,
and `part2' and `part3' are both 0xFF. As another example, if a disk is
partitioned first into DOS partitions, and then one of those DOS
partitions is subdivided into several BSD partitions using BSD's
"disklabel" strategy, then `part1' contains the DOS partition number,
`part2' contains the BSD sub-partition within that DOS partition, and
`part3' is 0xFF.

   DOS extended partitions are indicated as partition numbers starting
from 4 and increasing, rather than as nested sub-partitions, even
though the underlying disk layout of extended partitions is
hierarchical in nature. For example, if the boot loader boots from the
second extended partition on a disk partitioned in conventional DOS
style, then `part1' will be 5, and `part2' and `part3' will both be
0xFF.

   If bit 2 of the `flags' longword is set, the `cmdline' field is
valid, and contains the physical address of the command line to be
passed to the kernel. The command line is a normal C-style
zero-terminated string.

   If bit 3 of the `flags' is set, then the `mods' fields indicate to
the kernel what boot modules were loaded along with the kernel image,
and where they can be found. `mods_count' contains the number of
modules loaded; `mods_addr' contains the physical address of the first
module structure. `mods_count' may be zero, indicating no boot modules
were loaded, even if bit 1 of `flags' is set. Each module structure is
formatted as follows:

             +-------------------+
     0       | mod_start         |
     4       | mod_end           |
             +-------------------+
     8       | string            |
             +-------------------+
     12      | reserved (0)      |
             +-------------------+

   The first two fields contain the start and end addresses of the boot
module itself. The `string' field provides an arbitrary string to be
associated with that particular boot module; it is a zero-terminated
ASCII string, just like the kernel command line. The `string' field may
be 0 if there is no string associated with the module. Typically the
string might be a command line (e.g. if the operating system treats boot
modules as executable programs), or a pathname (e.g. if the operating
system treats boot modules as files in a file system), but its exact use
is specific to the operating system. The `reserved' field must be set
to 0 by the boot loader and ignored by the operating system.

   *Caution:* Bits 4 & 5 are mutually exclusive.

   If bit 4 in the `flags' word is set, then the following fields in
the Multiboot information structure starting at byte 28 are valid:

             +-------------------+
     28      | tabsize           |
     32      | strsize           |
     36      | addr              |
     40      | reserved (0)      |
             +-------------------+

   These indicate where the symbol table from an a.out kernel image can
be found. `addr' is the physical address of the size (4-byte unsigned
long) of an array of a.out format "nlist" structures, followed
immediately by the array itself, then the size (4-byte unsigned long) of
a set of zero-terminated ASCII strings (plus sizeof(unsigned long) in
this case), and finally the set of strings itself. `tabsize' is equal
to its size parameter (found at the beginning of the symbol section),
and `strsize' is equal to its size parameter (found at the beginning of
the string section) of the following string table to which the symbol
table refers. Note that `tabsize' may be 0, indicating no symbols, even
if bit 4 in the `flags' word is set.

   If bit 5 in the `flags' word is set, then the following fields in
the Multiboot information structure starting at byte 28 are valid:

             +-------------------+
     28      | num               |
     32      | size              |
     36      | addr              |
     40      | shndx             |
             +-------------------+

   These indicate where the section header table from an ELF kernel is,
the size of each entry, number of entries, and the string table used as
the index of names. They correspond to the `shdr_*' entries
(`shdr_num', etc.) in the Executable and Linkable Format (ELF)
specification in the program header. All sections are loaded, and the
physical address fields of the ELF section header then refer to where
the sections are in memory (refer to the i386 ELF documentation for
details as to how to read the section header(s)). Note that `shdr_num'
may be 0, indicating no symbols, even if bit 5 in the `flags' word is
set.

   If bit 6 in the `flags' word is set, then the `mmap_*' fields are
valid, and indicate the address and length of a buffer containing a
memory map of the machine provided by the BIOS. `mmap_addr' is the
address, and `mmap_length' is the total size of the buffer. The buffer
consists of one or more of the following size/structure pairs (`size'
is really used for skipping to the next pair):

             +-------------------+
     -4      | size              |
             +-------------------+
     0       | base_addr_low     |
     4       | base_addr_high    |
     8       | length_low        |
     12      | length_high       |
     16      | type              |
             +-------------------+

   where `size' is the size of the associated structure in bytes, which
can be greater than the minimum of 20 bytes. `base_addr_low' is the
lower 32 bits of the starting address, and `base_addr_high' is the
upper 32 bits, for a total of a 64-bit starting address. `length_low'
is the lower 32 bits of the size of the memory region in bytes, and
`length_high' is the upper 32 bits, for a total of a 64-bit length.
`type' is the variety of address range represented, where a value of 1
indicates available RAM, and all other values currently indicated a
reserved area.

   The map provided is guaranteed to list all standard RAM that should
be available for normal use.

   If bit 7 in the `flags' is set, then the `drives_*' fields are
valid, and indicate the address of the physical address of the first
drive structure and the size of drive structures. `drives_addr' is the
address, and `drives_length' is the total size of drive structures.
Note that `drives_length' may be zero. Each drive structure is
formatted as follows:

             +-------------------+
     0       | size              |
             +-------------------+
     4       | drive_number      |
             +-------------------+
     5       | drive_mode        |
             +-------------------+
     6       | drive_cylinders   |
     8       | drive_heads       |
     9       | drive_sectors     |
             +-------------------+
     10 - xx | drive_ports       |
             +-------------------+

   The `size' field specifies the size of this structure. The size
varies, depending on the number of ports. Note that the size may not be
equal to (10 + 2 * the number of ports), because of an alignment.

   The `drive_number' field contains the BIOS drive number. The
`drive_mode' field represents the access mode used by the boot loader.
Currently, the following modes are defined:

`0'
     CHS mode (traditional cylinder/head/sector addressing mode).

`1'
     LBA mode (Logical Block Addressing mode).

   The three fields, `drive_cylinders', `drive_heads' and
`drive_sectors', indicate the geometry of the drive detected by the
BIOS. `drive_cylinders' contains the number of the cylinders.
`drive_heads' contains the number of the heads. `drive_sectors'
contains the number of the sectors per track.

   The `drive_ports' field contains the array of the I/O ports used for
the drive in the BIOS code. The array consists of zero or more unsigned
two-bytes integers, and is terminated with zero. Note that the array
may contain any number of I/O ports that are not related to the drive
actually (such as DMA controller's ports).

   If bit 8 in the `flags' is set, then the `config_table' field is
valid, and indicates the address of the ROM configuration table
returned by the "GET CONFIGURATION" BIOS call. If the BIOS call fails,
then the size of the table must be _zero_.

   If bit 9 in the `flags' is set, the `boot_loader_name' field is
valid, and contains the physical address of the name of a boot loader
booting the kernel. The name is a normal C-style zero-terminated string.

   If bit 10 in the `flags' is set, the `apm_table' field is valid, and
contains the physical address of an APM table defined as below:

             +----------------------+
     0       | version              |
     2       | cseg                 |
     4       | offset               |
     8       | cseg_16              |
     10      | dseg                 |
     12      | flags                |
     14      | cseg_len             |
     16      | cseg_16_len          |
     18      | dseg_len             |
             +----------------------+

   The fields `version', `cseg', `offset', `cseg_16', `dseg', `flags',
`cseg_len', `cseg_16_len', `dseg_len' indicate the version number, the
protected mode 32-bit code segment, the offset of the entry point, the
protected mode 16-bit code segment, the protected mode 16-bit data
segment, the flags, the length of the protected mode 32-bit code
segment, the length of the protected mode 16-bit code segment, and the
length of the protected mode 16-bit data segment, respectively. Only
the field `offset' is 4 bytes, and the others are 2 bytes. See Advanced
Power Management (APM) BIOS Interface Specification
(http://www.microsoft.com/hwdev/busbios/amp_12.htm), for more
information.

   If bit 11 in the `flags' is set, the graphics table is available.
This must only be done if the kernel has indicated in the `Multiboot
Header' that it accepts a graphics mode.

   The fields `vbe_control_info' and `vbe_mode_info' contain the
physical addresses of VBE control information returned by the VBE
Function 00h and VBE mode information returned by the VBE Function 01h,
respectively.

   The field `vbe_mode' indicates current video mode in the format
specified in VBE 3.0.

   The rest fields `vbe_interface_seg', `vbe_interface_off', and
`vbe_interface_len' contain the table of a protected mode interface
defined in VBE 2.0+. If this information is not available, those fields
contain zero. Note that VBE 3.0 defines another protected mode
interface which is incompatible with the old one. If you want to use
the new protected mode interface, you will have to find the table
yourself.

   The fields for the graphics table are designed for VBE, but
Multiboot boot loaders may simulate VBE on non-VBE modes, as if they
were VBE modes.


File: multiboot.info,  Node: Examples,  Next: History,  Prev: Specification,  Up: Top

4 Examples
**********

*Caution:* The following items are not part of the specification
document, but are included for prospective operating system and boot
loader writers.

* Menu:

* Notes on PC::
* BIOS device mapping techniques::
* Example OS code::
* Example boot loader code::


File: multiboot.info,  Node: Notes on PC,  Next: BIOS device mapping techniques,  Up: Examples

4.1 Notes on PC
===============

In reference to bit 0 of the `flags' parameter in the Multiboot
information structure, if the bootloader in question uses older BIOS
interfaces, or the newest ones are not available (see description about
bit 6), then a maximum of either 15 or 63 megabytes of memory may be
reported. It is _highly_ recommended that boot loaders perform a
thorough memory probe.

   In reference to bit 1 of the `flags' parameter in the Multiboot
information structure, it is recognized that determination of which
BIOS drive maps to which device driver in an operating system is
non-trivial, at best. Many kludges have been made to various operating
systems instead of solving this problem, most of them breaking under
many conditions. To encourage the use of general-purpose solutions to
this problem, there are 2 BIOS device mapping techniques (*note BIOS
device mapping techniques::).

   In reference to bit 6 of the `flags' parameter in the Multiboot
information structure, it is important to note that the data structure
used there (starting with `BaseAddrLow') is the data returned by the
INT 15h, AX=E820h -- Query System Address Map call. See *Note Query
System Address Map: (grub.info)Query System Address Map, for more
information. The interface here is meant to allow a boot loader to work
unmodified with any reasonable extensions of the BIOS interface,
passing along any extra data to be interpreted by the operating system
as desired.


File: multiboot.info,  Node: BIOS device mapping techniques,  Next: Example OS code,  Prev: Notes on PC,  Up: Examples

4.2 BIOS device mapping techniques
==================================

Both of these techniques should be usable from any PC operating system,
and neither require any special support in the drivers themselves. This
section will be flushed out into detailed explanations, particularly for
the I/O restriction technique.

   The general rule is that the data comparison technique is the quick
and dirty solution. It works most of the time, but doesn't cover all the
bases, and is relatively simple.

   The I/O restriction technique is much more complex, but it has
potential to solve the problem under all conditions, plus allow access
of the remaining BIOS devices when not all of them have operating system
drivers.

* Menu:

* Data comparison technique::
* I/O restriction technique::


File: multiboot.info,  Node: Data comparison technique,  Next: I/O restriction technique,  Up: BIOS device mapping techniques

4.2.1 Data comparison technique
-------------------------------

Before activating _any_ of the device drivers, gather enough data from
similar sectors on each of the disks such that each one can be uniquely
identified.

   After activating the device drivers, compare data from the drives
using the operating system drivers. This should hopefully be sufficient
to provide such a mapping.

   Problems:

  1. The data on some BIOS devices might be identical (so the part
     reading the drives from the BIOS should have some mechanism to give
     up).

  2. There might be extra drives not accessible from the BIOS which are
     identical to some drive used by the BIOS (so it should be capable
     of giving up there as well).


File: multiboot.info,  Node: I/O restriction technique,  Prev: Data comparison technique,  Up: BIOS device mapping techniques

4.2.2 I/O restriction technique
-------------------------------

This first step may be unnecessary, but first create copy-on-write
mappings for the device drivers writing into PC RAM. Keep the original
copies for the "clean BIOS virtual machine" to be created later.

   For each device driver brought online, determine which BIOS devices
become inaccessible by:

  1. Create a "clean BIOS virtual machine".

  2. Set the I/O permission map for the I/O area claimed by the device
     driver to no permissions (neither read nor write).

  3. Access each device.

  4. Record which devices succeed, and those which try to access the
     "restricted" I/O areas (hopefully, this will be an "xor"
     situation).

   For each device driver, given how many of the BIOS devices were
subsumed by it (there should be no gaps in this list), it should be easy
to determine which devices on the controller these are.

   In general, you have at most 2 disks from each controller given BIOS
numbers, but they pretty much always count from the lowest logically
numbered devices on the controller.


File: multiboot.info,  Node: Example OS code,  Next: Example boot loader code,  Prev: BIOS device mapping techniques,  Up: Examples

4.3 Example OS code
===================

In this distribution, the example Multiboot kernel `kernel' is
included. The kernel just prints out the Multiboot information structure
on the screen, so you can make use of the kernel to test a
Multiboot-compliant boot loader and for reference to how to implement a
Multiboot kernel. The source files can be found under the directory
`docs' in the GRUB distribution.

   The kernel `kernel' consists of only three files: `boot.S',
`kernel.c' and `multiboot.h'. The assembly source `boot.S' is written
in GAS (*note GNU assembler: (as.info)Top.), and contains the Multiboot
information structure to comply with the specification. When a
Multiboot-compliant boot loader loads and execute it, it initialize the
stack pointer and `EFLAGS', and then call the function `cmain' defined
in `kernel.c'. If `cmain' returns to the callee, then it shows a
message to inform the user of the halt state and stops forever until
you push the reset key. The file `kernel.c' contains the function
`cmain', which checks if the magic number passed by the boot loader is
valid and so on, and some functions to print messages on the screen.
The file `multiboot.h' defines some macros, such as the magic number
for the Multiboot header, the Multiboot header structure and the
Multiboot information structure.

* Menu:

* multiboot.h::
* boot.S::
* kernel.c::
* Other Multiboot kernels::


File: multiboot.info,  Node: multiboot.h,  Next: boot.S,  Up: Example OS code

4.3.1 multiboot.h
-----------------

This is the source code in the file `multiboot.h':

     /* multiboot.h - the header for Multiboot */
     /* Copyright (C) 1999, 2001  Free Software Foundation, Inc.

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

     /* Macros. */

     /* The magic number for the Multiboot header. */
     #define MULTIBOOT_HEADER_MAGIC          0x1BADB002

     /* The flags for the Multiboot header. */
     #ifdef __ELF__
     # define MULTIBOOT_HEADER_FLAGS         0x00000003
     #else
     # define MULTIBOOT_HEADER_FLAGS         0x00010003
     #endif

     /* The magic number passed by a Multiboot-compliant boot loader. */
     #define MULTIBOOT_BOOTLOADER_MAGIC      0x2BADB002

     /* The size of our stack (16KB). */
     #define STACK_SIZE                      0x4000

     /* C symbol format. HAVE_ASM_USCORE is defined by configure. */
     #ifdef HAVE_ASM_USCORE
     # define EXT_C(sym)                     _ ## sym
     #else
     # define EXT_C(sym)                     sym
     #endif

     #ifndef ASM
     /* Do not include here in boot.S. */

     /* Types. */

     /* The Multiboot header. */
     typedef struct multiboot_header
     {
       unsigned long magic;
       unsigned long flags;
       unsigned long checksum;
       unsigned long header_addr;
       unsigned long load_addr;
       unsigned long load_end_addr;
       unsigned long bss_end_addr;
       unsigned long entry_addr;
     } multiboot_header_t;

     /* The symbol table for a.out. */
     typedef struct aout_symbol_table
     {
       unsigned long tabsize;
       unsigned long strsize;
       unsigned long addr;
       unsigned long reserved;
     } aout_symbol_table_t;

     /* The section header table for ELF. */
     typedef struct elf_section_header_table
     {
       unsigned long num;
       unsigned long size;
       unsigned long addr;
       unsigned long shndx;
     } elf_section_header_table_t;

     /* The Multiboot information. */
     typedef struct multiboot_info
     {
       unsigned long flags;
       unsigned long mem_lower;
       unsigned long mem_upper;
       unsigned long boot_device;
       unsigned long cmdline;
       unsigned long mods_count;
       unsigned long mods_addr;
       union
       {
         aout_symbol_table_t aout_sym;
         elf_section_header_table_t elf_sec;
       } u;
       unsigned long mmap_length;
       unsigned long mmap_addr;
     } multiboot_info_t;

     /* The module structure. */
     typedef struct module
     {
       unsigned long mod_start;
       unsigned long mod_end;
       unsigned long string;
       unsigned long reserved;
     } module_t;

     /* The memory map. Be careful that the offset 0 is base_addr_low
        but no size. */
     typedef struct memory_map
     {
       unsigned long size;
       unsigned long base_addr_low;
       unsigned long base_addr_high;
       unsigned long length_low;
       unsigned long length_high;
       unsigned long type;
     } memory_map_t;

     #endif /* ! ASM */


File: multiboot.info,  Node: boot.S,  Next: kernel.c,  Prev: multiboot.h,  Up: Example OS code

4.3.2 boot.S
------------

In the file `boot.S':

     /* boot.S - bootstrap the kernel */
     /* Copyright (C) 1999, 2001  Free Software Foundation, Inc.

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

     #define ASM     1
     #include <multiboot.h>

             .text

             .globl  start, _start
     start:
     _start:
             jmp     multiboot_entry

             /* Align 32 bits boundary. */
             .align  4

             /* Multiboot header. */
     multiboot_header:
             /* magic */
             .long   MULTIBOOT_HEADER_MAGIC
             /* flags */
             .long   MULTIBOOT_HEADER_FLAGS
             /* checksum */
             .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
     #ifndef __ELF__
             /* header_addr */
             .long   multiboot_header
             /* load_addr */
             .long   _start
             /* load_end_addr */
             .long   _edata
             /* bss_end_addr */
             .long   _end
             /* entry_addr */
             .long   multiboot_entry
     #endif /* ! __ELF__ */

     multiboot_entry:
             /* Initialize the stack pointer. */
             movl    $(stack + STACK_SIZE), %esp

             /* Reset EFLAGS. */
             pushl   $0
             popf

             /* Push the pointer to the Multiboot information structure. */
             pushl   %ebx
             /* Push the magic value. */
             pushl   %eax

             /* Now enter the C main function... */
             call    EXT_C(cmain)

             /* Halt. */
             pushl   $halt_message
             call    EXT_C(printf)

     loop:   hlt
             jmp     loop

     halt_message:
             .asciz  "Halted."

             /* Our stack area. */
             .comm   stack, STACK_SIZE


File: multiboot.info,  Node: kernel.c,  Next: Other Multiboot kernels,  Prev: boot.S,  Up: Example OS code

4.3.3 kernel.c
--------------

And, in the file `kernel.c':

     /* kernel.c - the C part of the kernel */
     /* Copyright (C) 1999  Free Software Foundation, Inc.

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

     #include <multiboot.h>

     /* Macros. */

     /* Check if the bit BIT in FLAGS is set. */
     #define CHECK_FLAG(flags,bit)   ((flags) & (1 << (bit)))

     /* Some screen stuff. */
     /* The number of columns. */
     #define COLUMNS                 80
     /* The number of lines. */
     #define LINES                   24
     /* The attribute of an character. */
     #define ATTRIBUTE               7
     /* The video memory address. */
     #define VIDEO                   0xB8000

     /* Variables. */
     /* Save the X position. */
     static int xpos;
     /* Save the Y position. */
     static int ypos;
     /* Point to the video memory. */
     static volatile unsigned char *video;

     /* Forward declarations. */
     void cmain (unsigned long magic, unsigned long addr);
     static void cls (void);
     static void itoa (char *buf, int base, int d);
     static void putchar (int c);
     void printf (const char *format, ...);

     /* Check if MAGIC is valid and print the Multiboot information structure
        pointed by ADDR. */
     void
     cmain (unsigned long magic, unsigned long addr)
     {
       multiboot_info_t *mbi;

       /* Clear the screen. */
       cls ();

       /* Am I booted by a Multiboot-compliant boot loader? */
       if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
         {
           printf ("Invalid magic number: 0x%x\n", (unsigned) magic);
           return;
         }

       /* Set MBI to the address of the Multiboot information structure. */
       mbi = (multiboot_info_t *) addr;

       /* Print out the flags. */
       printf ("flags = 0x%x\n", (unsigned) mbi->flags);

       /* Are mem_* valid? */
       if (CHECK_FLAG (mbi->flags, 0))
         printf ("mem_lower = %uKB, mem_upper = %uKB\n",
                 (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);

       /* Is boot_device valid? */
       if (CHECK_FLAG (mbi->flags, 1))
         printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device);

       /* Is the command line passed? */
       if (CHECK_FLAG (mbi->flags, 2))
         printf ("cmdline = %s\n", (char *) mbi->cmdline);

       /* Are mods_* valid? */
       if (CHECK_FLAG (mbi->flags, 3))
         {
           module_t *mod;
           int i;

           printf ("mods_count = %d, mods_addr = 0x%x\n",
                   (int) mbi->mods_count, (int) mbi->mods_addr);
           for (i = 0, mod = (module_t *) mbi->mods_addr;
                i < mbi->mods_count;
                i++, mod++)
             printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
                     (unsigned) mod->mod_start,
                     (unsigned) mod->mod_end,
                     (char *) mod->string);
         }

       /* Bits 4 and 5 are mutually exclusive! */
       if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
         {
           printf ("Both bits 4 and 5 are set.\n");
           return;
         }

       /* Is the symbol table of a.out valid? */
       if (CHECK_FLAG (mbi->flags, 4))
         {
           aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);

           printf ("aout_symbol_table: tabsize = 0x%0x, "
                   "strsize = 0x%x, addr = 0x%x\n",
                   (unsigned) aout_sym->tabsize,
                   (unsigned) aout_sym->strsize,
                   (unsigned) aout_sym->addr);
         }

       /* Is the section header table of ELF valid? */
       if (CHECK_FLAG (mbi->flags, 5))
         {
           elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);

           printf ("elf_sec: num = %u, size = 0x%x,"
                   " addr = 0x%x, shndx = 0x%x\n",
                   (unsigned) elf_sec->num, (unsigned) elf_sec->size,
                   (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
         }

       /* Are mmap_* valid? */
       if (CHECK_FLAG (mbi->flags, 6))
         {
           memory_map_t *mmap;

           printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
                   (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
           for (mmap = (memory_map_t *) mbi->mmap_addr;
                (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
                mmap = (memory_map_t *) ((unsigned long) mmap
                                         + mmap->size + sizeof (mmap->size)))
             printf (" size = 0x%x, base_addr = 0x%x%x,"
                     " length = 0x%x%x, type = 0x%x\n",
                     (unsigned) mmap->size,
                     (unsigned) mmap->base_addr_high,
                     (unsigned) mmap->base_addr_low,
                     (unsigned) mmap->length_high,
                     (unsigned) mmap->length_low,
                     (unsigned) mmap->type);
         }
     }

     /* Clear the screen and initialize VIDEO, XPOS and YPOS. */
     static void
     cls (void)
     {
       int i;

       video = (unsigned char *) VIDEO;

       for (i = 0; i < COLUMNS * LINES * 2; i++)
         *(video + i) = 0;

       xpos = 0;
       ypos = 0;
     }

     /* Convert the integer D to a string and save the string in BUF. If
        BASE is equal to 'd', interpret that D is decimal, and if BASE is
        equal to 'x', interpret that D is hexadecimal. */
     static void
     itoa (char *buf, int base, int d)
     {
       char *p = buf;
       char *p1, *p2;
       unsigned long ud = d;
       int divisor = 10;

       /* If %d is specified and D is minus, put `-' in the head. */
       if (base == 'd' && d < 0)
         {
           *p++ = '-';
           buf++;
           ud = -d;
         }
       else if (base == 'x')
         divisor = 16;

       /* Divide UD by DIVISOR until UD == 0. */
       do
         {
           int remainder = ud % divisor;

           *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
         }
       while (ud /= divisor);

       /* Terminate BUF. */
       *p = 0;

       /* Reverse BUF. */
       p1 = buf;
       p2 = p - 1;
       while (p1 < p2)
         {
           char tmp = *p1;
           *p1 = *p2;
           *p2 = tmp;
           p1++;
           p2--;
         }
     }

     /* Put the character C on the screen. */
     static void
     putchar (int c)
     {
       if (c == '\n' || c == '\r')
         {
         newline:
           xpos = 0;
           ypos++;
           if (ypos >= LINES)
             ypos = 0;
           return;
         }

       *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
       *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;

       xpos++;
       if (xpos >= COLUMNS)
         goto newline;
     }

     /* Format a string and print it on the screen, just like the libc
        function printf. */
     void
     printf (const char *format, ...)
     {
       char **arg = (char **) &format;
       int c;
       char buf[20];

       arg++;

       while ((c = *format++) != 0)
         {
           if (c != '%')
             putchar (c);
           else
             {
               char *p;

               c = *format++;
               switch (c)
                 {
                 case 'd':
                 case 'u':
                 case 'x':
                   itoa (buf, c, *((int *) arg++));
                   p = buf;
                   goto string;
                   break;

                 case 's':
                   p = *arg++;
                   if (! p)
                     p = "(null)";

                 string:
                   while (*p)
                     putchar (*p++);
                   break;

                 default:
                   putchar (*((int *) arg++));
                   break;
                 }
             }
         }
     }


File: multiboot.info,  Node: Other Multiboot kernels,  Prev: kernel.c,  Up: Example OS code

4.3.4 Other Multiboot kernels
-----------------------------

Other useful information should be available in Multiboot kernels, such
as GNU Mach and Fiasco `http://os.inf.tu-dresden.de/fiasco/'. And, it
is worth mentioning the OSKit
`http://www.cs.utah.edu/projects/flux/oskit/', which provides a library
supporting the specification.


File: multiboot.info,  Node: Example boot loader code,  Prev: Example OS code,  Up: Examples

4.4 Example boot loader code
============================

The GNU GRUB (*note GRUB: (grub.info)Top.) project is a full
Multiboot-compliant boot loader, supporting all required and optional
features present in this specification. A public release has not been
made, but the test release is available from:

   `ftp://alpha.gnu.org/gnu/grub'

   See the webpage `http://www.gnu.org/software/grub/grub.html', for
more information.


File: multiboot.info,  Node: History,  Next: Index,  Prev: Examples,  Up: Top

5 The change log of this specification
**************************************

0.7
        * "Multiboot Standard" is renamed to "Multiboot Specification".

        * Graphics fields are added to Multiboot header.

        * BIOS drive information, BIOS configuration table, the name of
          a boot loader, APM information, and graphics information are
          added to Multiboot information.

        * Rewritten in Texinfo format.

        * Rewritten, using more strict words.

        * The maintainer changes to the GNU GRUB maintainer team
          <bug-grub@gnu.org>, from Bryan Ford and Erich Stefan Boleyn.

0.6
        * A few wording changes.

        * Header checksum.

        * Clasification of machine state passed to an operating system.

0.5
        * Name change.

0.4
        * Major changes plus HTMLification.


File: multiboot.info,  Node: Index,  Prev: History,  Up: Top

Index
*****

[Index]
* Menu:


Tag Table:
Node: Top990
Node: Overview1326
Node: Motivation1794
Node: Architecture3191
Node: Operating systems3724
Node: Boot sources4518
Node: Boot-time configuration5488
Node: Convenience to operating systems6096
Node: Boot modules8327
Node: Terminology9476
Node: Specification11855
Node: OS image format12418
Node: Header layout13476
Node: Header magic fields14644
Node: Header address fields17505
Node: Header graphics fields19351
Node: Machine state20737
Node: Boot information format22997
Node: Examples38368
Node: Notes on PC38741
Node: BIOS device mapping techniques40307
Node: Data comparison technique41217
Node: I/O restriction technique42079
Node: Example OS code43296
Node: multiboot.h44838
Node: boot.S48662
Node: kernel.c51286
Node: Other Multiboot kernels60013
Node: Example boot loader code60444
Node: History60970
Node: Index61891

End Tag Table