Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
90ff4d27
Commit
90ff4d27
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.3.21
parent
0983223c
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2311 additions
and
2326 deletions
+2311
-2326
Documentation/fb/framebuffer.txt
Documentation/fb/framebuffer.txt
+20
-3
arch/i386/boot/Makefile
arch/i386/boot/Makefile
+20
-23
arch/i386/boot/bootsect.S
arch/i386/boot/bootsect.S
+324
-365
arch/i386/boot/compressed/Makefile
arch/i386/boot/compressed/Makefile
+1
-1
arch/i386/boot/setup.S
arch/i386/boot/setup.S
+645
-660
arch/i386/boot/tools/build.c
arch/i386/boot/tools/build.c
+7
-25
arch/i386/boot/video.S
arch/i386/boot/video.S
+1175
-1210
arch/i386/defconfig
arch/i386/defconfig
+46
-0
drivers/char/qpmouse.c
drivers/char/qpmouse.c
+2
-2
drivers/net/Config.in
drivers/net/Config.in
+3
-3
drivers/scsi/imm.c
drivers/scsi/imm.c
+1
-8
drivers/video/fbmem.c
drivers/video/fbmem.c
+5
-0
fs/partitions/msdos.c
fs/partitions/msdos.c
+1
-0
include/asm-alpha/keyboard.h
include/asm-alpha/keyboard.h
+25
-0
include/asm-alpha/uaccess.h
include/asm-alpha/uaccess.h
+9
-0
include/linux/fb.h
include/linux/fb.h
+1
-0
include/linux/ide.h
include/linux/ide.h
+14
-20
include/linux/sched.h
include/linux/sched.h
+1
-1
include/linux/tty.h
include/linux/tty.h
+1
-0
kernel/fork.c
kernel/fork.c
+10
-5
No files found.
Documentation/fb/framebuffer.txt
View file @
90ff4d27
...
...
@@ -2,7 +2,7 @@
-----------------------
Maintained by Geert Uytterhoeven <geert@linux-m68k.org>
Last revised:
November 7, 1998
Last revised:
October 7, 1999
0. Introduction
...
...
@@ -304,7 +304,20 @@ applications, please refer to the following documentation:
o linux/include/video/
8. Downloading
8. Mailing list
---------------
There's a _development_ mailing list at linux-fbdev@vuser.vu.union.edu,
controlled by majordomo. Send an email with `help' in the message body to
majordomo@vuser.vu.union.edu for subscription information.
The mailing list is archived at
http://www.mail-archive.com/linux-fbdev@vuser.vu.union.edu/
9. Downloading
--------------
All necessary files can be found at
...
...
@@ -313,8 +326,12 @@ All necessary files can be found at
and on its mirrors.
The latest version of fbset can be found at
http://www.cs.kuleuven.ac.be/~geert/bin/
9
. Credits
10
. Credits
----------
This readme was written by Geert Uytterhoeven, partly based on the original
...
...
arch/i386/boot/Makefile
View file @
90ff4d27
...
...
@@ -8,9 +8,6 @@
# Copyright (C) 1994 by Linus Torvalds
#
AS86
=
$(CROSS_COMPILE)
as86
-0
-a
LD86
=
$(CROSS_COMPILE)
ld86
-0
BOOT_INCL
=
$(TOPDIR)
/include/linux/config.h
\
$(TOPDIR)
/include/linux/autoconf.h
\
$(TOPDIR)
/include/asm/boot.h
...
...
@@ -45,40 +42,40 @@ install: $(CONFIGURE) $(BOOTIMAGE)
tools/build
:
tools/build.c
$(HOSTCC)
$(HOSTCFLAGS)
-o
$@
$<
-I
$(TOPDIR)
/include
setup
:
setup
.o
$(LD
86)
-s
-o
$@
$<
bootsect
:
bootsect
.o
$(LD
)
-Ttext
0x0
-s
-oformat
binary
-o
$@
$<
setup.o
:
setup
.s
$(AS
86
)
-o
$@
$<
bootsect.o
:
bootsect
.s
$(AS)
-o
$@
$<
setup.s
:
setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
bootsect.s
:
bootsect.S Makefile $(BOOT_INCL)
$(CPP)
-traditional
$(SVGA_MODE)
$(RAMDISK)
$<
-o
$@
b
setup
:
bsetup.o
$(LD
86)
-s
-o
$@
$<
b
bootsect
:
bbootsect.o bsetup
$(LD
)
-Ttext
0x0
-s
-oformat
binary
$<
-R
bsetup.o
-o
$@
b
setup.o
:
bsetup
.s
$(AS
86
)
-o
$@
$<
b
bootsect.o
:
bbootsect
.s
$(AS)
-o
$@
$<
b
setup.s
:
setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
b
bootsect.s
:
bootsect.S Makefile $(BOOT_INCL)
$(CPP)
-D__BIG_KERNEL__
-traditional
$(SVGA_MODE)
$(RAMDISK)
$<
-o
$@
bootsect
:
bootsect
.o
$(LD
86)
-s
-o
$@
$<
setup
:
setup
.o
$(LD
)
-Ttext
0x0
-s
-oformat
binary
-e
begtext
-o
$@
$<
bootsect.o
:
bootsect
.s
$(AS
86
)
-o
$@
$<
setup.o
:
setup
.s
$(AS)
-o
$@
$<
bootsect.s
:
bootsect.S Makefile $(BOOT_INCL)
setup.s
:
setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
$(CPP)
-traditional
$(SVGA_MODE)
$(RAMDISK)
$<
-o
$@
b
bootsect
:
bbootsect
.o
$(LD
86)
-s
-o
$@
$<
b
setup
:
bsetup
.o
$(LD
)
-Ttext
0x0
-s
-oformat
binary
-e
begtext
-o
$@
$<
b
bootsect.o
:
bbootsect
.s
$(AS
86
)
-o
$@
$<
b
setup.o
:
bsetup
.s
$(AS)
-o
$@
$<
b
bootsect.s
:
bootsect.S Makefile $(BOOT_INCL)
b
setup.s
:
setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
$(CPP)
-D__BIG_KERNEL__
-traditional
$(SVGA_MODE)
$(RAMDISK)
$<
-o
$@
dep
:
...
...
arch/i386/boot/bootsect.S
View file @
90ff4d27
!
!
bootsect.s
Copyright
(
C
)
1991
,
1992
Linus
Torvalds
!
modified
by
Drew
Eckhardt
!
modified
by
Bruce
Evans
(
bde
)
!
!
bootsect.s
is
loaded
at
0x7c00
by
the
bios
-
startup
routines
,
and
moves
!
itself
out
of
the
way
to
address
0x90000
,
and
jumps
there
.
!
!
bde
-
should
not
jump
blindly
,
there
may
be
systems
with
only
512
K
low
!
memory
.
Use
int
0x12
to
get
the
top
of
memory
,
etc
.
!
!
It
then
loads
'setup'
directly
after
itself
(
0x90200
),
and
the
system
!
at
0x10000
,
using
BIOS
interrupts
.
!
!
NOTE
!
currently
system
is
at
most
(
8
*
65536
-
4096
)
bytes
long
.
This
should
!
be
no
problem
,
even
in
the
future
.
I
want
to
keep
it
simple
.
This
508
kB
!
kernel
size
should
be
enough
,
especially
as
this
doesn
't contain the
!
buffer
cache
as
in
minix
(
and
especially
now
that
the
kernel
is
!
compressed
:
-)
!
!
The
loader
has
been
made
as
simple
as
possible
,
and
continuous
!
read
errors
will
result
in
a
unbreakable
loop
.
Reboot
by
hand
.
It
!
loads
pretty
fast
by
getting
whole
tracks
at
a
time
whenever
possible
.
#include <linux/config.h> /* for CONFIG_ROOT_RDONLY */
/*
*
bootsect
.
S
Copyright
(
C
)
1991
,
1992
Linus
Torvalds
*
*
modified
by
Drew
Eckhardt
*
modified
by
Bruce
Evans
(
bde
)
*
modified
by
Chris
Noe
(
May
1999
)
(
as86
->
gas
)
*
*
bootsect
is
loaded
at
0x7c00
by
the
bios
-
startup
routines
,
and
moves
*
itself
out
of
the
way
to
address
0x90000
,
and
jumps
there
.
*
*
bde
-
should
not
jump
blindly
,
there
may
be
systems
with
only
512
K
low
*
memory
.
Use
int
0x12
to
get
the
top
of
memory
,
etc
.
*
*
It
then
loads
'setup'
directly
after
itself
(
0x90200
),
and
the
system
*
at
0x10000
,
using
BIOS
interrupts
.
*
*
NOTE
!
currently
system
is
at
most
(
8
*
65536
-
4096
)
bytes
long
.
This
should
*
be
no
problem
,
even
in
the
future
.
I
want
to
keep
it
simple
.
This
508
kB
*
kernel
size
should
be
enough
,
especially
as
this
doesn
't contain the
*
buffer
cache
as
in
minix
(
and
especially
now
that
the
kernel
is
*
compressed
:
-)
*
*
The
loader
has
been
made
as
simple
as
possible
,
and
continuous
*
read
errors
will
result
in
a
unbreakable
loop
.
Reboot
by
hand
.
It
*
loads
pretty
fast
by
getting
whole
tracks
at
a
time
whenever
possible
.
*/
#include <linux/config.h> /* for CONFIG_ROOT_RDONLY */
#include <asm/boot.h>
.
text
SETUPSECS
=
4
/*
default
nr
of
setup
-
sectors
*/
BOOTSEG
=
0x07C0
/*
original
address
of
boot
-
sector
*/
INITSEG
=
DEF_INITSEG
/*
we
move
boot
here
-
out
of
the
way
*/
SETUPSEG
=
DEF_SETUPSEG
/*
setup
starts
here
*/
SYSSEG
=
DEF_SYSSEG
/*
system
loaded
at
0x10000
(
65536
)
*/
SYSSIZE
=
DEF_SYSSIZE
/*
system
size
:
#
of
16
-
byte
clicks
*/
/
*
to
be
loaded
*/
ROOT_DEV
=
0
/*
ROOT_DEV
is
now
written
by
"build"
*/
SWAP_DEV
=
0
/*
SWAP_DEV
is
now
written
by
"build"
*/
SETUPSECS
=
4
!
default
nr
of
setup
-
sectors
BOOTSEG
=
0x07C0
!
original
address
of
boot
-
sector
INITSEG
=
DEF_INITSEG
!
we
move
boot
here
-
out
of
the
way
SETUPSEG
=
DEF_SETUPSEG
!
setup
starts
here
SYSSEG
=
DEF_SYSSEG
!
system
loaded
at
0x10000
(
65536
)
.
SYSSIZE
=
DEF_SYSSIZE
!
system
size
:
number
of
16
-
byte
clicks
!
to
be
loaded
!
ROOT_DEV
&
SWAP_DEV
are
now
written
by
"build"
.
ROOT_DEV
=
0
SWAP_DEV
=
0
#ifndef SVGA_MODE
#define SVGA_MODE ASK_VGA
#endif
#ifndef RAMDISK
#define RAMDISK 0
#endif
#ifndef CONFIG_ROOT_RDONLY
#define CONFIG_ROOT_RDONLY 1
#endif
!
ld86
requires
an
entry
symbol
.
This
may
as
well
be
the
usual
one
.
.
globl
_main
_main
:
.
code16
.
text
.
global
_start
_start
:
#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
int
3
int
$
0x
3
#endif
mov
ax
,#
BOOTSEG
mov
ds
,
ax
mov
ax
,#
INITSEG
mov
es
,
ax
mov
cx
,#
128
sub
si
,
si
sub
di
,
di
movw
$BOOTSEG
,
%
ax
movw
%
ax
,
%
ds
movw
$INITSEG
,
%
ax
movw
%
ax
,
%
es
movw
$
128
,
%
cx
subw
%
si
,
%
si
subw
%
di
,
%
di
cld
rep
movsd
jmpi
go
,
INITSEG
!
ax
and
es
already
contain
INITSEG
go
:
mov
di
,#
0x4000
-
12
!
0x4000
is
arbitrary
value
>=
length
of
!
bootsect
+
length
of
setup
+
room
for
stack
!
12
is
disk
parm
size
!
bde
-
changed
0xff00
to
0x4000
to
use
debugger
at
0x6400
up
(
bde
)
.
We
!
wouldn
'
t
have
to
worry
about
this
if
we
checked
the
top
of
memory
.
Also
!
my
BIOS
can
be
configured
to
put
the
wini
drive
tables
in
high
memory
!
instead
of
in
the
vector
table
.
The
old
stack
might
have
clobbered
the
!
drive
table
.
mov
ds
,
ax
mov
ss
,
ax
!
put
stack
at
INITSEG
:
0x4000
-
12
.
mov
sp
,
di
/*
*
Many
BIOS
's default disk parameter tables will not
*
recognize
multi
-
sector
reads
beyond
the
maximum
sector
number
*
specified
in
the
default
diskette
parameter
tables
-
this
may
*
mean
7
sectors
in
some
cases
.
*
*
Since
single
sector
reads
are
slow
and
out
of
the
question
,
*
we
must
take
care
of
this
by
creating
new
parameter
tables
*
(
for
the
first
disk
)
in
RAM
.
We
will
set
the
maximum
sector
*
count
to
36
-
the
most
we
will
encounter
on
an
ED
2
.88.
*
*
High
doesn
't hurt. Low does.
*
*
Segments
are
as
follows
:
ds
=
es
=
ss
=
cs
-
INITSEG
,
*
fs
=
0
,
gs
is
unused
.
*/
!
cx
contains
0
from
rep
movsd
above
mov
fs
,
cx
mov
bx
,#
0x78
!
fs
:
bx
is
parameter
table
address
push
ds
seg
fs
lds
si
,(
bx
)
!
ds
:
si
is
source
mov
cl
,#
3
!
copy
12
bytes
movsl
ljmp
$INITSEG
,
$go
#
bde
-
changed
0xff00
to
0x4000
to
use
debugger
at
0x6400
up
(
bde
)
.
We
#
wouldn
'
t
have
to
worry
about
this
if
we
checked
the
top
of
memory
.
Also
#
my
BIOS
can
be
configured
to
put
the
wini
drive
tables
in
high
memory
#
instead
of
in
the
vector
table
.
The
old
stack
might
have
clobbered
the
#
drive
table
.
go
:
movw
$
0x4000
-
12
,
%
di
#
0x4000
is
an
arbitrary
value
>=
#
length
of
bootsect
+
length
of
#
setup
+
room
for
stack
;
#
12
is
disk
parm
size
.
movw
%
ax
,
%
ds
#
ax
and
es
already
contain
INITSEG
movw
%
ax
,
%
ss
movw
%
di
,
%
sp
#
put
stack
at
INITSEG
:
0x4000
-
12
.
#
Many
BIOS
's default disk parameter tables will not recognize
#
multi
-
sector
reads
beyond
the
maximum
sector
number
specified
#
in
the
default
diskette
parameter
tables
-
this
may
mean
7
#
sectors
in
some
cases
.
#
#
Since
single
sector
reads
are
slow
and
out
of
the
question
,
#
we
must
take
care
of
this
by
creating
new
parameter
tables
#
(
for
the
first
disk
)
in
RAM
.
We
will
set
the
maximum
sector
#
count
to
36
-
the
most
we
will
encounter
on
an
ED
2
.88.
#
#
High
doesn
't hurt. Low does.
#
#
Segments
are
as
follows
:
ds
=
es
=
ss
=
cs
-
INITSEG
,
fs
=
0
,
#
and
gs
is
unused
.
movw
%
cx
,
%
fs
#
set
fs
to
0
movw
$
0x78
,
%
bx
#
fs
:
bx
is
parameter
table
address
pushw
%
ds
ldsw
%
fs
:
(%
bx
),
%
si
#
ds
:
si
is
source
movb
$
3
,
%
cl
#
copy
12
bytes
cld
push
di
pushw
%
di
#
di
=
0x4000
-
12
.
rep
movsd
pop
di
pop
ds
movsl
popw
%
di
popw
%
ds
movb
$
36
,
0x4
(%
di
)
#
patch
sector
count
movw
%
di
,
%
fs
:
(%
bx
)
movw
%
es
,
%
fs
:
2
(%
bx
)
movb
4
(
di
),*
36
!
patch
sector
count
seg
fs
mov
(
bx
),
di
seg
fs
mov
2
(
bx
),
es
!
load
the
setup
-
sectors
directly
after
the
bootblock
.
!
Note
that
'es'
is
already
set
up
.
!
Also
cx
is
0
from
rep
movsd
above
.
#
Load
the
setup
-
sectors
directly
after
the
bootblock
.
#
Note
that
'es'
is
already
set
up
.
#
Also
,
cx
=
0
from
rep
movsl
above
.
load_setup
:
xor
ah
,
ah
!
reset
FDC
xor
dl
,
dl
int
0x13
xor
dx
,
dx
!
drive
0
,
head
0
mov
cl
,#
0x02
!
sector
2
,
track
0
mov
bx
,#
0x0200
!
address
=
512
,
in
INITSEG
mov
ah
,#
0x02
!
service
2
,
nr
of
sectors
mov
al
,
setup_sects
!
(
assume
all
on
head
0
,
track
0
)
int
0x13
!
read
it
jnc
ok_load_setup
!
ok
-
continue
push
ax
!
dump
error
code
xorb
%
ah
,
%
ah
#
reset
FDC
xorb
%
dl
,
%
dl
int
$
0x13
xorw
%
dx
,
%
dx
#
drive
0
,
head
0
movb
$
0x02
,
%
cl
#
sector
2
,
track
0
movw
$
0x0200
,
%
bx
#
address
=
512
,
in
INITSEG
movb
$
0x02
,
%
ah
#
service
2
,
"read sector(s)"
movb
setup_sects
,
%
al
#
(
assume
all
on
head
0
,
track
0
)
int
$
0x13
#
read
it
jnc
ok_load_setup
#
ok
-
continue
pushw
%
ax
#
dump
error
code
call
print_nl
mov
bp
,
s
p
mov
w
%
sp
,
%
b
p
call
print_hex
pop
ax
popw
%
ax
jmp
load_setup
ok_load_setup
:
!
Get
disk
drive
parameters
,
specifically
nr
of
sectors
/
track
#
Get
disk
drive
parameters
,
specifically
nr
of
sectors
/
track
.
#if 0
!
bde
-
the
Phoenix
BIOS
manual
says
function
0x08
only
works
for
fixed
!
disks
.
It
doesn
't work for one of my BIOS'
s
(
1987
Award
)
.
It
was
!
fatal
not
to
check
the
error
code
.
#
bde
-
the
Phoenix
BIOS
manual
says
function
0x08
only
works
for
fixed
#
disks
.
It
doesn
't work for one of my BIOS'
s
(
1987
Award
)
.
It
was
#
fatal
not
to
check
the
error
code
.
xor
dl
,
dl
mov
ah
,#
0x08
!
AH
=
8
is
get
drive
parameters
int
0x13
xor
ch
,
ch
#else
xorb
%
dl
,
%
dl
movb
$
0x08
,
%
ah
#
AH
=
8
is
get
drive
parameters
int
$
0x13
xorb
%
ch
,
%
ch
!
It
seems
that
there
is
no
BIOS
call
to
get
the
number
of
sectors
.
Guess
!
36
sectors
if
sector
36
can
be
read
,
18
sectors
if
sector
18
can
be
read
,
!
15
if
sector
15
can
be
read
.
Otherwise
guess
9
.
#else
mov
si
,#
disksizes
!
table
of
sizes
to
try
#
It
seems
that
there
is
no
BIOS
call
to
get
the
number
of
sectors
.
#
Guess
36
sectors
if
sector
36
can
be
read
,
18
sectors
if
sector
18
#
can
be
read
,
15
if
sector
15
can
be
read
.
Otherwise
guess
9
.
movw
$disksizes
,
%
si
#
table
of
sizes
to
try
probe_loop
:
lodsb
cb
w
!
extend
to
word
mov
sectors
,
ax
cmp
si
,#
disksizes
+
4
jae
got_sectors
!
if
all
else
fails
,
try
9
xchg
ax
,
cx
!
cx
=
track
and
sector
x
or
dx
,
dx
!
drive
0
,
head
0
xor
bl
,
bl
mov
bh
,
setup_sects
inc
bh
shl
bh
,#
1
!
address
after
setup
(
es
=
cs
)
mov
ax
,#
0x0201
!
service
2
,
1
sector
int
0x13
jc
probe_loop
!
try
next
value
cb
tw
#
extend
to
word
mov
w
%
ax
,
sectors
cmp
w
$disksizes
+
4
,
%
si
jae
got_sectors
#
if
all
else
fails
,
try
9
x
chgw
%
cx
,
%
ax
#
cx
=
track
and
sector
xor
w
%
dx
,
%
dx
#
drive
0
,
head
0
xorb
%
bl
,
%
bl
movb
setup_sects
,
%
bh
incb
%
bh
shlb
%
bh
#
address
after
setup
(
es
=
cs
)
movw
$
0x0201
,
%
ax
#
service
2
,
1
sector
int
$
0x13
jc
probe_loop
#
try
next
value
#endif
got_sectors
:
!
Restore
es
mov
ax
,#
INITSEG
mov
es
,
ax
!
Print
some
inane
message
mov
ah
,#
0x03
!
read
cursor
pos
xor
bh
,
bh
int
0x10
mov
cx
,#
9
mov
bx
,#
0x0007
!
page
0
,
attribute
7
(
normal
)
mov
bp
,#
msg1
mov
ax
,#
0x1301
!
write
string
,
move
cursor
int
0x10
!
ok
,
we
've written the message, now
!
we
want
to
load
the
system
(
at
0x10000
)
mov
ax
,#
SYSSEG
mov
es
,
ax
!
segment
of
0x010000
movw
$INITSEG
,
%
ax
movw
%
ax
,
%
es
#
set
up
es
movb
$
0x03
,
%
ah
#
read
cursor
pos
xorb
%
bh
,
%
bh
int
$
0x10
movw
$
9
,
%
cx
movw
$
0x0007
,
%
bx
#
page
0
,
attribute
7
(
normal
)
movw
$msg1
,
%
bp
movw
$
0x1301
,
%
ax
#
write
string
,
move
cursor
int
$
0x10
#
tell
the
user
we
're loading..
movw
$SYSSEG
,
%
ax
#
ok
,
we
've written the message, now
movw
%
ax
,
%
es
#
we
want
to
load
system
(
at
0x10000
)
call
read_it
call
kill_motor
call
print_nl
!
After
that
we
check
which
root
-
device
to
use
.
If
the
device
is
!
defined
(!=
0
),
nothing
is
done
and
the
given
device
is
used
.
!
Otherwise
,
one
of
/
dev
/
fd0H2880
(
2
,
32
)
or
/
dev
/
PS0
(
2
,
28
)
or
/
dev
/
at0
(
2
,
8
),
!
depending
on
the
number
of
sectors
we
pretend
to
know
we
have
.
#
After
that
we
check
which
root
-
device
to
use
.
If
the
device
is
#
defined
(!=
0
),
nothing
is
done
and
the
given
device
is
used
.
#
Otherwise
,
one
of
/
dev
/
fd0H2880
(
2
,
32
)
or
/
dev
/
PS0
(
2
,
28
)
or
/
dev
/
at0
(
2
,
8
)
#
depending
on
the
number
of
sectors
we
pretend
to
know
we
have
.
seg
cs
mov
ax
,
root_dev
or
ax
,
ax
movw
%
cs
:
root_dev
,
%
ax
orw
%
ax
,
%
ax
jne
root_defined
seg
cs
mov
bx
,
sectors
mov
ax
,#
0x0208
!
/
dev
/
ps0
-
1
.2
Mb
cmp
bx
,#
15
mov
w
%
cs
:
sectors
,
%
bx
mov
w
$
0x0208
,
%
ax
#
/
dev
/
ps0
-
1
.2
Mb
cmp
w
$
15
,
%
bx
je
root_defined
mov
al
,#
0x1c
!
/
dev
/
PS0
-
1
.44
Mb
cmp
bx
,#
18
movb
$
0x1c
,
%
al
#
/
dev
/
PS0
-
1
.44
Mb
cmpw
$
18
,
%
bx
je
root_defined
mov
al
,#
0x20
!
/
dev
/
fd0H2880
-
2
.88
Mb
cmp
bx
,#
36
movb
$
0x20
,
%
al
#
/
dev
/
fd0H2880
-
2
.88
Mb
cmpw
$
36
,
%
bx
je
root_defined
mov
al
,#
0
!
/
dev
/
fd0
-
autodetect
movb
$
0
,
%
al
#
/
dev
/
fd0
-
autodetect
root_defined
:
seg
cs
mov
root_dev
,
ax
movw
%
ax
,
%
cs
:
root_dev
#
After
that
(
everything
loaded
),
we
jump
to
the
setup
-
routine
#
loaded
directly
after
the
bootblock
:
!
after
that
(
everything
loaded
),
we
jump
to
!
the
setup
-
routine
loaded
directly
after
!
the
bootblock
:
ljmp
$SETUPSEG
,
$
0
jmpi
0
,
SETUPSEG
#
This
routine
loads
the
system
at
address
0x10000
,
making
sure
#
no
64
kB
boundaries
are
crossed
.
We
try
to
load
it
as
fast
as
#
possible
,
loading
whole
tracks
whenever
we
can
.
!
This
routine
loads
the
system
at
address
0x10000
,
making
sure
!
no
64
kB
boundaries
are
crossed
.
We
try
to
load
it
as
fast
as
!
possible
,
loading
whole
tracks
whenever
we
can
.
!
!
in
:
es
-
starting
address
segment
(
normally
0x1000
)
!
sread
:
.
word
0
!
sectors
read
of
current
track
head
:
.
word
0
!
current
head
track
:
.
word
0
!
current
track
#
es
=
starting
address
segment
(
normally
0x1000
)
sread
:
.
word
0
#
sectors
read
of
current
track
head
:
.
word
0
#
current
head
track
:
.
word
0
#
current
track
read_it
:
mov
al
,
setup_sects
inc
al
mov
sread
,
al
mov
ax
,
es
test
ax
,#
0x0fff
die
:
jne
die
!
es
must
be
at
64
kB
boundary
xor
bx
,
bx
!
bx
is
starting
address
within
segment
movb
setup_sects
,
%
al
incb
%
al
movb
%
al
,
sread
movw
%
es
,
%
ax
testw
$
0x0fff
,
%
ax
die
:
jne
die
#
es
must
be
at
64
kB
boundary
xorw
%
bx
,
%
bx
#
bx
is
starting
address
within
segment
rp_read
:
#ifdef __BIG_KERNEL__
#define CALL_HIGHLOAD_KLUDGE .word 0x1eff,0x220 ! call far * bootsect_kludge
!
NOTE
:
as86
can
't assemble this
CALL_HIGHLOAD_KLUDGE
!
this
is
within
setup
.
S
lcall
bootsect_kludge
#
in
setup
.
S
#else
mov
ax
,
es
sub
ax
,#
SYSSEG
mov
w
%
es
,
%
ax
sub
w
$SYSSEG
,
%
ax
#endif
cmp
ax
,
syssize
!
have
we
loaded
all
yet
?
jbe
ok1_read
cmpw
syssize
,
%
ax
#
have
we
loaded
all
yet
?
jbe
ok1_read
ret
ok1_read
:
mov
ax
,
sectors
sub
ax
,
sread
mov
cx
,
ax
shl
cx
,#
9
add
cx
,
bx
jnc
ok2_read
je
ok2_read
xor
ax
,
ax
sub
ax
,
bx
shr
ax
,#
9
movw
sectors
,
%
ax
subw
sread
,
%
ax
movw
%
ax
,
%
cx
shlw
$
9
,
%
cx
addw
%
bx
,
%
cx
jnc
ok2_read
je
ok2_read
xorw
%
ax
,
%
ax
subw
%
bx
,
%
ax
shrw
$
9
,
%
ax
ok2_read
:
call
read_track
mov
cx
,
ax
add
ax
,
sread
cmp
ax
,
sectors
jne
ok3_read
mov
ax
,#
1
sub
ax
,
head
jne
ok4_read
inc
track
call
read_track
movw
%
ax
,
%
cx
addw
sread
,
%
ax
cmpw
sectors
,
%
ax
jne
ok3_read
movw
$
1
,
%
ax
subw
head
,
%
ax
jne
ok4_read
incw
track
ok4_read
:
mov
head
,
ax
xor
ax
,
ax
mov
w
%
ax
,
head
xor
w
%
ax
,
%
ax
ok3_read
:
mov
sread
,
ax
shl
cx
,#
9
add
bx
,
cx
jnc
rp_read
mov
ax
,
es
add
ah
,#
0x10
mov
es
,
ax
xor
bx
,
bx
jmp
rp_read
movw
%
ax
,
sread
shlw
$
9
,
%
cx
addw
%
cx
,
%
bx
jnc
rp_read
movw
%
es
,
%
ax
addb
$
0x10
,
%
ah
movw
%
ax
,
%
es
xorw
%
bx
,
%
bx
jmp
rp_read
read_track
:
pusha
pusha
mov
ax
,
#
0xe2e
!
loading
...
message
2
e
=
.
mov
bx
,
#
7
int
0x10
mov
w
$
0xe2e
,
%
ax
#
loading
...
message
2
e
=
.
mov
w
$
7
,
%
bx
int
$
0x10
popa
mov
dx
,
track
mov
cx
,
sread
inc
cx
mov
ch
,
dl
mov
dx
,
head
mov
dh
,
dl
and
dx
,#
0x0100
mov
ah
,#
2
push
dx
!
save
for
error
dump
push
cx
push
bx
push
ax
int
0x13
movw
track
,
%
dx
movw
sread
,
%
cx
incw
%
cx
movb
%
dl
,
%
ch
movw
head
,
%
dx
movb
%
dl
,
%
dh
andw
$
0x0100
,
%
dx
movb
$
2
,
%
ah
pushw
%
dx
#
save
for
error
dump
pushw
%
cx
pushw
%
bx
pushw
%
ax
int
$
0x13
jc
bad_rt
add
sp
,
#
8
addw
$
8
,
%
sp
popa
ret
bad_rt
:
push
ax
!
save
error
code
call
print_all
!
ah
=
error
,
al
=
read
xor
ah
,
ah
xor
dl
,
dl
int
0x13
add
sp
,
#
10
popa
bad_rt
:
pushw
%
ax
#
save
error
code
call
print_all
#
ah
=
error
,
al
=
read
xorb
%
ah
,
%
ah
xorb
%
dl
,
%
dl
int
$
0x13
addw
$
10
,
%
sp
popa
jmp
read_track
/*
*
print_all
is
for
debugging
purposes
.
*
It
will
print
out
all
of
the
registers
.
The
assumption
is
that
this
is
*
called
from
a
routine
,
with
a
stack
frame
like
*
dx
*
cx
*
bx
*
ax
*
error
*
ret
<-
sp
*
*/
#
print_all
is
for
debugging
purposes
.
#
#
it
will
print
out
all
of
the
registers
.
The
assumption
is
that
this
is
#
called
from
a
routine
,
with
a
stack
frame
like
#
#
%
dx
#
%
cx
#
%
bx
#
%
ax
#
(
error
)
#
ret
<-
%
sp
print_all
:
mov
cx
,
#
5
!
error
code
+
4
registers
mov
bp
,
sp
movw
$
5
,
%
cx
#
error
code
+
4
registers
movw
%
sp
,
%
bp
print_loop
:
push
cx
!
save
count
left
call
print_nl
!
nl
for
readability
cmp
cl
,
#
5
jae
no_reg
!
see
if
register
name
is
needed
pushw
%
cx
#
save
count
left
call
print_nl
#
nl
for
readability
cmpb
$
5
,
%
cl
jae
no_reg
#
see
if
register
name
is
needed
mov
ax
,
#
0xe05
+
'A - 1
sub
al
,
cl
int
0x10
mov
al
,
#
'X
int
0x10
mov
al
,
#
':
int
0x10
movw
$
0xe05
+
'A'
-
1
,
%
ax
subb
%
cl
,
%
al
int
$
0x10
movb
$
'X'
,
%
al
int
$
0x10
movb
$
':'
,
%
al
int
$
0x10
no_reg
:
add
bp
,
#
2
!
next
register
call
print_hex
!
print
it
pop
cx
add
w
$
2
,
%
bp
#
next
register
call
print_hex
#
print
it
pop
w
%
cx
loop
print_loop
ret
print_nl
:
mov
ax
,
#
0xe0d
!
CR
int
0x10
mov
al
,
#
0xa
!
LF
int
0x10
mov
w
$
0xe0d
,
%
ax
#
CR
int
$
0x10
mov
b
$
0xa
,
%
al
#
LF
int
$
0x10
ret
/*
*
print_hex
is
for
debugging
purposes
,
and
prints
the
word
*
pointed
to
by
ss
:
bp
in
hexadecimal
.
*/
#
print_hex
is
for
debugging
purposes
,
and
prints
the
word
#
pointed
to
by
ss
:
bp
in
hexadecimal
.
print_hex
:
mov
cx
,
#
4
!
4
hex
digits
mov
dx
,
(
bp
)
!
load
word
into
dx
mov
w
$
4
,
%
cx
#
4
hex
digits
mov
w
(%
bp
),
%
dx
#
load
word
into
dx
print_digit
:
rol
dx
,
#
4
!
rotate
so
that
lowest
4
bits
are
used
mov
ax
,
#
0xe0f
!
ah
=
request
,
al
=
mask
for
nybble
and
al
,
dl
add
al
,
#
0x90
!
convert
al
to
ASCII
hex
(
four
instructions
)
rolw
$
4
,
%
dx
#
rotate
to
use
low
4
bits
movw
$
0xe0f
,
%
ax
#
ah
=
request
andb
%
dl
,
%
al
#
al
=
mask
for
nybble
addb
$
0x90
,
%
al
#
convert
al
to
ascii
hex
daa
#
in
only
four
instructions
!
adc
$
0x40
,
%
al
daa
adc
al
,
#
0x40
daa
int
0x10
int
$
0x10
loop
print_digit
ret
#
This
procedure
turns
off
the
floppy
drive
motor
,
so
#
that
we
enter
the
kernel
in
a
known
state
,
and
#
don
'
t
have
to
worry
about
it
later
.
/*
*
This
procedure
turns
off
the
floppy
drive
motor
,
so
*
that
we
enter
the
kernel
in
a
known
state
,
and
*
don
't have to worry about it later.
*/
kill_motor
:
push
dx
mov
dx
,#
0x3f2
xor
al
,
al
out
b
pop
dx
push
w
%
dx
mov
w
$
0x3f2
,
%
dx
xor
b
%
al
,
%
al
out
w
%
al
,
%
dx
pop
w
%
dx
ret
sectors
:
.
word
0
disksizes
:
.
byte
36
,
18
,
15
,
9
sectors
:
.
word
0
disksizes
:
.
byte
36
,
18
,
15
,
9
msg1
:
.
byte
13
,
10
.
ascii
"Loading"
msg1
:
.
byte
13
,
10
.
ascii
"Loading"
#
XXX
:
This
is
a
*
very
*
snug
fit
.
.
org
497
setup_sects
:
.
byte
SETUPSECS
root_flags
:
.
word
CONFIG_ROOT_RDONLY
syssize
:
.
word
SYSSIZE
swap_dev
:
.
word
SWAP_DEV
ram_size
:
.
word
RAMDISK
vid_mode
:
.
word
SVGA_MODE
root_dev
:
.
word
ROOT_DEV
boot_flag
:
.
word
0xAA55
setup_sects
:
.
byte
SETUPSECS
root_flags
:
.
word
CONFIG_ROOT_RDONLY
syssize
:
.
word
SYSSIZE
swap_dev
:
.
word
SWAP_DEV
ram_size
:
.
word
RAMDISK
vid_mode
:
.
word
SVGA_MODE
root_dev
:
.
word
ROOT_DEV
boot_flag
:
.
word
0xAA55
arch/i386/boot/compressed/Makefile
View file @
90ff4d27
...
...
@@ -39,7 +39,7 @@ piggy.o: $(SYSTEM)
$(OBJCOPY)
$(SYSTEM)
$$
tmppiggy
;
\
gzip
-f
-9
<
$$
tmppiggy
>
$$
tmppiggy.gz
;
\
echo
"SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}"
>
$$
tmppiggy.lnk
;
\
$(LD)
-
m
elf_i386
-
r
-o
piggy.o
-b
binary
$$
tmppiggy.gz
-b
elf32-i386
-T
$$
tmppiggy.lnk
;
\
$(LD)
-r
-o
piggy.o
-b
binary
$$
tmppiggy.gz
-b
elf32-i386
-T
$$
tmppiggy.lnk
;
\
rm
-f
$$
tmppiggy
$$
tmppiggy.gz
$$
tmppiggy.lnk
clean
:
...
...
arch/i386/boot/setup.S
View file @
90ff4d27
!
!
setup.S
Copyright
(
C
)
1991
,
1992
Linus
Torvalds
!
!
setup.s
is
responsible
for
getting
the
system
data
from
the
BIOS
,
!
and
putting
them
into
the
appropriate
places
in
system
memory
.
!
both
setup
.
s
and
system
has
been
loaded
by
the
bootblock
.
!
!
This
code
asks
the
bios
for
memory
/
disk
/
other
parameters
,
and
!
puts
them
in
a
"safe"
place
:
0x90000
-
0x901FF
,
ie
where
the
!
boot
-
block
used
to
be
.
It
is
then
up
to
the
protected
mode
!
system
to
read
them
from
there
before
the
area
is
overwritten
!
for
buffer
-
blocks
.
!
!
Move
PS
/
2
aux
init
code
to
psaux
.
c
!
(
troyer
@
saifr00.cfsat.
Honeywell
.
COM
)
03
Oct92
!
!
some
changes
and
additional
features
by
Christoph
Niemann
,
!
March
1993
/
June
1994
(
Christoph
.
Niemann
@
linux
.
org
)
!
!
add
APM
BIOS
checking
by
Stephen
Rothwell
,
May
1994
!
(
Stephen
.
Rothwell
@
canb.auug.org.au
)
!
!
High
load
stuff
,
initrd
support
and
position
independency
!
by
Hans
Lermen
&
Werner
Almesberger
,
February
1996
!
<
lermen
@
elserv.ffm.fgan.de
>,
<
almesber
@
lrc
.
epfl
.
ch
>
!
!
Video
handling
moved
to
video
.
S
by
Martin
Mares
,
March
1996
!
<
mj
@
k332.feld.cvut.cz
>
!
!
Extended
memory
detection
scheme
retwiddled
by
orc
@
pell
.
chi
.
il
.
us
(
david
!
parsons
)
to
avoid
loadlin
confusion
,
July
1997
!
/*
*
setup
.
S
Copyright
(
C
)
1991
,
1992
Linus
Torvalds
*
*
setup
.
s
is
responsible
for
getting
the
system
data
from
the
BIOS
,
*
and
putting
them
into
the
appropriate
places
in
system
memory
.
*
both
setup
.
s
and
system
has
been
loaded
by
the
bootblock
.
*
*
This
code
asks
the
bios
for
memory
/
disk
/
other
parameters
,
and
*
puts
them
in
a
"safe"
place
:
0x90000
-
0x901FF
,
ie
where
the
*
boot
-
block
used
to
be
.
It
is
then
up
to
the
protected
mode
*
system
to
read
them
from
there
before
the
area
is
overwritten
*
for
buffer
-
blocks
.
*
*
Move
PS
/
2
aux
init
code
to
psaux
.
c
*
(
troyer
@
saifr00
.
cfsat
.
Honeywell
.
COM
)
03
Oct92
*
*
some
changes
and
additional
features
by
Christoph
Niemann
,
*
March
1993
/
June
1994
(
Christoph
.
Niemann
@
linux
.
org
)
*
*
add
APM
BIOS
checking
by
Stephen
Rothwell
,
May
1994
*
(
Stephen
.
Rothwell
@
canb
.
auug
.
org
.
au
)
*
*
High
load
stuff
,
initrd
support
and
position
independency
*
by
Hans
Lermen
&
Werner
Almesberger
,
February
1996
*
<
lermen
@
elserv
.
ffm
.
fgan
.
de
>,
<
almesber
@
lrc
.
epfl
.
ch
>
*
*
Video
handling
moved
to
video
.
S
by
Martin
Mares
,
March
1996
*
<
mj
@
k332
.
feld
.
cvut
.
cz
>
*
*
Extended
memory
detection
scheme
retwiddled
by
orc
@
pell
.
chi
.
il
.
us
(
david
*
parsons
)
to
avoid
loadlin
confusion
,
July
1997
*
*
Transcribed
from
Intel
(
as86
)
->
AT
&
T
(
gas
)
by
Chris
Noe
,
May
1999
.
*
<
stiker
@
northlink
.
com
>
*/
#define __ASSEMBLY__
#include <linux/config.h>
...
...
@@ -39,17 +42,20 @@
#include <asm/boot.h>
#include <asm/e820.h>
!
Signature
words
to
ensure
LILO
loaded
us
right
/*
Signature
words
to
ensure
LILO
loaded
us
right
*/
#define SIG1 0xAA55
#define SIG2 0x5A5A
INITSEG
=
DEF_INITSEG
!
0x9000
,
we
move
boot
here
-
out
of
the
way
SYSSEG
=
DEF_SYSSEG
!
0x1000
,
system
loaded
at
0x10000
(
65536
)
.
SETUPSEG
=
DEF_SETUPSEG
!
0x9020
,
this
is
the
current
segment
!
...
and
the
former
contents
of
CS
DELTA_INITSEG
=
SETUPSEG
-
INITSEG
!
0x0020
INITSEG
=
DEF_INITSEG
#
0x9000
,
we
move
boot
here
,
out
of
the
way
SYSSEG
=
DEF_SYSSEG
#
0x1000
,
system
loaded
at
0x10000
(
65536
)
.
SETUPSEG
=
DEF_SETUPSEG
#
0x9020
,
this
is
the
current
segment
#
...
and
the
former
contents
of
CS
DELTA_INITSEG
=
SETUPSEG
-
INITSEG
#
0x0020
.
code16
.
globl
begtext
,
begdata
,
begbss
,
endtext
,
enddata
,
endbss
.
text
begtext
:
.
data
...
...
@@ -58,631 +64,617 @@ begdata:
begbss
:
.
text
entry
start
start
:
jmp
trampoline
!
------------------------
start
of
header
--------------------------------
!
!
SETUP
-
header
,
must
start
at
CS
:
2
(
old
0x9020
:
2
)
!
.
ascii
"HdrS"
!
Signature
for
SETUP
-
header
.
word
0x0201
!
Version
number
of
header
format
!
(
must
be
>=
0x0105
!
else
old
loadlin
-
1
.5
will
fail
)
realmode_swtch
:
.
word
0
,
0
!
default_switch
,
SETUPSEG
#
This
is
the
setup
header
,
and
it
must
start
at
%
cs
:
2
(
old
0x9020
:
2
)
.
ascii
"HdrS"
#
header
signature
.
word
0x0201
#
header
version
number
(>=
0x0105
)
#
or
else
old
loadlin
-
1
.5
will
fail
)
realmode_swtch
:
.
word
0
,
0
#
default_switch
,
SETUPSEG
start_sys_seg
:
.
word
SYSSEG
.
word
kernel_version
!
pointing
to
kernel
version
string
!
note
:
above
part
of
header
is
compatible
with
loadlin
-
1
.5
(
header
v1
.5
),
!
must
not
change
it
type_of_loader
:
.
byte
0
!
=
0
,
old
one
(
LILO
,
Loadlin
,
!
Bootlin
,
SYSLX
,
bootsect
...
)
!
else
it
is
set
by
the
loader
:
!
0
xTV
:
T
=
0
for
LILO
!
T
=
1
for
Loadlin
!
T
=
2
for
bootsect
-
loader
!
T
=
3
for
SYSLX
!
T
=
4
for
ETHERBOOT
!
V
=
version
loadflags
:
!
flags
,
unused
bits
must
be
zero
(
RFU
)
LOADED_HIGH
=
1
!
bit
within
loadflags
,
!
if
set
,
then
the
kernel
is
loaded
high
CAN_USE_HEAP
=
0x80
!
if
set
,
the
loader
also
has
set
heap_end_ptr
!
to
tell
how
much
space
behind
setup
.
S
|
can
be
used
for
heap
purposes
.
!
Only
the
loader
knows
what
is
free
!
.
word
kernel_version
#
pointing
to
kernel
version
string
#
above
section
of
header
is
compatible
#
with
loadlin
-
1
.5
(
header
v1
.5
)
.
Don
't
#
change
it
.
type_of_loader
:
.
byte
0
#
=
0
,
old
one
(
LILO
,
Loadlin
,
#
Bootlin
,
SYSLX
,
bootsect
...
)
# else it is set by the loader:
#
0
xTV
:
T
=
0
for
LILO
#
T
=
1
for
Loadlin
#
T
=
2
for
bootsect
-
loader
#
T
=
3
for
SYSLX
#
T
=
4
for
ETHERBOOT
#
V
=
version
#
flags
,
unused
bits
must
be
zero
(
RFU
)
bit
within
loadflags
loadflags
:
LOADED_HIGH
=
1
#
if
set
,
the
kernel
is
loaded
high
CAN_USE_HEAP
=
0x80
#
if
set
,
the
loader
also
has
set
#
heap_end_ptr
to
tell
how
much
#
space
behind
setup
.
S
can
be
used
for
#
heap
purposes
.
#
Only
the
loader
knows
what
is
free
#ifndef __BIG_KERNEL__
.
byte
0
x00
.
byte
0
#else
.
byte
LOADED_HIGH
#endif
setup_move_size
:
.
word
0x8000
!
size
to
move
,
when
we
(
setup
)
are
not
!
loaded
at
0x90000
.
We
will
move
ourselves
!
to
0x90000
then
just
before
jumping
into
!
the
kernel
.
However
,
only
the
loader
!
know
how
much
of
data
behind
us
also
needs
!
to
be
loaded
.
code32_start
:
!
here
loaders
can
put
a
different
!
start
address
for
32
-
bit
code
.
setup_move_size
:
.
word
0x8000
#
size
to
move
,
when
setup
is
not
#
loaded
at
0x90000
.
We
will
move
setup
#
to
0x90000
then
just
before
jumping
#
into
the
kernel
.
However
,
only
the
#
loader
knows
how
much
data
behind
#
us
also
needs
to
be
loaded
.
code32_start
:
#
here
loaders
can
put
a
different
#
start
address
for
32
-
bit
code
.
#ifndef __BIG_KERNEL__
.
long
0x1000
!
0x1000
=
default
for
zImage
.
long
0x1000
#
0x1000
=
default
for
zImage
#else
.
long
0x100000
!
0x100000
=
default
for
big
kernel
.
long
0x100000
#
0x100000
=
default
for
big
kernel
#endif
ramdisk_image
:
.
long
0
!
address
of
loaded
ramdisk
image
!
Here
the
loader
(
or
kernel
generator
)
puts
!
the
32
-
bit
address
were
it
loaded
the
image
.
!
This
only
will
be
interpreted
by
the
kernel
.
ramdisk_size
:
.
long
0
!
its
size
in
bytes
ramdisk_image
:
.
long
0
#
address
of
loaded
ramdisk
image
#
Here
the
loader
puts
the
32
-
bit
#
address
where
it
loaded
the
image
.
#
This
only
will
be
read
by
the
kernel
.
ramdisk_size
:
.
long
0
#
its
size
in
bytes
.
global
bootsect_kludge
#
so
that
we
can
see
it
in
bootsect
.
S
bootsect_kludge
:
.
word
bootsect_helper
,
SETUPSEG
heap_end_ptr
:
.
word
modelist
+
1024
!
space
from
here
(
exclusive
)
down
to
!
end
of
setup
code
can
be
used
by
setup
!
for
local
heap
purposes
.
.
word
bootsect_helper
,
SETUPSEG
heap_end_ptr
:
.
word
modelist
+
1024
#
space
from
here
(
exclusive
)
down
to
#
end
of
setup
code
can
be
used
by
setup
#
for
local
heap
purposes
.
trampoline
:
call
start_of_setup
.
space
1024
!
------------------------
end
of
header
----------------------------------
#
End
of
setup
header
#####################################################
start_of_setup
:
!
Bootlin
depends
on
this
being
done
early
mov
ax
,#
0x01500
mov
dl
,#
0x81
int
0x13
#
Bootlin
depends
on
this
being
done
early
mov
w
$
0x01500
,
%
ax
mov
b
$
0x81
,
%
dl
int
$
0x13
#ifdef SAFE_RESET_DISK_CONTROLLER
!
Reset
the
disk
controller
.
mov
ax
,#
0x0000
mov
dl
,#
0x80
int
0x13
#
Reset
the
disk
controller
.
mov
w
$
0x0000
,
%
ax
mov
b
$
0x80
,
$dl
int
$
0x13
#endif
!
set
DS
=
CS
,
we
know
that
SETUPSEG
==
CS
at
this
point
mov
ax
,
cs
!
aka
#
SETUPSEG
mov
ds
,
ax
!
Check
signature
at
end
of
setup
cmp
setup_sig1
,#
SIG1
#
Set
%
ds
=
%
cs
,
we
know
that
SETUPSEG
=
%
cs
at
this
point
movw
%
cs
,
%
ax
#
aka
SETUPSEG
movw
%
ax
,
%
ds
#
Check
signature
at
end
of
setup
cmpw
$SIG1
,
setup_sig1
jne
bad_sig
cmp
setup_sig2
,#
SIG2
cmpw
$SIG2
,
setup_sig2
jne
bad_sig
jmp
good_sig1
!
Routine
to
print
ASCIIz
string
at
DS
:
SI
jmp
good_sig1
prtstr
:
lodsb
and
al
,
al
#
Routine
to
print
asciiz
string
at
ds
:
si
prtstr
:
lodsb
andb
%
al
,
%
al
jz
fin
call
prtchr
jmp
prtstr
fin
:
ret
!
Space
printing
prtsp2
:
call
prtspc
!
Print
double
space
prtspc
:
mov
al
,#
0x20
!
Print
single
space
(
fall
-
thru
!)
!
Part
of
above
routine
,
this
one
just
prints
ASCII
al
fin
:
ret
prtchr
:
push
ax
push
cx
xor
bh
,
bh
mov
cx
,#
0x01
mov
ah
,#
0x0e
int
0x10
pop
cx
pop
ax
#
Space
printing
prtsp2
:
call
prtspc
#
Print
double
space
prtspc
:
movb
$
0x20
,
%
al
#
Print
single
space
(
note
:
fall
-
thru
)
#
Part
of
above
routine
,
this
one
just
prints
ascii
al
prtchr
:
pushw
%
ax
pushw
%
cx
xorb
%
bh
,
%
bh
movw
$
0x01
,
%
cx
movb
$
0x0e
,
%
ah
int
$
0x10
popw
%
cx
popw
%
ax
ret
beep
:
mov
al
,#
0x07
beep
:
mov
b
$
0x07
,
%
al
jmp
prtchr
no_sig_mess
:
.
ascii
"No setup signature found ..."
db
0x00
no_sig_mess
:
.
string
"No setup signature found ..."
good_sig1
:
jmp
good_sig
!
We
now
have
to
find
the
rest
of
the
setup
code
/
data
#
We
now
have
to
find
the
rest
of
the
setup
code
/
data
bad_sig
:
mov
ax
,
cs
!
aka
#
SETUPSEG
sub
ax
,#
DELTA_INITSEG
!
aka
#
INITSEG
mov
ds
,
ax
xor
bh
,
bh
mov
bl
,[
497
]
!
get
setup
sects
from
boot
sector
sub
bx
,#
4
!
LILO
loads
4
sectors
of
setup
shl
bx
,#
7
!
convert
to
dwords
(
1
sect
=
2
^
7
dwords
)
mov
cx
,
bx
shr
bx
,#
2
!
convert
to
segment
add
bx
,#
SYSSEG
seg
cs
mov
start_sys_seg
,
bx
!
Move
rest
of
setup
code
/
data
to
here
mov
di
,#
2048
!
four
sectors
loaded
by
LILO
sub
si
,
si
mov
ax
,
cs
!
aka
#
SETUPSEG
mov
es
,
ax
mov
ax
,#
SYSSEG
mov
ds
,
ax
movw
%
cs
,
%
ax
#
SETUPSEG
subw
$DELTA_INITSEG
,
%
ax
#
INITSEG
movw
%
ax
,
%
ds
xorb
%
bh
,
%
bh
movb
(
497
),
%
bl
#
get
setup
sect
from
bootsect
subw
$
4
,
%
bx
#
LILO
loads
4
sectors
of
setup
shlw
$
7
,
%
bx
#
convert
to
dwords
(
1
sect
=
2
^
7
dwords
)
movw
%
bx
,
%
cx
shrw
$
2
,
%
bx
#
convert
to
segment
addw
$SYSSEG
,
%
bx
movw
%
bx
,
%
cs
:
start_sys_seg
#
Move
rest
of
setup
code
/
data
to
here
movw
$
2048
,
%
di
#
four
sectors
loaded
by
LILO
subw
%
si
,
%
si
movw
%
cs
,
%
ax
#
aka
SETUPSEG
movw
%
ax
,
%
es
movw
$SYSSEG
,
%
ax
movw
%
ax
,
%
ds
rep
movsd
mov
ax
,
cs
!
aka
#
SETUPSEG
mov
ds
,
ax
cmp
setup_sig1
,#
SIG1
movsl
movw
%
cs
,
%
ax
#
aka
SETUPSEG
movw
%
ax
,
%
ds
cmpw
$SIG1
,
setup_sig1
jne
no_sig
cmp
setup_sig2
,#
SIG2
cmpw
$SIG2
,
setup_sig2
jne
no_sig
jmp
good_sig
no_sig
:
lea
si
,
no_sig_mess
lea
no_sig_mess
,
%
si
call
prtstr
no_sig_loop
:
jmp
no_sig_loop
good_sig
:
mov
ax
,
cs
!
aka
#
SETUPSEG
sub
ax
,#
DELTA_INITSEG
!
aka
#
INITSEG
mov
ds
,
ax
!
check
if
an
old
loader
tries
to
load
a
big
-
kernel
seg
cs
test
byte
ptr
loadflags
,#
LOADED_HIGH
!
Have
we
a
big
kernel
?
jz
loader_ok
!
NO
,
no
danger
even
for
old
loaders
!
YES
,
we
have
a
big
-
kernel
seg
cs
cmp
byte
ptr
type_of_loader
,#
0
!
Have
we
one
of
the
new
loaders
?
jnz
loader_ok
!
YES
,
OK
!
NO
,
we
have
an
old
loader
,
must
give
up
push
cs
pop
ds
lea
si
,
loader_panic_mess
movw
%
cs
,
%
ax
#
aka
SETUPSEG
subw
$DELTA_INITSEG
,
%
ax
#
aka
INITSEG
movw
%
ax
,
%
ds
#
Check
if
an
old
loader
tries
to
load
a
big
-
kernel
testb
$LOADED_HIGH
,
%
cs
:
loadflags
#
Do
we
have
a
big
kernel
?
jz
loader_ok
#
No
,
no
danger
for
old
loaders
.
cmpb
$
0
,
%
cs
:
type_of_loader
#
Do
we
have
a
loader
that
#
can
deal
with
us
?
jnz
loader_ok
#
Yes
,
continue
.
pushw
%
cs
#
No
,
we
have
an
old
loader
,
popw
%
ds
#
die
.
lea
loader_panic_mess
,
%
si
call
prtstr
jmp
no_sig_loop
loader_panic_mess
:
.
ascii
"Wrong loader: giving up."
db
0
loader_panic_mess
:
.
string
"Wrong loader, giving up..."
loader_ok
:
!
Get
memory
size
(
extended
mem
,
kB
)
#
Get
memory
size
(
extended
mem
,
kB
)
xor
eax
,
eax
mov
dword
ptr
[
0x1e0
],
eax
xor
l
%
eax
,
%
eax
mov
l
%
eax
,
(
0x1e0
)
#ifndef STANDARD_MEMORY_BIOS_CALL
mov
byte
ptr
[
E820NR
],
al
!
Try
three
different
memory
detection
schemes
.
First
,
try
!
e820h
,
which
lets
us
assemble
a
memory
map
,
then
try
e801h
,
!
which
returns
a
32
-
bit
memory
size
,
and
finally
88
h
,
which
!
returns
0
-
64
m
!
method
E820H
:
!
the
memory
map
from
hell
.
e820h
returns
memory
classified
into
!
a
whole
bunch
of
different
types
,
and
allows
memory
holes
and
!
everything
.
We
scan
through
this
memory
map
and
build
a
list
!
of
the
first
32
memory
areas
,
which
we
return
at
[
E820MAP
]
.
!
movb
%
al
,
(
E820NR
)
#
Try
three
different
memory
detection
schemes
.
First
,
try
#
e820h
,
which
lets
us
assemble
a
memory
map
,
then
try
e801h
,
#
which
returns
a
32
-
bit
memory
size
,
and
finally
88
h
,
which
#
returns
0
-
64
m
#
method
E820H
:
#
the
memory
map
from
hell
.
e820h
returns
memory
classified
into
#
a
whole
bunch
of
different
types
,
and
allows
memory
holes
and
#
everything
.
We
scan
through
this
memory
map
and
build
a
list
#
of
the
first
32
memory
areas
,
which
we
return
at
[
E820MAP
]
.
#
meme820
:
mov
edx
,
#
0x534d4150
!
ascii
`
SMAP
'
xor
ebx
,
ebx
!
continuation
counter
mov
di
,
#
E820MAP
!
point
into
the
whitelist
!
so
we
can
have
the
bios
!
directly
write
into
it
.
movl
$
0x534d4150
,
%
edx
#
ascii
`
SMAP
'
xorl
%
ebx
,
%
ebx
#
continuation
counter
movw
$E820MAP
,
%
di
#
point
into
the
whitelist
#
so
we
can
have
the
bios
#
directly
write
into
it
.
jmpe820
:
mov
eax
,
#
0x0000e820
!
e820
,
upper
word
zeroed
mov
ecx
,
#
20
!
size
of
the
e820rec
push
ds
!
data
record
.
pop
es
int
0x15
!
make
the
call
jc
bail820
!
fall
to
e801
if
it
fails
cmp
eax
,
#
0x534d4150
!
check
the
return
is
`
SMAP
'
jne
bail820
!
fall
to
e801
if
it
fails
!
cmp
dword
ptr
[
16
+
di
],
#
1
!
is
this
usable
memory
?
!
jne
again820
!
If
this
is
usable
memory
,
we
save
it
by
simply
advancing
di
by
!
sizeof
(
e820rec
)
.
!
movl
$
0x0000e820
,
%
eax
#
e820
,
upper
word
zeroed
movl
$
20
,
%
ecx
#
size
of
the
e820rec
pushw
%
ds
#
data
record
.
popw
%
es
int
$
0x15
#
make
the
call
jc
bail820
#
fall
to
e801
if
it
fails
cmpl
$
0x534d4150
,
%
eax
#
check
the
return
is
`
SMAP
'
jne
bail820
#
fall
to
e801
if
it
fails
#
cmpl
$
1
,
16
(%
di
)
#
is
this
usable
memory
?
#
jne
again820
#
If
this
is
usable
memory
,
we
save
it
by
simply
advancing
%
di
by
#
sizeof
(
e820rec
)
.
#
good820
:
mov
al
,
byte
ptr
[
E820NR
]
!
up
to
32
good
entries
,
that
i
s
cmp
al
,
#
E820MAX
mov
b
(
E820NR
),
%
al
#
up
to
32
entrie
s
cmp
b
$E820MAX
,
%
al
jnl
bail820
inc
byte
ptr
[
E820NR
]
mov
ax
,
di
add
ax
,
#
20
mov
di
,
ax
incb
(
E820NR
)
movw
%
di
,
%
ax
addw
$
20
,
%
ax
movw
%
ax
,
%
di
again820
:
cmp
ebx
,
#
0
!
check
to
see
if
ebx
is
jne
jmpe820
!
set
to
EOF
cmpl
$
0
,
%
ebx
#
check
to
see
if
jne
jmpe820
#
%
ebx
is
set
to
EOF
bail820
:
!
method
E801H
:
!
memory
size
is
in
1
k
chunksizes
,
to
avoid
confusing
loadlin
.
!
we
store
the
0xe801
memory
size
in
a
completely
different
place
,
!
because
it
will
most
likely
be
longer
than
16
bits
.
!
(
use
1e0
because
that
's what Larry Augustine uses in his
!
alternative
new
memory
detection
scheme
,
and
it
's sensible
!
to
write
everything
into
the
same
place
.
)
#
method
E801H
:
#
memory
size
is
in
1
k
chunksizes
,
to
avoid
confusing
loadlin
.
#
we
store
the
0xe801
memory
size
in
a
completely
different
place
,
#
because
it
will
most
likely
be
longer
than
16
bits
.
#
(
use
1e0
because
that
's what Larry Augustine uses in his
#
alternative
new
memory
detection
scheme
,
and
it
's sensible
#
to
write
everything
into
the
same
place
.
)
meme801
:
mov
ax
,#
0xe801
int
0x15
movw
$
0xe801
,
%
ax
int
$
0x15
jc
mem88
and
edx
,
#
0xffff
!
clear
sign
extend
shl
edx
,
6
!
and
go
from
64
k
to
1
k
chunks
mov
[
0x1e0
],
edx
!
store
extended
memory
size
and
ecx
,
#
0xffff
!
clear
sign
extend
add
[
0x1e0
],
ecx
!
and
add
lower
memory
into
total
size
.
and
l
$
0xffff
,
%
edx
#
clear
sign
extend
shl
l
$
6
,
%
edx
#
and
go
from
64
k
to
1
k
chunks
mov
l
%
edx
,
(
0x1e0
)
#
store
extended
memory
size
andl
$
0xffff
,
%
ecx
#
clear
sign
extend
addl
%
ecx
,
(
0x1e0
)
#
and
add
lower
memory
into
#
total
size
.
!
Ye
Olde
Traditional
Methode
.
Returns
the
memory
size
(
up
to
16
mb
or
!
64
mb
,
depending
on
the
bios
)
in
ax
.
#
Ye
Olde
Traditional
Methode
.
Returns
the
memory
size
(
up
to
16
mb
or
#
64
mb
,
depending
on
the
bios
)
in
ax
.
mem88
:
#endif
mov
ah
,#
0x88
int
0x15
mov
[
2
],
ax
!
Set
the
keyboard
repeat
rate
to
the
max
mov
ax
,#
0x0305
xor
bx
,
bx
!
clear
bx
int
0x16
!
Check
for
video
adapter
and
its
parameters
and
allow
the
!
user
to
browse
video
modes
.
call
video
!
NOTE
:
we
need
DS
pointing
to
boot
sector
!
Get
hd0
data
xor
ax
,
ax
!
clear
ax
mov
ds
,
ax
lds
si
,[
4
*
0x41
]
mov
ax
,
cs
!
aka
#
SETUPSEG
sub
ax
,#
DELTA_INITSEG
!
aka
#
INITSEG
push
ax
mov
es
,
ax
mov
di
,#
0x0080
mov
cx
,#
0x10
push
cx
movb
$
0x88
,
%
ah
int
$
0x15
movw
%
ax
,
(
2
)
#
Set
the
keyboard
repeat
rate
to
the
max
movw
$
0x0305
,
%
ax
xorw
%
bx
,
%
bx
int
$
0x16
#
Check
for
video
adapter
and
its
parameters
and
allow
the
#
user
to
browse
video
modes
.
call
video
#
NOTE
:
we
need
%
ds
pointing
#
to
bootsector
#
Get
hd0
data
...
xorw
%
ax
,
%
ax
movw
%
ax
,
%
ds
ldsw
(
4
*
0x41
),
%
si
movw
%
cs
,
%
ax
#
aka
SETUPSEG
subw
$DELTA_INITSEG
,
%
ax
#
aka
INITSEG
pushw
%
ax
movw
%
ax
,
%
es
movw
$
0x0080
,
%
di
movw
$
0x10
,
%
cx
pushw
%
cx
cld
rep
movsb
!
Get
hd1
data
xor
ax
,
ax
!
clear
ax
mov
ds
,
ax
lds
si
,[
4
*
0x46
]
pop
cx
pop
es
mov
di
,#
0x0090
movsb
#
Get
hd1
data
...
xorw
%
ax
,
%
ax
movw
%
ax
,
%
ds
ldsw
(
4
*
0x46
),
%
si
popw
%
cx
popw
%
es
movw
$
0x0090
,
%
di
rep
movsb
!
Check
that
there
IS
a
hd1
:
-)
mov
ax
,#
0x01500
mov
dl
,#
0x81
int
0x13
#
Check
that
there
IS
a
hd1
:
-)
movw
$
0x01500
,
%
ax
movb
$
0x81
,
%
dl
int
$
0x13
jc
no_disk1
cmp
ah
,#
3
cmpb
$
3
,
%
ah
je
is_disk1
no_disk1
:
mov
ax
,
cs
!
aka
#
SETUPSEG
sub
ax
,#
DELTA_INITSEG
!
aka
#
INITSEG
mov
es
,
ax
mov
di
,#
0x0090
mov
cx
,#
0x10
xor
ax
,
ax
!
clear
ax
mov
w
%
cs
,
%
ax
#
aka
SETUPSEG
sub
w
$DELTA_INITSEG
,
%
ax
#
aka
INITSEG
mov
w
%
ax
,
%
es
mov
w
$
0x0090
,
%
di
mov
w
$
0x10
,
%
cx
xor
w
%
ax
,
%
ax
cld
rep
stosb
is_disk1
:
!
check
for
Micro
Channel
(
MCA
)
bus
mov
ax
,
cs
!
aka
#
SETUPSEG
sub
ax
,#
DELTA_INITSEG
!
aka
#
INITSEG
mov
ds
,
ax
mov
ds
,
ax
xor
ax
,
ax
mov
[
0xa0
],
ax
!
set
table
length
to
0
mov
ah
,
#
0xc0
#
check
for
Micro
Channel
(
MCA
)
bus
movw
%
cs
,
%
ax
#
aka
SETUPSEG
subw
$DELTA_INITSEG
,
%
ax
#
aka
INITSEG
movw
%
ax
,
%
ds
xorw
%
ax
,
%
ax
movw
%
ax
,
0xa0
#
set
table
length
to
0
movb
$
0xc0
,
%
ah
stc
int
0x15
!
puts
feature
table
at
es
:
bx
jc
no_mca
push
ds
mov
ax
,
es
mov
ds
,
ax
mov
ax
,
cs
!
aka
#
SETUPSEG
sub
ax
,
#
DELTA_INITSEG
!
aka
#
INITSEG
mov
es
,
ax
mov
si
,
bx
mov
di
,#
0xa0
mov
cx
,(
si
)
add
cx
,#
2
!
table
length
is
a
short
cmp
cx
,#
0x10
jc
sysdesc_ok
mov
cx
,#
0x10
!
we
keep
only
first
16
bytes
int
$
0x15
#
moves
feature
table
to
es
:
bx
jc
no_mca
pushw
%
ds
movw
%
es
,
%
ax
movw
%
ax
,
%
ds
movw
%
cs
,
%
ax
#
aka
SETUPSEG
subw
$DELTA_INITSEG
,
%
ax
#
aka
INITSEG
movw
%
ax
,
%
es
movw
%
bx
,
%
si
movw
$
0xa0
,
%
di
movw
(%
si
),
%
cx
addw
$
2
,
%
cx
#
table
length
is
a
short
cmpw
$
0x10
,
%
cx
jc
sysdesc_ok
movw
$
0x10
,
%
cx
#
we
keep
only
first
16
bytes
sysdesc_ok
:
rep
movsb
pop
ds
popw
%
ds
no_mca
:
!
Check
for
PS
/
2
pointing
device
mov
ax
,
cs
!
aka
#
SETUPSEG
sub
ax
,#
DELTA_INITSEG
!
aka
#
INITSEG
mov
ds
,
ax
mov
[
0x1ff
],#
0
!
default
is
no
pointing
device
int
0x11
!
int
0x11
:
equipment
determination
test
al
,#
0x04
!
check
if
pointing
device
installed
#
Check
for
PS
/
2
pointing
device
movw
%
cs
,
%
ax
#
aka
SETUPSEG
subw
$DELTA_INITSEG
,
%
ax
#
aka
INITSEG
movw
%
ax
,
%
ds
movw
$
0
,
(
0x1ff
)
#
default
is
no
pointing
device
int
$
0x11
#
int
0x11
:
equipment
list
testb
$
0x04
,
%
al
#
check
if
mouse
installed
jz
no_psmouse
mov
[
0x1ff
],#
0xaa
!
device
present
movw
$
0xAA
,
(
0x1ff
)
#
device
present
no_psmouse
:
#ifdef CONFIG_APM
!
check
for
APM
BIOS
!
NOTE
:
DS
is
pointing
to
the
boot
sector
!
mov
[
64
],#
0
!
version
==
0
means
no
APM
BIOS
mov
ax
,#
0x05300
!
APM
BIOS
installation
check
xor
bx
,
bx
int
0x15
jc
done_apm_bios
!
error
->
no
APM
BIOS
cmp
bx
,#
0x0504d
!
check
for
"PM"
signature
jne
done_apm_bios
!
no
signature
->
no
APM
BIOS
and
cx
,#
0x02
!
Is
32
bit
supported
?
je
done_apm_bios
!
no
...
mov
ax
,#
0x05304
!
Disconnect
first
just
in
case
xor
bx
,
bx
int
0x15
!
ignore
return
code
mov
ax
,#
0x05303
!
32
bit
connect
xor
ebx
,
ebx
int
0x15
jc
no_32_apm_bios
!
error
mov
[
66
],
ax
!
BIOS
code
segment
mov
[
68
],
ebx
!
BIOS
entry
point
offset
mov
[
72
],
cx
!
BIOS
16
bit
code
segment
mov
[
74
],
dx
!
BIOS
data
segment
mov
[
78
],
esi
!
BIOS
code
segment
length
mov
[
82
],
di
!
BIOS
data
segment
length
!
!
Redo
the
installation
check
as
the
32
bit
connect
!
modifies
the
flags
returned
on
some
BIOSs
!
mov
ax
,#
0x05300
!
APM
BIOS
installation
check
xor
bx
,
bx
int
0x15
jc
apm_disconnect
!
error
->
should
not
happen
,
tidy
up
cmp
bx
,#
0x0504d
!
check
for
"PM"
signature
jne
apm_disconnect
!
no
signature
->
should
not
happen
,
tidy
up
mov
[
64
],
ax
!
record
the
APM
BIOS
version
mov
[
76
],
cx
!
and
flags
#
Then
check
for
an
APM
BIOS
...
#
%
ds
points
to
the
bootsector
movw
$
0
,
0x40
#
version
=
0
means
no
APM
BIOS
movw
$
0x05300
,
%
ax
#
APM
BIOS
installation
check
xorw
%
bx
,
%
bx
int
$
0x15
jc
done_apm_bios
#
Nope
,
no
APM
BIOS
cmpw
$
0x0504d
,
%
bx
#
Check
for
"PM"
signature
jne
done_apm_bios
#
No
signature
,
no
APM
BIOS
andw
$
0x02
,
%
cx
#
Is
32
bit
supported
?
je
done_apm_bios
#
No
32
-
bit
,
no
(
good
)
APM
BIOS
movw
$
0x05304
,
%
ax
#
Disconnect
first
just
in
case
xorw
%
bx
,
%
bx
int
$
0x15
#
ignore
return
code
movw
$
0x05303
,
%
ax
#
32
bit
connect
xorw
%
ebx
,
%
ebx
int
$
0x15
jc
no_32_apm_bios
#
Ack
,
error
.
movw
%
ax
,
(
66
)
#
BIOS
code
segment
movl
%
ebx
,
(
68
)
#
BIOS
entry
point
offset
movw
%
cx
,
(
72
)
#
BIOS
16
bit
code
segment
movw
%
dx
,
(
74
)
#
BIOS
data
segment
movl
%
esi
,
(
78
)
#
BIOS
code
segment
length
movw
%
di
,
(
82
)
#
BIOS
data
segment
length
#
Redo
the
installation
check
as
the
32
bit
connect
#
modifies
the
flags
returned
on
some
BIOSs
movw
$
0x05300
,
%
ax
#
APM
BIOS
installation
check
xorw
%
bx
,
%
bx
int
$
0x15
jc
apm_disconnect
#
error
->
shouldn
't happen
cmpw
$
0x0504d
,
%
bx
#
check
for
"PM"
signature
jne
apm_disconnect
#
no
sig
->
shouldn
't happen
movw
%
ax
,
(
64
)
#
record
the
APM
BIOS
version
movw
%
cx
,
(
76
)
#
and
flags
jmp
done_apm_bios
apm_disconnect
:
mov
ax
,#
0x05304
!
Disconnect
xor
bx
,
bx
int
0x15
!
ignore
return
code
apm_disconnect
:
#
Tidy
up
movw
$
0x05304
,
%
ax
#
Disconnect
xorw
%
bx
,
%
bx
int
$
0x15
#
ignore
return
code
jmp
done_apm_bios
no_32_apm_bios
:
and
[
76
],
#
0xfffd
!
remove
32
bit
support
bit
andw
$
0xfffd
,
(
76
)
#
remove
32
bit
support
bit
done_apm_bios
:
#endif
!
Now
we
want
to
move
to
protected
mode
...
seg
cs
cmp
realmode_swtch
,#
0
#
Now
we
want
to
move
to
protected
mode
...
cmpw
$
0
,
%
cs
:
realmode_swtch
jz
rmodeswtch_normal
seg
cs
callf
far
*
realmode_swtch
call
*%
cs
:
realmode_swtch
jmp
rmodeswtch_end
rmodeswtch_normal
:
push
cs
push
w
%
cs
call
default_switch
rmodeswtch_end
:
!
we
get
the
code32
start
address
and
modify
the
below
'jmpi'
!
(
loader
may
have
changed
it
)
seg
cs
mov
eax
,
code32_start
seg
cs
mov
code32
,
eax
!
Now
we
move
the
system
to
its
rightful
place
!
...
but
we
check
,
if
we
have
a
big
-
kernel
.
!
in
this
case
we
*
must
*
not
move
it
...
seg
cs
test
byte
ptr
loadflags
,#
LOADED_HIGH
jz
do_move0
!
we
have
a
normal
low
loaded
zImage
!
we
have
a
high
loaded
big
kernel
jmp
end_move
!
...
and
we
skip
moving
rmodeswtch_end
:
#
we
get
the
code32
start
address
and
modify
the
below
'jmpi'
#
(
loader
may
have
changed
it
)
movl
%
cs
:
code32_start
,
%
eax
movl
%
eax
,
%
cs
:
code32
#
Now
we
move
the
system
to
its
rightful
place
...
but
we
check
if
we
have
a
#
big
-
kernel
.
In
that
case
we
*
must
*
not
move
it
...
testb
$LOADED_HIGH
,
%
cs
:
loadflags
jz
do_move0
#
..
then
we
have
a
normal
low
#
loaded
zImage
#
..
or
else
we
have
a
high
#
loaded
bzImage
jmp
end_move
#
...
and
we
skip
moving
do_move0
:
mov
ax
,#
0x100
!
start
of
destination
segment
mov
bp
,
cs
!
aka
#
SETUPSEG
sub
bp
,#
DELTA_INITSEG
!
aka
#
INITSEG
seg
cs
mov
bx
,
start_sys_seg
!
start
of
source
segment
cld
!
'direction'
=
0
,
movs
moves
forward
movw
$
0x100
,
%
ax
#
start
of
destination
segment
movw
%
cs
,
%
bp
#
aka
SETUPSEG
subw
$DELTA_INITSEG
,
%
bp
#
aka
INITSEG
movw
%
cs
:
start_sys_seg
,
%
bx
#
start
of
source
segment
cld
do_move
:
mov
es
,
ax
!
destination
segment
inc
ah
!
instead
of
add
ax
,#
0x100
mov
ds
,
bx
!
source
segment
add
bx
,#
0x100
sub
di
,
di
sub
si
,
si
mov
cx
,#
0x400
mov
w
%
ax
,
%
es
#
destination
segment
inc
b
%
ah
#
instead
of
add
ax
,#
0x100
mov
w
%
bx
,
%
ds
#
source
segment
add
w
$
0x100
,
%
bx
sub
w
%
di
,
%
di
sub
w
%
si
,
%
si
mov
w
$
0x400
,
%
cx
rep
movsd
cmp
bx
,
bp
!
we
assume
start_sys_seg
>
0x200
,
!
so
we
will
perhaps
read
one
page
more
then
!
needed
,
but
never
overwrite
INITSEG
because
!
destination
is
minimum
one
page
below
source
movsl
cmpw
%
bp
,
%
bx
#
assume
start_sys_seg
>
0x200
,
#
so
we
will
perhaps
read
one
#
page
more
than
needed
,
but
#
never
overwrite
INITSEG
#
because
destination
is
a
#
minimum
one
page
below
source
jb
do_move
!
then
we
load
the
segment
descriptors
end_move
:
mov
ax
,
cs
!
aka
#
SETUPSEG
!
right
,
forgot
this
at
first
.
didn
't work :-)
mov
ds
,
ax
!
If
we
have
our
code
not
at
0x90000
,
we
need
to
move
it
there
now
.
!
We
also
then
need
to
move
the
parameters
behind
it
(
command
line
)
!
Because
we
would
overwrite
the
code
on
the
current
IP
,
we
move
!
it
in
two
steps
,
jumping
high
after
the
first
one
.
mov
ax
,
cs
cmp
ax
,#
SETUPSEG
#
then
we
load
the
segment
descriptors
movw
%
cs
,
%
ax
#
aka
SETUPSEG
movw
%
ax
,
%
ds
#
If
we
have
our
code
not
at
0x90000
,
we
need
to
move
it
there
now
.
#
We
also
then
need
to
move
the
params
behind
it
(
commandline
)
#
Because
we
would
overwrite
the
code
on
the
current
IP
,
we
move
#
it
in
two
steps
,
jumping
high
after
the
first
one
.
movw
%
cs
,
%
ax
cmpw
$SETUPSEG
,
%
ax
je
end_move_self
cli
!
make
sure
we
really
have
interrupts
disabled
!
!
because
after
this
the
stack
should
not
be
used
sub
ax
,#
DELTA_INITSEG
!
aka
#
INITSEG
mov
dx
,
ss
cmp
dx
,
ax
cli
#
make
sure
we
really
have
#
interrupts
disabled
!
#
because
after
this
the
stack
#
should
not
be
used
subw
$DELTA_INITSEG
,
%
ax
#
aka
INITSEG
movw
%
ss
,
%
dx
cmpw
%
ax
,
%
dx
jb
move_self_1
add
dx
,#
INITSEG
sub
dx
,
ax
!
this
will
be
SS
after
the
move
addw
$INITSEG
,
%
dx
subw
%
ax
,
%
dx
#
this
will
go
into
%
ss
after
#
the
move
move_self_1
:
mov
ds
,
ax
mov
ax
,#
INITSEG
!
real
INITSEG
mov
es
,
ax
seg
cs
mov
cx
,
setup_move_siz
e
std
!
we
have
to
move
up
,
so
we
use
direction
down
!
because
the
areas
may
overlap
mov
di
,
cx
dec
di
mov
si
,
d
i
sub
cx
,#
move_self_here
+
0x200
mov
w
%
ax
,
%
ds
mov
w
$INITSEG
,
%
ax
#
real
INITSEG
mov
w
%
ax
,
%
es
movw
%
cs
:
setup_move_size
,
%
cx
std
#
we
have
to
move
up
,
so
we
us
e
#
direction
down
because
the
#
areas
may
overlap
mov
w
%
cx
,
%
di
dec
w
%
di
mov
w
%
di
,
%
s
i
sub
w
$move_self_here
+
0x200
,
%
cx
rep
movsb
jmpi
move_self_here
,
SETUPSEG
!
jump
to
our
final
place
ljmp
$SETUPSEG
,
$move_self_here
move_self_here
:
mov
cx
,#
move_self_here
+
0x200
mov
w
$move_self_here
+
0x200
,
%
cx
rep
movsb
mov
ax
,#
SETUPSEG
mov
ds
,
ax
mov
ss
,
dx
!
now
we
are
at
the
right
place
end_move_self
:
lidt
idt_48
!
load
idt
with
0
,
0
lgdt
gdt_48
!
load
gdt
with
whatever
appropriate
!
that
was
painless
,
now
we
enable
A20
call
empty_8042
mov
al
,#
0xD1
!
command
write
out
#
0x64
,
al
call
empty_8042
mov
al
,#
0xDF
!
A20
on
out
#
0x60
,
al
movw
$SETUPSEG
,
%
ax
movw
%
ax
,
%
ds
movw
%
dx
,
%
ss
end_move_self
:
#
now
we
are
at
the
right
place
lidt
idt_48
#
load
idt
with
0
,
0
lgdt
gdt_48
#
load
gdt
with
whatever
is
#
appropriate
#
that
was
painless
,
now
we
enable
a20
call
empty_8042
!
wait
until
a20
really
*
is
*
enabled
; it can take a fair amount of
!
time
on
certain
systems
; Toshiba Tecras are known to have this
!
problem
.
The
memory
location
used
here
is
the
int
0x1f
vector
,
!
which
should
be
safe
to
use
; any *unused* memory location < 0xfff0
!
should
work
here
.
movb
$
0xD1
,
%
al
#
command
write
outb
%
al
,
$
0x64
call
empty_8042
#define TEST_ADDR 0x7c
movb
$
0xDF
,
%
al
#
A20
on
outb
%
al
,
$
0x60
call
empty_8042
push
ds
xor
ax
,
ax
!
segment
0x0000
mov
ds
,
ax
dec
ax
!
segment
0xffff
(
HMA
)
mov
gs
,
ax
mov
bx
,[
TEST_ADDR
]
!
we
want
to
restore
the
value
later
#
wait
until
a20
really
*
is
*
enabled
; it can take a fair amount of
#
time
on
certain
systems
; Toshiba Tecras are known to have this
#
problem
.
The
memory
location
used
here
(
0x200
)
is
the
int
0x80
#
vector
,
which
should
be
safe
to
use
.
push
%
ds
push
%
es
xorw
%
ax
,
%
ax
#
segment
0x0000
movw
%
ax
,
%
fs
decw
%
ax
#
segment
0xffff
(
HMA
)
movw
%
ax
,
%
gs
a20_wait
:
inc
ax
mov
[
TEST_ADDR
],
ax
seg
gs
cmp
ax
,[
TEST_ADDR
+
0x10
]
je
a20_wait
!
loop
until
no
longer
aliased
mov
[
TEST_ADDR
],
bx
!
restore
original
value
pop
ds
!
make
sure
any
possible
coprocessor
is
properly
reset
..
xor
ax
,
ax
out
#
0xf0
,
al
call
delay
out
#
0xf1
,
al
incw
%
ax
#
unused
memory
location
<
0xfff0
movw
%
ax
,
%
fs
:
(
0x200
)
#
we
use
the
"int 0x80"
vector
cmpw
%
gs
:
(
0x210
),
%
ax
#
and
its
corresponding
HMA
addr
je
a20_wait
#
loop
until
no
longer
aliased
#
make
sure
any
possible
coprocessor
is
properly
reset
..
xorw
%
ax
,
%
ax
outb
%
al
,
$
0xf0
call
delay
!
well
,
that
went
ok
,
I
hope
.
Now
we
mask
all
interrupts
-
the
rest
!
is
done
in
init_IRQ
()
.
outb
%
al
,
$
0xf1
call
delay
mov
al
,#
0xFF
!
mask
off
all
interrupts
for
now
out
#
0xA1
,
al
#
well
,
that
went
ok
,
I
hope
.
Now
we
mask
all
interrupts
-
the
rest
#
is
done
in
init_IRQ
()
.
movb
$
0xFF
,
%
al
#
mask
all
interrupts
for
now
outb
%
al
,
$
0xA1
call
delay
mov
al
,#
0xFB
!
mask
all
irq
's but irq2 which
out
#
0x21
,
al
!
is
cascaded
!
Well
,
that
certainly
wasn
't fun :-(. Hopefully it works, and we don'
t
!
need
no
steenking
BIOS
anyway
(
except
for
the
initial
loading
:
-)
.
!
The
BIOS
routine
wants
lots
of
unnecessary
data
,
and
it
's less
!
"
interesting
"
anyway
.
This
is
how
REAL
programmers
do
it
.
!
!
Well
,
now
's the time to actually move into protected mode. To make
!
things
as
simple
as
possible
,
we
do
no
register
set
-
up
or
anything
,
!
we
let
the
GNU
-
compiled
32
-
bit
programs
do
that
.
We
just
jump
to
!
absolute
address
0x1000
(
or
the
loader
supplied
one
),
!
in
32
-
bit
protected
mode
.
!
!
Note
that
the
short
jump
isn
't strictly needed, although there are
!
reasons
why
it
might
be
a
good
idea
.
It
won
't hurt in any case.
!
mov
ax
,#
1
!
protected
mode
(
PE
)
bit
lmsw
ax
!
This
is
it
!
movb
$
0xFB
,
%
al
#
mask
all
irq
's but irq2 which
outb
%
al
,
$
0x21
#
is
cascaded
#
Well
,
that
certainly
wasn
't fun :-(. Hopefully it works, and we don'
t
#
need
no
steenking
BIOS
anyway
(
except
for
the
initial
loading
:
-)
.
#
The
BIOS
-
routine
wants
lots
of
unnecessary
data
,
and
it
's less
#
"
interesting
"
anyway
.
This
is
how
REAL
programmers
do
it
.
#
#
Well
,
now
's the time to actually move into protected mode. To make
#
things
as
simple
as
possible
,
we
do
no
register
set
-
up
or
anything
,
#
we
let
the
gnu
-
compiled
32
-
bit
programs
do
that
.
We
just
jump
to
#
absolute
address
0x1000
(
or
the
loader
supplied
one
),
#
in
32
-
bit
protected
mode
.
#
#
Note
that
the
short
jump
isn
't strictly needed, although there are
#
reasons
why
it
might
be
a
good
idea
.
It
won
't hurt in any case.
mov
w
$
1
,
%
ax
#
protected
mode
(
PE
)
bit
lmsw
%
ax
#
This
is
it
!
jmp
flush_instr
flush_instr
:
xor
bx
,
bx
!
Flag
to
indicate
a
boot
!
NOTE
:
For
high
loaded
big
kernels
we
need
a
!
jmpi
0x100000
,
__KERNEL_CS
!
!
but
we
yet
haven
't reloaded the CS register, so the default size
!
of
the
target
offset
still
is
16
bit
.
!
However
,
using
an
operant
prefix
(
0x66
),
the
CPU
will
properly
!
take
our
48
bit
far
pointer
.
(
INTeL
80386
Programmer
's Reference
!
Manual
,
Mixing
16
-
bit
and
32
-
bit
code
,
page
16
-
6
)
db
0x66
,
0xea
!
prefix
+
jmpi
-
opcode
code32
:
dd
0x1000
!
will
be
set
to
0x100000
for
big
kernels
dw
__KERNEL_CS
flush_instr
:
xorw
%
bx
,
%
bx
#
Flag
to
indicate
a
boot
#
NOTE
:
For
high
loaded
big
kernels
we
need
a
#
jmpi
0x100000
,
__KERNEL_CS
#
#
but
we
yet
haven
't reloaded the CS register, so the default size
#
of
the
target
offset
still
is
16
bit
.
#
However
,
using
an
operant
prefix
(
0x66
),
the
CPU
will
properly
#
take
our
48
bit
far
pointer
.
(
INTeL
80386
Programmer
's Reference
#
Manual
,
Mixing
16
-
bit
and
32
-
bit
code
,
page
16
-
6
)
.
byte
0x66
,
0xea
#
prefix
+
jmpi
-
opcode
code32
:
.
long
0x1000
#
will
be
set
to
0x100000
#
for
big
kernels
.
word
__KERNEL_CS
#
Here
'
s
a
bunch
of
information
about
your
current
kernel
..
kernel_version
:
.
ascii
UTS_RELEASE
.
ascii
" ("
.
ascii
LINUX_COMPILE_BY
...
...
@@ -690,191 +682,184 @@ kernel_version: .ascii UTS_RELEASE
.
ascii
LINUX_COMPILE_HOST
.
ascii
") "
.
ascii
UTS_VERSION
db
0
!
This
is
the
default
real
mode
switch
routine
.
!
to
be
called
just
before
protected
mode
transition
.
byte
0
#
This
is
the
default
real
mode
switch
routine
.
#
to
be
called
just
before
protected
mode
transition
default_switch
:
cli
!
no
interrupts
allowed
!
mov
al
,#
0x80
!
disable
NMI
for
the
bootup
sequence
out
#
0x70
,
al
retf
!
This
routine
only
gets
called
,
if
we
get
loaded
by
the
simple
!
bootsect
loader
_and_
have
a
bzImage
to
load
.
!
Because
there
is
no
place
left
in
the
512
bytes
of
the
boot
sector
,
!
we
must
emigrate
to
code
space
here
.
!
cli
#
no
interrupts
allowed
!
mov
b
$
0x80
,
%
al
#
disable
NMI
for
bootup
#
sequence
outb
%
al
,
$
0x70
lret
#
This
routine
only
gets
called
,
if
we
get
loaded
by
the
simple
#
bootsect
loader
_and_
have
a
bzImage
to
load
.
#
Because
there
is
no
place
left
in
the
512
bytes
of
the
boot
sector
,
#
we
must
emigrate
to
code
space
here
.
bootsect_helper
:
seg
cs
cmp
word
ptr
bootsect_es
,#
0
cmpw
$
0
,
%
cs
:
bootsect_es
jnz
bootsect_second
seg
cs
mov
byte
ptr
type_of_loader
,#
0x20
mov
ax
,
es
shr
ax
,#
4
seg
cs
mov
byte
ptr
bootsect_src_base
+
2
,
ah
mov
ax
,
es
seg
cs
mov
bootsect_es
,
ax
sub
ax
,#
SYSSEG
retf
!
nothing
else
to
do
for
now
movb
$
0x20
,
%
cs
:
type_of_loader
movw
%
es
,
%
ax
shrw
$
4
,
%
ax
movb
%
ah
,
%
cs
:
bootsect_src_base
+
2
movw
%
es
,
%
ax
movw
%
ax
,
%
cs
:
bootsect_es
subw
$SYSSEG
,
%
ax
lret
#
nothing
else
to
do
for
now
bootsect_second
:
push
cx
push
si
push
bx
test
bx
,
bx
!
64
K
full
?
push
w
%
cx
push
w
%
si
push
w
%
bx
test
w
%
bx
,
%
bx
#
64
K
full
?
jne
bootsect_ex
mov
cx
,#
0x8000
!
full
64
K
move
,
INT15
moves
words
push
c
s
p
op
e
s
mov
si
,#
bootsect_gdt
mov
ax
,#
0x8700
int
0x15
jc
bootsect_panic
!
this
,
if
INT15
fails
seg
c
s
mov
es
,
bootsect_es
!
we
reset
es
to
always
point
to
0x10000
seg
cs
inc
byte
ptr
bootsect_dst_base
+
2
movw
$
0x8000
,
%
cx
#
full
64
K
,
INT15
moves
word
s
p
ushw
%
c
s
popw
%
es
mov
w
$bootsect_gdt
,
%
si
movw
$
0x8700
,
%
ax
int
$
0x15
jc
bootsect_panic
#
this
,
if
INT15
fail
s
movw
%
cs
:
bootsect_es
,
%
es
#
we
reset
%
es
to
always
point
inc
b
%
cs
:
bootsect_dst_base
+
2
#
to
0x10000
bootsect_ex
:
seg
cs
mov
ah
,
byte
ptr
bootsect_dst_base
+
2
shl
ah
,
4
!
we
now
have
the
number
of
moved
frames
in
ax
xor
al
,
al
pop
bx
pop
si
pop
cx
retf
movb
%
cs
:
bootsect_dst_base
+
2
,
%
ah
shlb
$
4
,
%
ah
#
we
now
have
the
number
of
#
moved
frames
in
%
ax
xor
b
%
al
,
%
al
pop
w
%
bx
pop
w
%
si
pop
w
%
cx
lret
bootsect_gdt
:
.
word
0
,
0
,
0
,
0
.
word
0
,
0
,
0
,
0
.
word
0
,
0
,
0
,
0
.
word
0
,
0
,
0
,
0
bootsect_src
:
.
word
0xffff
bootsect_src_base
:
.
byte
0
,
0
,
1
!
base
=
0x010000
.
byte
0x93
!
typbyte
.
word
0
!
limit16
,
base24
=
0
.
byte
0x00
,
0x00
,
0x01
#
base
=
0x010000
.
byte
0x93
#
typbyte
.
word
0
#
limit16
,
base24
=
0
bootsect_dst
:
.
word
0xffff
bootsect_dst_base
:
.
byte
0
,
0
,
0x10
!
base
=
0x100000
.
byte
0x93
!
typbyte
.
word
0
!
limit16
,
base24
=
0
.
word
0
,
0
,
0
,
0
!
BIOS
CS
.
word
0
,
0
,
0
,
0
!
BIOS
DS
.
byte
0x00
,
0x00
,
0x10
#
base
=
0x100000
.
byte
0x93
#
typbyte
.
word
0
#
limit16
,
base24
=
0
.
word
0
,
0
,
0
,
0
#
BIOS
CS
.
word
0
,
0
,
0
,
0
#
BIOS
DS
bootsect_es
:
.
word
0
bootsect_panic
:
push
cs
pop
ds
push
w
%
cs
pop
w
%
ds
cld
lea
si
,
bootsect_panic_mess
lea
w
bootsect_panic_mess
,
%
si
call
prtstr
bootsect_panic_loop
:
jmp
bootsect_panic_loop
bootsect_panic_mess
:
.
ascii
"INT15 refuses to access high memory. Giving up."
db
0
.
string
"INT15 refuses to access high mem, giving up."
!
This
routine
checks
that
the
keyboard
command
queue
is
empty
!
(
after
emptying
the
output
buffers
)
!
!
Some
machines
have
delusions
that
the
keyboard
buffer
is
always
full
!
with
no
keyboard
attached
...
#
This
routine
checks
that
the
keyboard
command
queue
is
empty
#
(
after
emptying
the
output
buffers
)
#
#
Some
machines
have
delusions
that
the
keyboard
buffer
is
always
full
#
with
no
keyboard
attached
...
empty_8042
:
push
ecx
mov
ecx
,#
0xFFFFFF
pushl
%
ecx
movl
$
0xFFFFFF
,
%
ecx
empty_8042_loop
:
dec
ecx
jz
empty_8042_end_loop
decl
%
ecx
jz
empty_8042_end_loop
call
delay
in
al
,#
0x64
!
8042
status
port
test
al
,#
1
!
output
buffer
?
inb
$
0x64
,
%
al
#
8042
status
port
testb
$
1
,
%
al
#
output
buffer
?
jz
no_output
call
delay
in
al
,#
0x60
!
read
it
in
b
$
0x60
,
%
al
#
read
it
jmp
empty_8042_loop
no_output
:
test
al
,#
2
!
is
input
buffer
full
?
jnz
empty_8042_loop
!
yes
-
loop
test
b
$
2
,
%
al
#
is
input
buffer
full
?
jnz
empty_8042_loop
#
yes
-
loop
empty_8042_end_loop
:
pop
ecx
popl
%
ecx
ret
!
!
Read
the
CMOS
clock
.
Return
the
seconds
in
al
!
#
Read
the
cmos
clock
.
Return
the
seconds
in
al
gettime
:
push
cx
mov
ah
,#
0x02
int
0x1a
mov
al
,
dh
!
dh
contains
the
seconds
and
al
,#
0x0f
mov
ah
,
d
h
mov
cl
,#
0x04
shr
ah
,
cl
push
w
%
cx
mov
b
$
0x02
,
%
ah
int
$
0x1a
mov
b
%
dh
,
%
al
#
%
dh
contains
the
seconds
and
b
$
0x0f
,
%
al
mov
b
%
dh
,
%
a
h
mov
b
$
0x04
,
%
cl
shr
b
%
cl
,
%
ah
aad
pop
cx
pop
w
%
cx
ret
!
!
Delay
is
needed
after
doing
I
/
O
!
#
Delay
is
needed
after
doing
I
/
O
delay
:
.
word
0x00eb
!
jmp
$
+
2
jmp
.
+
2
#
jmp
$
+
2
ret
!
!
Descriptor
tables
!
#
Descriptor
tables
gdt
:
.
word
0
,
0
,
0
,
0
!
dummy
.
word
0
,
0
,
0
,
0
!
unused
.
word
0
xFFFF
!
4
Gb
-
(
0x100000
*
0x1000
=
4
Gb
)
.
word
0x
0000
!
base
address
=
0
.
word
0x
9A00
!
code
read
/
exec
.
word
0x00CF
!
granularity
=
4096
,
386
(+
5
th
nibble
of
limit
)
.
word
0xFFFF
!
4
Gb
-
(
0x100000
*
0x1000
=
4
Gb
)
.
word
0
x0000
!
base
address
=
0
.
word
0x9200
!
data
read
/
write
.
word
0x00CF
!
granularity
=
4096
,
386
(+
5
th
nibble
of
limit
)
.
word
0
,
0
,
0
,
0
#
dummy
.
word
0
,
0
,
0
,
0
#
unused
.
word
0xFFFF
#
4
Gb
-
(
0x100000
*
0x1000
=
4
Gb
)
.
word
0
#
base
address
=
0
.
word
0x
9A00
#
code
read
/
exec
.
word
0x
00CF
#
granularity
=
4096
,
386
#
(+
5
th
nibble
of
limit
)
.
word
0xFFFF
#
4
Gb
-
(
0x100000
*
0x1000
=
4
Gb
)
.
word
0
#
base
address
=
0
.
word
0x9200
#
data
read
/
write
.
word
0x00CF
#
granularity
=
4096
,
386
#
(+
5
th
nibble
of
limit
)
idt_48
:
.
word
0
!
idt
limit
=
0
.
word
0
,
0
!
idt
base
=
0
L
.
word
0
#
idt
limit
=
0
.
word
0
,
0
#
idt
base
=
0
L
gdt_48
:
.
word
0x800
!
gdt
limit
=
2048
,
256
GDT
entries
.
word
512
+
gdt
,
0x9
!
gdt
base
=
0X9
xxxx
.
word
0x800
0
#
gdt
limit
=
2048
,
#
256
GDT
entries
!
!
Include
video
setup
&
detection
code
!
.
word
512
+
gdt
,
0x9
#
gdt
base
=
0X9
xxxx
#
include "video.S"
#
Include
video
setup
&
detection
code
!
!
Setup
signature
--
must
be
last
!
#include "video.S"
#
Setup
signature
--
must
be
last
setup_sig1
:
.
word
SIG1
setup_sig2
:
.
word
SIG2
!
!
After
this
point
,
there
is
some
free
space
which
is
used
by
the
video
mode
!
handling
code
to
store
the
temporary
mode
table
(
not
used
by
the
kernel
)
.
!
#
After
this
point
,
there
is
some
free
space
which
is
used
by
the
video
mode
#
handling
code
to
store
the
temporary
mode
table
(
not
used
by
the
kernel
)
.
modelist
:
...
...
arch/i386/boot/tools/build.c
View file @
90ff4d27
...
...
@@ -58,27 +58,10 @@ void die(const char * str, ...)
exit
(
1
);
}
/* Reading of ld86 output (Minix format) */
#define MINIX_HEADER_LEN 32
void
minix_open
(
const
char
*
name
)
void
file_open
(
const
char
*
name
)
{
static
byte
hdr
[]
=
{
0x01
,
0x03
,
0x10
,
0x04
,
0x20
,
0x00
,
0x00
,
0x00
};
static
u32
*
lb
=
(
u32
*
)
buf
;
if
((
fd
=
open
(
name
,
O_RDONLY
,
0
))
<
0
)
die
(
"Unable to open `%s': %m"
,
name
);
if
(
read
(
fd
,
buf
,
MINIX_HEADER_LEN
)
!=
MINIX_HEADER_LEN
)
die
(
"%s: Unable to read header"
,
name
);
if
(
memcmp
(
buf
,
hdr
,
sizeof
(
hdr
))
||
lb
[
5
])
die
(
"%s: Non-Minix header"
,
name
);
if
(
lb
[
3
])
die
(
"%s: Illegal data segment"
);
if
(
lb
[
4
])
die
(
"%s: Illegal bss segment"
);
if
(
lb
[
7
])
die
(
"%s: Illegal symbol table"
);
}
void
usage
(
void
)
...
...
@@ -125,7 +108,7 @@ int main(int argc, char ** argv)
}
fprintf
(
stderr
,
"Root device is (%d, %d)
\n
"
,
major_root
,
minor_root
);
minix_open
(
argv
[
1
]);
/* Copy the boot sector */
file_open
(
argv
[
1
]);
i
=
read
(
fd
,
buf
,
sizeof
(
buf
));
fprintf
(
stderr
,
"Boot sector %d bytes.
\n
"
,
i
);
if
(
i
!=
512
)
...
...
@@ -138,7 +121,7 @@ int main(int argc, char ** argv)
die
(
"Write call failed"
);
close
(
fd
);
minix
_open
(
argv
[
2
]);
/* Copy the setup code */
file
_open
(
argv
[
2
]);
/* Copy the setup code */
for
(
i
=
0
;
(
c
=
read
(
fd
,
buf
,
sizeof
(
buf
)))
>
0
;
i
+=
c
)
if
(
write
(
1
,
buf
,
c
)
!=
c
)
die
(
"Write call failed"
);
...
...
@@ -146,8 +129,8 @@ int main(int argc, char ** argv)
die
(
"read-error on `setup'"
);
close
(
fd
);
setup_sectors
=
(
i
+
511
)
/
512
;
/* Pad unused space with zeros */
/* for compatibility with ancient versions of LILO */
setup_sectors
=
(
i
+
511
)
/
512
;
/* Pad unused space with zeros */
/* for compatibility with ancient versions of LILO
.
*/
if
(
setup_sectors
<
SETUP_SECTS
)
setup_sectors
=
SETUP_SECTS
;
fprintf
(
stderr
,
"Setup is %d bytes.
\n
"
,
i
);
...
...
@@ -161,8 +144,7 @@ int main(int argc, char ** argv)
i
+=
c
;
}
if
((
fd
=
open
(
argv
[
3
],
O_RDONLY
,
0
))
<
0
)
/* Copy the image itself */
die
(
"Unable to open `%s': %m"
,
argv
[
3
]);
file_open
(
argv
[
3
]);
if
(
fstat
(
fd
,
&
sb
))
die
(
"Unable to stat `%s': %m"
,
argv
[
3
]);
sz
=
sb
.
st_size
;
...
...
@@ -187,7 +169,7 @@ int main(int argc, char ** argv)
}
close
(
fd
);
if
(
lseek
(
1
,
497
,
SEEK_SET
)
!=
497
)
/* Write sizes to the boot
sector */
if
(
lseek
(
1
,
497
,
SEEK_SET
)
!=
497
)
/* Write sizes to the bootsector */
die
(
"Output: seek failed"
);
buf
[
0
]
=
setup_sectors
;
if
(
write
(
1
,
buf
,
1
)
!=
1
)
...
...
arch/i386/boot/video.S
View file @
90ff4d27
!
!
Display
adapter
&
video
mode
setup
,
version
2
.13
(
14
-
May
-
99
)
!
!
Copyright
(
C
)
1995
--
1999
Martin
Mares
<
mj
@
ucw
.
cz
>
!
Based
on
the
original
setup
.
S
code
(
C
)
Linus
Torvalds
and
Mats
Anderson
!
!
For
further
information
,
look
at
Documentation
/
svga
.
txt
.
!
/*
video.S
*
*
Display
adapter
&
video
mode
setup
,
version
2
.13
(
14
-
May
-
99
)
*
*
Copyright
(
C
)
1995
--
1998
Martin
Mares
<
mj
@
ucw
.
cz
>
*
Based
on
the
original
setup
.
S
code
(
C
)
Linus
Torvalds
and
Mats
Anderson
*
*
Rewritten
to
use
GNU
'as'
by
Chris
Noe
<
stiker
@
northlink
.
com
>
May
1999
*
*
For
further
information
,
look
at
Documentation
/
svga
.
txt
.
*
*/
#include <linux/config.h> /* for CONFIG_VIDEO_* */
!
Enable
autodetection
of
SVGA
adapters
and
modes
.
If
you
really
need
this
!
feature
,
drop
me
a
mail
as
I
think
of
removing
it
some
day
.
You
can
!
always
enter
`
scan
' to get the video mode table and then use the real
!
video
mode
numbers
(
those
4
-
digit
hexadecimal
numbers
,
NOT
the
menu
!
item
numbers
)
which
don
't rely on any autodetection.
/*
Enable
autodetection
of
SVGA
adapters
and
modes
.
*/
#undef CONFIG_VIDEO_SVGA
!
Enable
autodetection
of
VESA
modes
/*
Enable
autodetection
of
VESA
modes
*/
#define CONFIG_VIDEO_VESA
!
Enable
compacting
of
mode
table
/*
Enable
compacting
of
mode
table
*/
#define CONFIG_VIDEO_COMPACT
!
Retain
screen
contents
when
switching
modes
/*
Retain
screen
contents
when
switching
modes
*/
#define CONFIG_VIDEO_RETAIN
!
Enable
local
mode
list
/*
Enable
local
mode
list
*/
#undef CONFIG_VIDEO_LOCAL
!
Force
400
scan
lines
for
standard
modes
(
hack
to
fix
bad
behaviour
!
of
certain
broken
BIOSes
--
don
't use unless needed)
/*
Force
400
scan
lines
for
standard
modes
(
hack
to
fix
bad
BIOS
behaviour
*/
#undef CONFIG_VIDEO_400_HACK
!
A
special
hack
allowing
to
force
specific
BIOS
mode
ID
along
with
specific
!
dimensions
.
Especially
useful
for
certain
X
-
Window
graphics
mode
hacks
!
(
e.g
.,
800
x600
modes
on
IBM
ThinkPad
)
.
/*
Hack
that
lets
you
force
specific
BIOS
mode
ID
and
specific
dimensions
*/
#undef CONFIG_VIDEO_GFX_HACK
#define VIDEO_GFX_BIOS_AX 0x4f02 /* 800x600 on ThinkPad */
#define VIDEO_GFX_BIOS_BX 0x0102
#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425 /* 100x37 */
!
This
code
uses
an
extended
set
of
video
mode
numbers
.
These
include
:
!
Aliases
for
standard
modes
!
NORMAL_VGA
(-
1
)
!
EXTENDED_VGA
(-
2
)
!
ASK_VGA
(-
3
)
!
Video
modes
numbered
by
menu
position
--
NOT
RECOMMENDED
because
of
lack
!
of
compatibility
when
extending
the
table
.
These
are
between
0x00
and
0xff
.
/*
This
code
uses
an
extended
set
of
video
mode
numbers
.
These
include
:
*
Aliases
for
standard
modes
*
NORMAL_VGA
(-
1
)
*
EXTENDED_VGA
(-
2
)
*
ASK_VGA
(-
3
)
*
Video
modes
numbered
by
menu
position
--
NOT
RECOMMENDED
because
of
lack
*
of
compatibility
when
extending
the
table
.
These
are
between
0x00
and
0xff
.
*/
#define VIDEO_FIRST_MENU 0x0000
!
Standard
BIOS
video
modes
(
BIOS
number
+
0x0100
)
/*
Standard
BIOS
video
modes
(
BIOS
number
+
0x0100
)
*/
#define VIDEO_FIRST_BIOS 0x0100
!
VESA
BIOS
video
modes
(
VESA
number
+
0x0200
)
/*
VESA
BIOS
video
modes
(
VESA
number
+
0x0200
)
*/
#define VIDEO_FIRST_VESA 0x0200
!
Video7
special
modes
(
BIOS
number
+
0x0900
)
/*
Video7
special
modes
(
BIOS
number
+
0x0900
)
*/
#define VIDEO_FIRST_V7 0x0900
!
Special
video
modes
/*
Special
video
modes
*/
#define VIDEO_FIRST_SPECIAL 0x0f00
#define VIDEO_80x25 0x0f00
#define VIDEO_8POINT 0x0f01
...
...
@@ -66,14 +68,15 @@
#define VIDEO_80x60 0x0f07
#define VIDEO_GFX_HACK 0x0f08
#define VIDEO_LAST_SPECIAL 0x0f09
!
Video
modes
given
by
resolution
/*
Video
modes
given
by
resolution
*/
#define VIDEO_FIRST_RESOLUTION 0x1000
!
The
"recalculate timings"
flag
/*
The
"recalculate timings"
flag
*/
#define VIDEO_RECALC 0x8000
!
Positions
of
various
video
parameters
passed
to
the
kernel
!
(
see
also
include
/
linux
/
tty
.
h
)
/*
Positions
of
various
video
parameters
passed
to
the
kernel
*/
/*
(
see
also
include
/
linux
/
tty
.
h
)
*/
#define PARAM_CURSOR_POS 0x00
#define PARAM_VIDEO_PAGE 0x04
#define PARAM_VIDEO_MODE 0x06
...
...
@@ -94,530 +97,505 @@
#define PARAM_VESAPM_OFF 0x30
#define PARAM_LFB_PAGES 0x32
!
Define
DO_STORE
according
to
CONFIG_VIDEO_RETAIN
/*
Define
DO_STORE
according
to
CONFIG_VIDEO_RETAIN
*/
#ifdef CONFIG_VIDEO_RETAIN
#define DO_STORE call store_screen
#else
#define DO_STORE
#endif /* CONFIG_VIDEO_RETAIN */
!
!
This
is
the
main
entry
point
called
by
setup
.
S
!
!
Input
:
!
DS
pointing
to
the
boot
sector
video
:
push
ds
!
We
use
different
segments
push
ds
!
FS
contains
original
DS
pop
fs
push
cs
!
DS
is
equal
to
CS
pop
ds
push
cs
!
ES
is
equal
to
CS
pop
es
xor
ax
,
ax
mov
gs
,
ax
!
GS
is
zero
#
This
is
the
main
entry
point
called
by
setup
.
S
#
%
ds
*
must
*
be
pointing
to
the
bootsector
video
:
pushw
%
ds
#
We
use
different
segments
pushw
%
ds
#
FS
contains
original
DS
popw
%
fs
pushw
%
cs
#
DS
is
equal
to
CS
popw
%
ds
pushw
%
cs
#
ES
is
equal
to
CS
popw
%
es
xorw
%
ax
,
%
ax
movw
%
ax
,
%
gs
#
GS
is
zero
cld
call
basic_detect
!
Basic
adapter
type
testing
(
EGA
/
VGA
/
MDA
/
CGA
)
call
basic_detect
#
Basic
adapter
type
testing
(
EGA
/
VGA
/
MDA
/
CGA
)
#ifdef CONFIG_VIDEO_SELECT
seg
fs
!
User
-
selected
video
mode
mov
ax
,[
0x01fa
]
cmp
ax
,#
ASK_VGA
!
Bring
up
the
menu
movw
%
fs
:
(
0x01fa
),
%
ax
#
User
selected
video
mode
cmpw
$ASK_VGA
,
%
ax
#
Bring
up
the
menu
jz
vid2
call
mode_set
!
Set
the
mode
call
mode_set
#
Set
the
mode
jc
vid1
lea
si
,
badmdt
!
Invalid
mode
ID
leaw
badmdt
,
%
si
#
Invalid
mode
ID
call
prtstr
vid2
:
call
mode_menu
vid1
:
#ifdef CONFIG_VIDEO_RETAIN
call
restore_screen
!
Restore
screen
contents
call
restore_screen
#
Restore
screen
contents
#endif /* CONFIG_VIDEO_RETAIN */
#endif /* CONFIG_VIDEO_SELECT */
call
mode_params
!
Store
mode
parameters
pop
ds
!
Restore
original
DS
call
mode_params
#
Store
mode
parameters
pop
w
%
ds
#
Restore
original
DS
ret
!
!
Detect
if
we
have
CGA
,
MDA
,
EGA
or
VGA
and
pass
it
to
the
kernel
.
!
#
Detect
if
we
have
CGA
,
MDA
,
EGA
or
VGA
and
pass
it
to
the
kernel
.
basic_detect
:
seg
fs
!
Default
is
no
VGA
movb
[
PARAM_HAVE_VGA
],#
0
mov
ah
,#
0x12
!
Check
EGA
/
VGA
mov
bl
,#
0x10
int
0x10
seg
fs
mov
[
PARAM_VIDEO_EGA_BX
],
bx
!
Used
for
identification
of
EGA
in
the
kernel
cmp
bl
,#
0x10
!
No
,
this
is
a
CGA
/
MDA
/
HGA
card
.
movb
$
0
,
%
fs
:
(
PARAM_HAVE_VGA
)
movb
$
0x12
,
%
ah
#
Check
EGA
/
VGA
movb
$
0x10
,
%
bl
int
$
0x10
movw
%
bx
,
%
fs
:
(
PARAM_VIDEO_EGA_BX
)
#
Identifies
EGA
to
the
kernel
cmpb
$
0x10
,
%
bl
#
No
,
it
's a CGA/MDA/HGA card.
je
basret
incb
[
adapter
]
mov
ax
,#
0x1a00
!
Check
for
EGA
/
VGA
discrimination
int
0x10
cmp
al
,#
0x1a
!
1
a
means
VGA
,
anything
else
EGA
jne
basret
seg
fs
incb
[
PARAM_HAVE_VGA
]
!
We
've detected a VGA
incb
[
adapter
]
incb
adapter
movw
$
0x1a00
,
%
ax
#
Check
EGA
or
VGA
?
int
$
0x10
cmpb
$
0x1a
,
%
al
#
1
a
means
VGA
...
jne
basret
#
anything
else
is
EGA
.
incb
%
fs
:
(
PARAM_HAVE_VGA
)
#
We
've detected a VGA
incb
adapter
basret
:
ret
!
!
Store
the
video
mode
parameters
for
later
usage
by
the
kernel
.
!
This
is
done
by
asking
the
BIOS
except
for
the
rows
/
columns
!
parameters
in
the
default
80
x25
mode
--
these
are
set
directly
,
!
because
some
very
obscure
BIOSes
supply
insane
values
.
!
#
Store
the
video
mode
parameters
for
later
usage
by
the
kernel
.
#
This
is
done
by
asking
the
BIOS
except
for
the
rows
/
columns
#
parameters
in
the
default
80
x25
mode
--
these
are
set
directly
,
#
because
some
very
obscure
BIOSes
supply
insane
values
.
mode_params
:
#ifdef CONFIG_VIDEO_SELECT
cmpb
[
graphic_mode
],#
0
cmpb
$
0
,
graphic_mode
jnz
mopar_gr
#endif
mov
ah
,#
0x03
!
Read
cursor
position
xor
bh
,
bh
int
0x10
seg
fs
mov
[
PARAM_CURSOR_POS
],
dx
mov
ah
,#
0x0f
!
Read
page
/
mode
/
width
int
0x10
seg
fs
mov
[
PARAM_VIDEO_PAGE
],
bx
seg
fs
mov
[
PARAM_VIDEO_MODE
],
ax
!
Video
mode
and
screen
width
cmp
al
,#
7
!
MDA
/
HGA
=>
segment
differs
movb
$
0x03
,
%
ah
#
Read
cursor
position
xorb
%
bh
,
%
bh
int
$
0x10
movw
%
dx
,
%
fs
:
(
PARAM_CURSOR_POS
)
movb
$
0x0f
,
%
ah
#
Read
page
/
mode
/
width
int
$
0x10
movw
%
bx
,
%
fs
:
(
PARAM_VIDEO_PAGE
)
movw
%
ax
,
%
fs
:
(
PARAM_VIDEO_MODE
)
#
Video
mode
and
screen
width
cmpb
$
0x7
,
%
al
#
MDA
/
HGA
=>
segment
differs
jnz
mopar0
mov
[
video_segment
],#
0xb000
mopar0
:
seg
gs
!
Font
size
mov
ax
,[
0x485
]
seg
fs
mov
[
PARAM_FONT_POINTS
],
ax
!
(
valid
only
on
EGA
/
VGA
)
mov
ax
,[
force_size
]
!
Forced
size
?
or
ax
,
ax
movw
$
0xb000
,
video_segment
mopar0
:
movw
%
gs
:
(
0x485
),
%
ax
#
Font
size
movw
%
ax
,
%
fs
:
(
PARAM_FONT_POINTS
)
#
(
valid
only
on
EGA
/
VGA
)
movw
force_size
,
%
ax
#
Forced
size
?
orw
%
ax
,
%
ax
jz
mopar1
seg
fs
mov
[
PARAM_VIDEO_COLS
],
ah
seg
fs
mov
[
PARAM_VIDEO_LINES
],
al
ret
mopar1
:
mov
al
,#
25
cmpb
[
adapter
],#
0
!
If
we
are
on
CGA
/
MDA
/
HGA
,
the
screen
must
jz
mopar2
!
have
25
lines
.
seg
gs
!
On
EGA
/
VGA
,
use
the
EGA
+
BIOS
variable
mov
al
,[
0x484
]
!
containing
maximal
line
number
.
inc
al
mopar2
:
seg
fs
movb
[
PARAM_VIDEO_LINES
],
al
movb
%
ah
,
%
fs
:
(
PARAM_VIDEO_COLS
)
movb
%
al
,
%
fs
:
(
PARAM_VIDEO_LINES
)
ret
#ifdef CONFIG_VIDEO_SELECT
mopar1
:
movb
$
25
,
%
al
cmpb
$
0
,
adapter
#
If
we
are
on
CGA
/
MDA
/
HGA
,
the
jz
mopar2
#
screen
must
have
25
lines
.
!
!
Fetching
of
VESA
frame
buffer
parameters
!
movb
%
gs
:
(
0x484
),
%
al
#
On
EGA
/
VGA
,
use
the
EGA
+
BIOS
incb
%
al
#
location
of
max
lines
.
mopar2
:
movb
%
al
,
%
fs
:
(
PARAM_VIDEO_LINES
)
ret
#ifdef CONFIG_VIDEO_SELECT
#
Fetching
of
VESA
frame
buffer
parameters
mopar_gr
:
lea
di
,
modelist
+
1024
seg
fs
movb
[
PARAM_HAVE_VGA
],#
0x23
mov
ax
,(
di
+
16
)
seg
fs
mov
[
PARAM_LFB_LINELENGTH
],
ax
mov
ax
,(
di
+
18
)
seg
fs
mov
[
PARAM_LFB_WIDTH
],
ax
mov
ax
,(
di
+
20
)
seg
fs
mov
[
PARAM_LFB_HEIGHT
],
ax
mov
al
,(
di
+
25
)
mov
ah
,#
0
seg
fs
mov
[
PARAM_LFB_DEPTH
],
ax
mov
al
,(
di
+
29
)
mov
ah
,#
0
seg
fs
mov
[
PARAM_LFB_PAGES
],
ax
mov
eax
,(
di
+
40
)
seg
fs
mov
[
PARAM_LFB_BASE
],
eax
mov
eax
,(
di
+
31
)
seg
fs
mov
[
PARAM_LFB_COLORS
],
eax
mov
eax
,(
di
+
35
)
seg
fs
mov
[
PARAM_LFB_COLORS
+
4
],
eax
!
get
video
mem
size
lea
di
,
modelist
+
1024
mov
ax
,#
0x4f00
int
0x10
xor
eax
,
eax
mov
ax
,(
di
+
18
)
seg
fs
mov
[
PARAM_LFB_SIZE
],
eax
!
get
protected
mode
interface
informations
mov
ax
,#
0x4f0a
xor
bx
,
bx
xor
di
,
di
int
0x10
cmp
ax
,#
0x004f
leaw
modelist
+
1024
,
%
di
movb
$
0x23
,
%
fs
:
(
PARAM_HAVE_VGA
)
movw
16
(%
di
),
%
ax
movw
%
ax
,
%
fs
:
(
PARAM_LFB_LINELENGTH
)
movw
18
(%
di
),
%
ax
movw
%
ax
,
%
fs
:
(
PARAM_LFB_WIDTH
)
movw
20
(%
di
),
%
ax
movw
%
ax
,
%
fs
:
(
PARAM_LFB_HEIGHT
)
movb
25
(%
di
),
%
al
movb
$
0
,
%
ah
movw
%
ax
,
%
fs
:
(
PARAM_LFB_DEPTH
)
movb
29
(%
di
),
%
al
movb
$
0
,
%
ah
movw
%
ax
,
%
fs
:
(
PARAM_LFB_PAGES
)
movl
40
(%
di
),
%
eax
movl
%
eax
,
%
fs
:
(
PARAM_LFB_BASE
)
movl
31
(%
di
),
%
eax
movl
%
eax
,
%
fs
:
(
PARAM_LFB_COLORS
)
movl
35
(%
di
),
%
eax
movl
%
eax
,
%
fs
:
(
PARAM_LFB_COLORS
+
4
)
#
get
video
mem
size
leaw
modelist
+
1024
,
%
di
movw
$
0x4f00
,
%
ax
int
$
0x10
xorl
%
eax
,
%
eax
movw
18
(%
di
),
%
ax
movl
%
eax
,
%
fs
:
(
PARAM_LFB_SIZE
)
#
get
protected
mode
interface
informations
movw
$
0x4f0a
,
%
ax
xorw
%
bx
,
%
bx
xorw
%
di
,
%
di
int
$
0x10
cmp
$
0x004f
,
%
ax
jnz
no_pm
seg
fs
mov
[
PARAM_VESAPM_SEG
],
es
seg
fs
mov
[
PARAM_VESAPM_OFF
],
di
no_pm
:
ret
!
!
The
video
mode
menu
!
movw
%
es
,
%
fs
:
(
PARAM_VESAPM_SEG
)
movw
%
di
,
%
fs
:
(
PARAM_VESAPM_OFF
)
no_pm
:
ret
#
The
video
mode
menu
mode_menu
:
lea
si
,
keymsg
!
"Return/Space/Timeout"
message
lea
w
keymsg
,
%
si
#
"Return/Space/Timeout"
message
call
prtstr
call
flush
nokey
:
call
getkt
cmp
al
,#
0x0d
!
ENTER
?
je
listm
!
yes
-
manual
mode
selection
cmp
al
,#
0x20
!
SPACE
?
je
defmd1
!
no
-
repeat
cmpb
$
0x0d
,
%
al
#
ENTER
?
je
listm
#
yes
-
manual
mode
selection
cmpb
$
0x20
,
%
al
#
SPACE
?
je
defmd1
#
no
-
repeat
call
beep
jmp
nokey
defmd1
:
ret
!
No
mode
selected
=>
use
the
80
x25
default
listm
:
call
mode_table
!
We
need
a
mode
table
to
be
listed
listm0
:
lea
si
,
name_bann
!
Print
adapter
name
defmd1
:
ret
#
No
mode
chosen
?
Default
80
x25
listm
:
call
mode_table
#
List
mode
table
listm0
:
leaw
name_bann
,
%
si
#
Print
adapter
name
call
prtstr
mov
si
,[
card_name
]
or
si
,
si
mov
w
card_name
,
%
si
or
w
%
si
,
%
si
jnz
an2
mov
al
,[
adapter
]
lea
si
,
old_name
or
al
,
al
movb
adapter
,
%
al
leaw
old_name
,
%
si
orb
%
al
,
%
al
jz
an1
lea
si
,
ega_name
dec
al
leaw
ega_name
,
%
si
decb
%
al
jz
an1
lea
si
,
vga_name
leaw
vga_name
,
%
si
jmp
an1
an2
:
call
prtstr
lea
si
,
svga_name
lea
w
svga_name
,
%
si
an1
:
call
prtstr
lea
si
,
listhdr
!
Table
header
lea
w
listhdr
,
%
si
#
Table
header
call
prtstr
mov
dl
,#
0x30
!
DL
holds
mode
number
lea
si
,
modelist
lm1
:
cmp
(
si
),#
ASK_VGA
!
End
?
mov
b
$
0x30
,
%
dl
#
DL
holds
mode
number
lea
w
modelist
,
%
si
lm1
:
cmp
w
$ASK_VGA
,
(%
si
)
#
End
?
jz
lm2
mov
al
,
dl
!
Menu
selection
number
movb
%
dl
,
%
al
#
Menu
selection
number
call
prtchr
call
prtsp2
lodsw
call
prthw
!
Mode
ID
call
prthw
#
Mode
ID
call
prtsp2
mov
al
,(
si
+
1
)
call
prtdec
!
Rows
mov
al
,#
0x78
!
'x'
mov
b
0x1
(%
si
),
%
al
call
prtdec
#
Rows
mov
b
$
0x78
,
%
al
#
the
letter
'x'
call
prtchr
lodsw
call
prtdec
!
Columns
mov
al
,#
0x0d
!
New
line
call
prtdec
#
Columns
mov
b
$
0x0d
,
%
al
#
New
line
call
prtchr
mov
al
,#
0x0a
mov
b
$
0x0a
,
%
al
call
prtchr
inc
dl
!
Next
character
cmp
dl
,#
0x3a
inc
b
%
dl
#
Next
character
cmp
b
$
0x3a
,
%
dl
jnz
lm1
mov
dl
,#
0x61
movb
$
0x61
,
%
dl
jmp
lm1
lm2
:
lea
si
,
prompt
!
Mode
prompt
lm2
:
lea
w
prompt
,
%
si
#
Mode
prompt
call
prtstr
lea
di
,
edit_buf
!
Editor
buffer
lea
w
edit_buf
,
%
di
#
Editor
buffer
lm3
:
call
getkey
cmp
al
,#
0x0d
!
Enter
?
cmp
b
$
0x0d
,
%
al
#
Enter
?
jz
lment
cmp
al
,#
0x08
!
Backspace
?
cmpb
$
0x08
,
%
al
#
Backspace
?
jz
lmbs
cmp
al
,#
0x20
!
Printable
?
cmpb
$
0x20
,
%
al
#
Printable
?
jc
lm3
cmp
di
,#
edit_buf
+
4
!
Enough
space
?
cmpw
$edit_buf
+
4
,
%
di
#
Enough
space
?
jz
lm3
stosb
call
prtchr
jmp
lm3
lmbs
:
cmp
di
,#
edit_buf
!
Backspace
lmbs
:
cmp
w
$edit_buf
,
%
di
#
Backspace
jz
lm3
dec
di
mov
al
,#
0x08
decw
%
di
movb
$
0x08
,
%
al
call
prtchr
call
prtspc
mov
al
,#
0x08
mov
b
$
0x08
,
%
al
call
prtchr
jmp
lm3
lment
:
movb
(
di
),#
0
lea
si
,
crlft
lment
:
movb
$
0
,
(%
di
)
lea
w
crlft
,
%
si
call
prtstr
lea
si
,
edit_buf
cmpb
(
si
),#
0
!
Empty
string
=>
use
default
mode
lea
w
edit_buf
,
%
si
cmpb
$
0
,
(%
si
)
#
Empty
string
=
default
mode
jz
lmdef
cmpb
(
si
+
1
),#
0
!
One
character
=>
menu
selection
cmpb
$
0
,
1
(%
si
)
#
One
character
=
menu
selection
jz
mnusel
cmp
(
si
),#
0x6373
!
"scan"
=>
mode
scanning
cmpw
$
0x6373
,
(%
si
)
#
"scan"
=>
mode
scanning
jnz
lmhx
cmp
(
si
+
2
),#
0x6e61
cmpw
$
0x6e61
,
2
(%
si
)
jz
lmscan
lmhx
:
xor
bx
,
bx
!
Else
=>
mode
ID
in
hex
lmhx
:
xorw
%
bx
,
%
bx
#
Else
=>
mode
ID
in
hex
lmhex
:
lodsb
or
al
,
al
or
b
%
al
,
%
al
jz
lmuse1
sub
al
,#
0x30
subb
$
0x30
,
%
al
jc
lmbad
cmp
al
,#
10
cmpb
$
10
,
%
al
jc
lmhx1
sub
al
,#
7
and
al
,#
0xdf
cmp
al
,#
10
subb
$
7
,
%
al
andb
$
0xdf
,
%
al
cmpb
$
10
,
%
al
jc
lmbad
cmp
al
,#
16
cmpb
$
16
,
%
al
jnc
lmbad
lmhx1
:
shl
bx
,#
4
or
bl
,
al
lmhx1
:
shlw
$
4
,
%
bx
orb
%
al
,
%
bl
jmp
lmhex
lmuse1
:
mov
ax
,
bx
lmuse1
:
movw
%
bx
,
%
ax
jmp
lmuse
mnusel
:
lodsb
!
Menu
selection
xor
ah
,
ah
sub
al
,#
0x30
mnusel
:
lodsb
#
Menu
selection
xor
b
%
ah
,
%
ah
sub
b
$
0x30
,
%
al
jc
lmbad
cmp
al
,#
10
cmpb
$
10
,
%
al
jc
lmuse
cmp
al
,#
0x61
-
0x30
cmpb
$
0x61
-
0x30
,
%
al
jc
lmbad
sub
al
,#
0x61
-
0x30
-
10
cmp
al
,#
36
subb
$
0x61
-
0x30
-
10
,
%
al
cmpb
$
36
,
%
al
jnc
lmbad
lmuse
:
call
mode_set
jc
lmdef
lmbad
:
lea
si
,
unknt
call
prtstr
br
lm2
lmscan
:
cmpb
[
adapter
],#
0
!
Scanning
supported
only
on
EGA
/
VGA
lmbad
:
leaw
unknt
,
%
si
call
prtstr
jmp
lm2
lmscan
:
cmpb
$
0
,
adapter
#
Scanning
only
on
EGA
/
VGA
jz
lmbad
mov
[
mt_end
],#
0
!
Scanning
of
modes
:
done
as
new
autodetection
movb
[
scanning
],#
1
call
mode_table
br
listm0
movw
$
0
,
mt_end
#
Scanning
of
modes
is
movb
$
1
,
scanning
#
done
as
new
autodetection
.
call
mode_table
jmp
listm0
lmdef
:
ret
!
!
Additional
parts
of
mode_set
...
(
relative
jumps
,
you
know
)
!
setv7
:
!
Video7
extended
modes
#
Additional
parts
of
mode_set
...
(
relative
jumps
,
you
know
)
setv7
:
#
Video7
extended
modes
DO_STORE
sub
bh
,#
VIDEO_FIRST_V7
>>
8
mov
ax
,#
0x6f05
int
0x10
sub
b
$VIDEO_FIRST_V7
>>
8
,
%
bh
mov
w
$
0x6f05
,
%
ax
int
$
0x10
stc
ret
_setrec
:
br
setrec
!
Ugly
...
_set_80x25
:
br
set_80x25
!
!
Aliases
for
backward
compatibility
.
!
_setrec
:
jmp
setrec
#
Ugly
...
_set_80x25
:
jmp
set_80x25
#
Aliases
for
backward
compatibility
.
setalias
:
mov
ax
,#
VIDEO_80x25
inc
bx
mov
w
$VIDEO_80x25
,
%
ax
inc
w
%
bx
jz
mode_set
mov
al
,#
VIDEO_8POINT
-
VIDEO_FIRST_SPECIAL
inc
bx
jnz
setbad
!
Fall
-
through
!
!
!
Setting
of
user
mode
(
AX
=
mode
ID
)
=>
CF
=
success
!
movb
$VIDEO_8POINT
-
VIDEO_FIRST_SPECIAL
,
%
al
incw
%
bx
jnz
setbad
#
Fall
-
through
!
#
Setting
of
user
mode
(
AX
=
mode
ID
)
=>
CF
=
success
mode_set
:
mov
bx
,
a
x
cmp
ah
,#
0xff
mov
w
%
ax
,
%
b
x
cmp
b
$
0xff
,
%
ah
jz
setalias
test
ah
,#
VIDEO_RECALC
>>
8
testb
$VIDEO_RECALC
>>
8
,
%
ah
jnz
_setrec
cmp
ah
,#
VIDEO_FIRST_RESOLUTION
>>
8
cmpb
$VIDEO_FIRST_RESOLUTION
>>
8
,
%
ah
jnc
setres
cmp
ah
,#
VIDEO_FIRST_SPECIAL
>>
8
cmpb
$VIDEO_FIRST_SPECIAL
>>
8
,
%
ah
jz
setspc
cmp
ah
,#
VIDEO_FIRST_V7
>>
8
cmpb
$VIDEO_FIRST_V7
>>
8
,
%
ah
jz
setv7
cmp
ah
,#
VIDEO_FIRST_VESA
>>
8
cmpb
$VIDEO_FIRST_VESA
>>
8
,
%
ah
jnc
check_vesa
or
ah
,
ah
orb
%
ah
,
%
ah
jz
setmenu
dec
ah
decb
%
ah
jz
setbios
setbad
:
clc
movb
[
do_restore
],#
0
!
The
screen
needn
't be restored
movb
$
0
,
do_restore
#
The
screen
needn
't be restored
ret
setvesa
:
DO_STORE
sub
bh
,#
VIDEO_FIRST_VESA
>>
8
mov
ax
,#
0x4f02
!
VESA
BIOS
mode
set
call
int
0x10
cmp
ax
,#
0x004f
!
AL
=
4
f
if
implemented
,
AH
=
0
if
OK
jnz
setbad
subb
$VIDEO_FIRST_VESA
>>
8
,
%
bh
movw
$
0x4f02
,
%
ax
#
VESA
BIOS
mode
set
call
int
$
0x10
cmpw
$
0x004f
,
%
ax
#
AL
=
4
f
if
implemented
jnz
setbad
#
AH
=
0
if
OK
stc
ret
setbios
:
DO_STORE
int
0x10
!
Standard
BIOS
mode
set
call
push
bx
mov
ah
,#
0x0f
!
Check
if
really
set
int
0x10
pop
bx
cmp
al
,
b
l
int
$
0x10
#
Standard
BIOS
mode
set
call
push
w
%
bx
mov
b
$
0x0f
,
%
ah
#
Check
if
really
set
int
$
0x10
pop
w
%
bx
cmp
b
%
bl
,
%
a
l
jnz
setbad
stc
ret
setspc
:
xor
bh
,
bh
!
Set
special
mode
cmp
bl
,#
VIDEO_LAST_SPECIAL
-
VIDEO_FIRST_SPECIAL
setspc
:
xor
b
%
bh
,
%
bh
#
Set
special
mode
cmp
b
$VIDEO_LAST_SPECIAL
-
VIDEO_FIRST_SPECIAL
,
%
bl
jnc
setbad
add
bx
,
bx
.
word
0xa7ff
,
spec_inits
!
JMP
[
BX
+
spec_inits
]
addw
%
bx
,
%
bx
.
word
0xa7ff
,
spec_inits
#
JMP
[
BX
+
spec_inits
]
setmenu
:
or
al
,
al
!
80
x25
is
an
exception
or
b
%
al
,
%
al
#
80
x25
is
an
exception
jz
_set_80x25
push
bx
!
Set
mode
chosen
from
menu
call
mode_table
!
Build
the
mode
table
pop
ax
shl
ax
,#
2
add
si
,
ax
cmp
si
,
di
pushw
%
bx
#
Set
mode
chosen
from
menu
call
mode_table
#
Build
the
mode
table
popw
%
ax
shlw
$
2
,
%
ax
addw
%
ax
,
%
si
cmpw
%
di
,
%
si
jnc
setbad
mov
ax
,(
si
)
!
Fetch
mode
ID
movw
(%
si
),
%
ax
#
Fetch
mode
ID
_m_s
:
jmp
mode_set
setres
:
push
bx
!
Set
mode
chosen
by
its
resolution
setres
:
pushw
%
bx
#
Set
mode
chosen
by
resolution
call
mode_table
pop
bx
xchg
bh
,
bl
pop
w
%
bx
xchg
b
%
bl
,
%
bh
setr1
:
lodsw
cmp
ax
,#
ASK_VGA
!
End
of
the
list
?
cmp
w
$ASK_VGA
,
%
ax
#
End
of
the
list
?
jz
setbad
lodsw
cmp
ax
,
b
x
cmp
w
%
bx
,
%
a
x
jnz
setr1
mov
ax
,(
si
-
4
)
!
Fetch
mode
ID
movw
-
4
(%
si
),
%
ax
#
Fetch
mode
ID
jmp
_m_s
check_vesa
:
lea
di
,
modelist
+
1024
sub
bh
,#
VIDEO_FIRST_VESA
>>
8
mov
cx
,
bx
!
Get
mode
information
structure
mov
ax
,#
0x4f01
int
0x10
add
bh
,#
VIDEO_FIRST_VESA
>>
8
cmp
ax
,#
0x004f
lea
w
modelist
+
1024
,
%
di
sub
b
$VIDEO_FIRST_VESA
>>
8
,
%
bh
mov
w
%
bx
,
%
cx
#
Get
mode
information
structure
mov
w
$
0x4f01
,
%
ax
int
$
0x10
add
b
$VIDEO_FIRST_VESA
>>
8
,
%
bh
cmp
w
$
0x004f
,
%
ax
jnz
setbad
mov
al
,(
di
)
!
Check
capabilities
.
and
al
,#
0x19
cmp
al
,#
0x09
jz
setvesa
!
t
his
is
a
text
mode
mov
al
,(
di
)
!
Check
capabilities
.
and
al
,#
0x99
cmp
al
,#
0x99
jnz
_setbad
!
to
bad
,
no
linear
frame
buffer
sub
bh
,#
VIDEO_FIRST_VESA
>>
8
or
bx
,#
0x4000
!
want
use
linear
frame
buffer
mov
ax
,#
0x4f02
!
VESA
BIOS
mode
set
call
int
0x10
cmp
ax
,#
0x004f
!
AL
=
4
f
if
implemented
,
AH
=
0
if
OK
jnz
_setbad
movb
[
graphic_mode
],#
1
!
flag
graphic
mode
movb
[
do_restore
],#
0
!
no
screen
restore
mov
b
(%
di
),
%
al
#
Check
capabilities
.
and
b
$
0x19
,
%
al
cmp
b
$
0x09
,
%
al
jz
setvesa
#
T
his
is
a
text
mode
mov
b
(%
di
),
%
al
#
Check
capabilities
.
and
b
$
0x99
,
%
al
cmp
b
$
0x99
,
%
al
jnz
_setbad
#
Doh
!
No
linear
frame
buffer
.
sub
b
$VIDEO_FIRST_VESA
>>
8
,
%
bh
or
w
$
0x4000
,
%
bx
#
Use
linear
frame
buffer
mov
w
$
0x4f02
,
%
ax
#
VESA
BIOS
mode
set
call
int
$
0x10
cmp
w
$
0x004f
,
%
ax
#
AL
=
4
f
if
implemented
jnz
_setbad
#
AH
=
0
if
OK
movb
$
1
,
graphic_mode
#
flag
graphic
mode
movb
$
0
,
do_restore
#
no
screen
restore
stc
ret
_setbad
:
br
setbad
!
Ugly
...
!
!
Recalculate
vertical
display
end
registers
--
this
fixes
various
!
inconsistencies
of
extended
modes
on
many
adapters
.
Called
when
!
the
VIDEO_RECALC
flag
is
set
in
the
mode
ID
.
!
setrec
:
sub
ah
,#
VIDEO_RECALC
>>
8
!
Set
the
base
mode
_setbad
:
jmp
setbad
#
Ugly
...
#
Recalculate
vertical
display
end
registers
--
this
fixes
various
#
inconsistencies
of
extended
modes
on
many
adapters
.
Called
when
#
the
VIDEO_RECALC
flag
is
set
in
the
mode
ID
.
setrec
:
subb
$VIDEO_RECALC
>>
8
,
%
ah
#
Set
the
base
mode
call
mode_set
jnc
rct3
seg
gs
!
Font
size
in
pixels
mov
ax
,[
0x485
]
seg
gs
!
Number
of
rows
mov
bl
,[
0x484
]
inc
bl
mul
bl
!
Number
of
visible
dec
ax
!
scan
lines
-
1
mov
dx
,#
0x3d4
mov
bx
,
ax
mov
al
,#
0x12
!
Lower
8
bits
mov
ah
,
bl
out
dx
,
ax
mov
al
,#
0x07
!
Bits
8
and
9
in
the
overflow
register
movw
%
gs
:
(
0x485
),
%
ax
#
Font
size
in
pixels
movb
%
gs
:
(
0x484
),
%
bl
#
Number
of
rows
incb
%
bl
mulb
%
bl
#
Number
of
visible
decw
%
ax
#
scan
lines
-
1
movw
$
0x3d4
,
%
dx
movw
%
ax
,
%
bx
movb
$
0x12
,
%
al
#
Lower
8
bits
movb
%
bl
,
%
ah
outw
%
ax
,
%
dx
movb
$
0x07
,
%
al
#
Bits
8
and
9
in
the
overflow
register
call
inidx
xchg
ah
,
al
and
ah
,#
0xbd
shr
bh
,#
1
xchg
b
%
al
,
%
ah
and
b
$
0xbd
,
%
ah
shr
b
%
bh
jnc
rct1
or
ah
,#
0x02
rct1
:
shr
bh
,#
1
or
b
$
0x02
,
%
ah
rct1
:
shr
b
%
bh
jnc
rct2
or
ah
,#
0x40
rct2
:
mov
al
,#
0x07
out
dx
,
a
x
or
b
$
0x40
,
%
ah
rct2
:
mov
b
$
0x07
,
%
al
out
w
%
ax
,
%
d
x
stc
rct3
:
ret
!
!
Table
of
routines
for
setting
of
the
special
modes
.
!
#
Table
of
routines
for
setting
of
the
special
modes
.
spec_inits
:
.
word
set_80x25
.
word
set_8pixel
...
...
@@ -629,589 +607,575 @@ spec_inits:
.
word
set_80x60
.
word
set_gfx
!
!
Set
the
80
x25
mode
.
If
already
set
,
do
nothing
.
!
#
Set
the
80
x25
mode
.
If
already
set
,
do
nothing
.
set_80x25
:
mov
[
force_size
],#
0x5019
!
Override
possibly
broken
BIOS
vars
mov
w
$
0x5019
,
force_size
#
Override
possibly
broken
BIOS
use_80x25
:
#ifdef CONFIG_VIDEO_400_HACK
mov
ax
,#
0x1202
!
Force
400
scan
lines
mov
bl
,#
0x30
int
0x10
mov
w
$
0x1202
,
%
ax
#
Force
400
scan
lines
mov
b
$
0x30
,
%
bl
int
$
0x10
#else
mov
ah
,#
0x0f
!
Get
current
mode
ID
int
0x10
cmp
ax
,#
0x5007
!
Mode
7
(
80
x25
mono
)
is
the
only
one
available
jz
st80
!
on
CGA
/
MDA
/
HGA
and
is
also
available
on
EGAM
cmp
ax
,#
0x5003
!
Unknown
mode
=>
force
80
x25
color
movb
$
0x0f
,
%
ah
#
Get
current
mode
ID
int
$
0x10
cmpw
$
0x5007
,
%
ax
#
Mode
7
(
80
x25
mono
)
is
the
only
one
available
jz
st80
#
on
CGA
/
MDA
/
HGA
and
is
also
available
on
EGAM
cmpw
$
0x5003
,
%
ax
#
Unknown
mode
,
force
80
x25
color
jnz
force3
st80
:
cmpb
[
adapter
],#
0
!
CGA
/
MDA
/
HGA
=>
mode
3
/
7
is
always
80
x25
st80
:
cmpb
$
0
,
adapter
#
CGA
/
MDA
/
HGA
=>
mode
3
/
7
is
always
80
x25
jz
set80
seg
gs
!
This
is
EGA
+
--
beware
of
80
x50
etc
.
mov
al
,[
0x0484
]
or
al
,
al
!
Some
buggy
BIOS
es
set
0
rows
mov
b
%
gs
:
(
0x0484
),
%
al
#
This
is
EGA
+
--
beware
of
80
x50
etc
.
or
b
%
al
,
%
al
#
Some
buggy
BIOS
'
es set 0 rows
jz
set80
cmp
al
,#
24
!
Let
's hope this is correct
cmpb
$
24
,
%
al
#
It
's hopefully correct
jz
set80
#endif /* CONFIG_VIDEO_400_HACK */
force3
:
DO_STORE
mov
ax
,#
0x0003
!
Forced
set
int
0x10
mov
w
$
0x0003
,
%
ax
#
Forced
set
int
$
0x10
set80
:
stc
ret
!
!
Set
the
80
x50
/
80
x43
8
-
pixel
mode
.
Simple
BIOS
calls
.
!
#
Set
the
80
x50
/
80
x43
8
-
pixel
mode
.
Simple
BIOS
calls
.
set_8pixel
:
DO_STORE
call
use_80x25
!
The
base
is
80
x25
call
use_80x25
#
The
base
is
80
x25
set_8pt
:
mov
ax
,#
0x1112
!
Use
8
x8
font
xor
bl
,
bl
int
0x10
mov
ax
,#
0x1200
!
Use
alternate
print
screen
mov
bl
,#
0x20
int
0x10
mov
ax
,#
0x1201
!
Turn
off
cursor
emulation
mov
bl
,#
0x34
int
0x10
mov
ah
,#
0x01
!
Define
cursor
(
scan
lines
6
to
7
)
mov
cx
,#
0x0607
int
0x10
mov
w
$
0x1112
,
%
ax
#
Use
8
x8
font
xor
b
%
bl
,
%
bl
int
$
0x10
mov
w
$
0x1200
,
%
ax
#
Use
alternate
print
screen
mov
b
$
0x20
,
%
bl
int
$
0x10
mov
w
$
0x1201
,
%
ax
#
Turn
off
cursor
emulation
mov
b
$
0x34
,
%
bl
int
$
0x10
mov
b
$
0x01
,
%
ah
#
Define
cursor
scan
lines
6
-
7
mov
w
$
0x0607
,
%
cx
int
$
0x10
set_current
:
stc
ret
!
!
Set
the
80
x28
mode
.
This
mode
works
on
all
VGA
's, because it'
s
a
standard
!
80
x25
mode
with
14
-
point
fonts
instead
of
16
-
point
.
!
#
Set
the
80
x28
mode
.
This
mode
works
on
all
VGA
's, because it'
s
a
standard
#
80
x25
mode
with
14
-
point
fonts
instead
of
16
-
point
.
set_80x28
:
DO_STORE
call
use_80x25
!
The
base
is
80
x25
set14
:
mov
ax
,#
0x1111
!
Use
9
x14
font
xor
bl
,
bl
int
0x10
mov
ah
,#
0x01
!
Define
cursor
(
scan
lines
11
to
12
)
mov
cx
,#
0x0b0c
int
0x10
call
use_80x25
#
The
base
is
80
x25
set14
:
mov
w
$
0x1111
,
%
ax
#
Use
9
x14
font
xor
b
%
bl
,
%
bl
int
$
0x10
mov
b
$
0x01
,
%
ah
#
Define
cursor
scan
lines
11
-
12
mov
w
$
0x0b0c
,
%
cx
int
$
0x10
stc
ret
!
!
Set
the
80
x43
mode
.
This
mode
is
works
on
all
VGA
's.
!
It
'
s
a
350
-
scanline
mode
with
8
-
pixel
font
.
!
#
Set
the
80
x43
mode
.
This
mode
is
works
on
all
VGA
's.
#
It
'
s
a
350
-
scanline
mode
with
8
-
pixel
font
.
set_80x43
:
DO_STORE
mov
ax
,#
0x1201
!
Set
350
scans
mov
bl
,#
0x30
int
0x10
mov
ax
,#
0x0003
!
Reset
video
mode
int
0x10
jmp
set_8pt
!
Use
8
-
pixel
font
!
!
Set
the
80
x30
mode
(
all
VGA
's). 480 scanlines, 16-pixel font.
!
movw
$
0x1201
,
%
ax
#
Set
350
scans
movb
$
0x30
,
%
bl
int
$
0x10
movw
$
0x0003
,
%
ax
#
Reset
video
mode
int
$
0x10
jmp
set_8pt
#
Use
8
-
pixel
font
#
Set
the
80
x30
mode
(
all
VGA
's). 480 scanlines, 16-pixel font.
set_80x30
:
call
use_80x25
!
Start
with
real
80
x25
call
use_80x25
#
Start
with
real
80
x25
DO_STORE
mov
dx
,#
0x3cc
!
Get
CRTC
port
in
al
,
dx
mov
dl
,#
0xd4
ror
al
,#
1
!
Mono
or
color
?
mov
w
$
0x3cc
,
%
dx
#
Get
CRTC
port
in
b
%
dx
,
%
al
mov
b
$
0xd4
,
%
dl
ror
b
%
al
#
Mono
or
color
?
jc
set48a
mov
dl
,#
0xb4
set48a
:
mov
ax
,#
0x0c11
!
Vertical
sync
end
(
also
unlocks
CR0
-
7
)
movb
$
0xb4
,
%
dl
set48a
:
movw
$
0x0c11
,
%
ax
#
Vertical
sync
end
(
also
unlocks
CR0
-
7
)
call
outidx
mov
ax
,#
0x0b06
!
Vertical
total
mov
w
$
0x0b06
,
%
ax
#
Vertical
total
call
outidx
mov
ax
,#
0x3e07
!
(
Vertical
)
overflow
mov
w
$
0x3e07
,
%
ax
#
(
Vertical
)
overflow
call
outidx
mov
ax
,#
0xea10
!
Vertical
sync
start
mov
w
$
0xea10
,
%
ax
#
Vertical
sync
start
call
outidx
mov
ax
,#
0xdf12
!
Vertical
display
end
mov
w
$
0xdf12
,
%
ax
#
Vertical
display
end
call
outidx
mov
ax
,#
0xe715
!
Vertical
blank
start
mov
w
$
0xe715
,
%
ax
#
Vertical
blank
start
call
outidx
mov
ax
,#
0x0416
!
Vertical
blank
end
mov
w
$
0x0416
,
%
ax
#
Vertical
blank
end
call
outidx
push
dx
mov
dl
,#
0xcc
!
Misc
output
register
(
read
)
in
al
,
dx
mov
dl
,#
0xc2
!
(
write
)
and
al
,#
0x0d
!
Preserve
clock
select
bits
and
color
bit
or
al
,#
0xe2
!
Set
correct
sync
polarity
out
dx
,
al
pop
dx
mov
[
force_size
],#
0x501
e
stc
!
That
's all.
push
w
%
dx
mov
b
$
0xcc
,
%
dl
#
Misc
output
register
(
read
)
in
b
%
dx
,
%
al
mov
b
$
0xc2
,
%
dl
#
(
write
)
and
b
$
0x0d
,
%
al
#
Preserve
clock
select
bits
and
color
bit
or
b
$
0xe2
,
%
al
#
Set
correct
sync
polarity
out
b
%
al
,
%
dx
pop
w
%
dx
mov
w
$
0x501e
,
force_siz
e
stc
#
That
's all.
ret
!
!
Set
the
80
x34
mode
(
all
VGA
's). 480 scans, 14-pixel font.
!
#
Set
the
80
x34
mode
(
all
VGA
's). 480 scans, 14-pixel font.
set_80x34
:
call
set_80x30
!
Set
480
scans
call
set14
!
And
14
-
pt
font
mov
ax
,#
0xdb12
!
VGA
vertical
display
end
mov
[
force_size
],#
0x5022
call
set_80x30
#
Set
480
scans
call
set14
#
And
14
-
pt
font
mov
w
$
0xdb12
,
%
ax
#
VGA
vertical
display
end
mov
w
$
0x5022
,
force_size
setvde
:
call
outidx
stc
ret
!
!
Set
the
80
x60
mode
(
all
VGA
's). 480 scans, 8-pixel font.
!
#
Set
the
80
x60
mode
(
all
VGA
's). 480 scans, 8-pixel font.
set_80x60
:
call
set_80x30
!
Set
480
scans
call
set_8pt
!
And
8
-
pt
font
mov
ax
,#
0xdf12
!
VGA
vertical
display
end
mov
[
force_size
],#
0x503c
call
set_80x30
#
Set
480
scans
call
set_8pt
#
And
8
-
pt
font
mov
w
$
0xdf12
,
%
ax
#
VGA
vertical
display
end
mov
w
$
0x503c
,
force_size
jmp
setvde
!
!
Special
hack
for
ThinkPad
graphics
!
#
Special
hack
for
ThinkPad
graphics
set_gfx
:
#ifdef CONFIG_VIDEO_GFX_HACK
mov
ax
,#
VIDEO_GFX_BIOS_AX
mov
bx
,#
VIDEO_GFX_BIOS_BX
int
0x10
mov
[
force_size
],#
VIDEO_GFX_DUMMY_RESOLUTION
mov
w
$VIDEO_GFX_BIOS_AX
,
%
ax
mov
w
$VIDEO_GFX_BIOS_BX
,
%
bx
int
$
0x10
mov
w
$VIDEO_GFX_DUMMY_RESOLUTION
,
force_size
stc
#endif
ret
#ifdef CONFIG_VIDEO_RETAIN
!
!
Store
screen
contents
to
temporary
buffer
.
!
#
Store
screen
contents
to
temporary
buffer
.
store_screen
:
cmpb
[
do_restore
],#
0
!
Already
stored
?
cmpb
$
0
,
do_restore
#
Already
stored
?
jnz
stsr
testb
[
loadflags
],#
CAN_USE_HEAP
!
Have
we
space
for
storing
?
testb
$CAN_USE_HEAP
,
loadflags
#
Have
we
space
for
storing
?
jz
stsr
push
ax
push
bx
push
[
force_size
]
!
Don
't force specific size
mov
[
force_size
],#
0
call
mode_params
!
Obtain
params
of
current
mode
pop
[
force_size
]
seg
fs
mov
ah
,[
PARAM_VIDEO_LINES
]
seg
fs
mov
al
,[
PARAM_VIDEO_COLS
]
mov
bx
,
ax
!
BX
=
dimensions
mul
ah
mov
cx
,
ax
!
CX
=
number
of
characters
to
store
add
ax
,
ax
!
Calculate
image
size
add
ax
,#
modelist
+
1024
+
4
cmp
ax
,[
heap_end_ptr
]
jnc
sts1
!
Unfortunately
,
out
of
memory
seg
fs
!
Store
mode
params
mov
ax
,[
PARAM_CURSOR_POS
]
lea
di
,
modelist
+
1024
pushw
%
ax
pushw
%
bx
pushw
force_size
#
Don
't force specific size
movw
$
0
,
force_size
call
mode_params
#
Obtain
params
of
current
mode
popw
force_size
movb
%
fs
:
(
PARAM_VIDEO_LINES
),
%
ah
movb
%
fs
:
(
PARAM_VIDEO_COLS
),
%
al
movw
%
ax
,
%
bx
#
BX
=
dimensions
mulb
%
ah
movw
%
ax
,
%
cx
#
CX
=
number
of
characters
addw
%
ax
,
%
ax
#
Calculate
image
size
addw
$modelist
+
1024
+
4
,
%
ax
cmpw
heap_end_ptr
,
%
ax
jnc
sts1
#
Unfortunately
,
out
of
memory
movw
%
fs
:
(
PARAM_CURSOR_POS
),
%
ax
#
Store
mode
params
leaw
modelist
+
1024
,
%
di
stosw
mov
ax
,
b
x
mov
w
%
bx
,
%
a
x
stosw
push
ds
!
Store
the
screen
mov
ds
,[
video_segment
]
xor
si
,
si
pushw
%
ds
#
Store
the
screen
movw
video_segment
,
%
ds
xorw
%
si
,
%
si
rep
movsw
pop
ds
incb
[
do_restore
]
!
Screen
will
be
restored
later
sts1
:
pop
bx
pop
ax
pop
w
%
ds
incb
do_restore
#
Screen
will
be
restored
later
sts1
:
pop
w
%
bx
pop
w
%
ax
stsr
:
ret
!
!
Restore
screen
contents
from
temporary
buffer
.
!
#
Restore
screen
contents
from
temporary
buffer
.
restore_screen
:
cmpb
[
do_restore
],#
0
!
Has
the
screen
been
stored
?
cmpb
$
0
,
do_restore
#
Has
the
screen
been
stored
?
jz
res1
call
mode_params
!
Get
parameters
of
current
mode
seg
fs
mov
cl
,[
PARAM_VIDEO_LINES
]
seg
fs
mov
ch
,[
PARAM_VIDEO_COLS
]
lea
si
,
modelist
+
1024
!
Screen
buffer
lodsw
!
Set
cursor
position
mov
dx
,
ax
cmp
dh
,
cl
call
mode_params
#
Get
parameters
of
current
mode
movb
%
fs
:
(
PARAM_VIDEO_LINES
),
%
cl
movb
%
fs
:
(
PARAM_VIDEO_COLS
),
%
ch
leaw
modelist
+
1024
,
%
si
#
Screen
buffer
lodsw
#
Set
cursor
position
movw
%
ax
,
%
dx
cmpb
%
cl
,
%
dh
jc
res2
mov
dh
,
cl
dec
dh
res2
:
cmp
dl
,
ch
movb
%
cl
,
%
dh
decb
%
dh
res2
:
cmpb
%
ch
,
%
dl
jc
res3
mov
dl
,
ch
dec
dl
res3
:
mov
ah
,#
0x02
mov
bh
,#
0x00
int
0x10
lodsw
!
Display
size
mov
dl
,
ah
!
DL
=
number
of
lines
mov
ah
,#
0
!
BX
=
physical
length
of
orig
.
line
mov
bx
,
ax
cmp
dl
,
cl
!
Too
many
?
movb
%
ch
,
%
dl
decb
%
dl
res3
:
movb
$
0x02
,
%
ah
movb
$
0x00
,
%
bh
int
$
0x10
lodsw
#
Display
size
movb
%
ah
,
%
dl
#
DL
=
number
of
lines
movb
$
0
,
%
ah
#
BX
=
phys
.
length
of
orig
.
line
movw
%
ax
,
%
bx
cmpb
%
cl
,
%
dl
#
Too
many
?
jc
res4
push
ax
mov
al
,
dl
sub
al
,
cl
mul
bl
add
si
,
ax
add
si
,
ax
pop
ax
mov
dl
,
cl
res4
:
cmp
al
,
ch
!
Too
wide
?
pushw
%
ax
movb
%
dl
,
%
al
subb
%
cl
,
%
al
mulb
%
bl
addw
%
ax
,
%
si
addw
%
ax
,
%
si
popw
%
ax
movb
%
cl
,
%
dl
res4
:
cmpb
%
ch
,
%
al
#
Too
wide
?
jc
res5
mov
al
,
ch
!
AX
=
width
of
src
.
line
res5
:
mov
cl
,#
0
xchg
cl
,
ch
mov
bp
,
cx
!
BP
=
width
of
dest
.
line
push
es
mov
es
,[
video_segment
]
xor
di
,
di
!
Move
the
data
add
bx
,
bx
!
Convert
BX
and
BP
to
_bytes_
add
bp
,
bp
res6
:
push
si
push
di
mov
cx
,
ax
movb
%
ch
,
%
al
#
AX
=
width
of
src
.
line
res5
:
movb
$
0
,
%
cl
xchgb
%
ch
,
%
cl
movw
%
cx
,
%
bp
#
BP
=
width
of
dest
.
line
pushw
%
es
movw
video_segment
,
%
es
xorw
%
di
,
%
di
#
Move
the
data
addw
%
bx
,
%
bx
#
Convert
BX
and
BP
to
_bytes_
addw
%
bp
,
%
bp
res6
:
pushw
%
si
pushw
%
di
movw
%
ax
,
%
cx
rep
movsw
pop
di
pop
si
add
di
,
bp
add
si
,
bx
dec
dl
pop
w
%
di
pop
w
%
si
add
w
%
bp
,
%
di
add
w
%
bx
,
%
si
dec
b
%
dl
jnz
res6
pop
es
!
Done
popw
%
es
#
Done
res1
:
ret
#endif /* CONFIG_VIDEO_RETAIN */
!
!
Write
to
indexed
VGA
register
(
AL
=
index
,
AH
=
data
,
DX
=
index
reg
.
port
)
!
outidx
:
out
dx
,
al
push
ax
mov
al
,
ah
inc
dx
out
dx
,
al
dec
dx
pop
ax
#
Write
to
indexed
VGA
register
(
AL
=
index
,
AH
=
data
,
DX
=
index
reg
.
port
)
outidx
:
outb
%
al
,
%
dx
pushw
%
ax
movb
%
ah
,
%
al
incw
%
dx
outb
%
al
,
%
dx
decw
%
dx
popw
%
ax
ret
!
!
Build
the
table
of
video
modes
(
stored
after
the
setup
.
S
code
at
the
!
`
modelist
'
label
.
Each
video
mode
record
looks
like
:
!
.
word
MODE
-
ID
(
our
special
mode
ID
(
see
above
))
!
.
byte
rows
(
number
of
rows
)
!
.
byte
columns
(
number
of
columns
)
!
Returns
address
of
the
end
of
the
table
in
DI
,
the
end
is
marked
!
with
a
ASK_VGA
ID
.
!
#
Build
the
table
of
video
modes
(
stored
after
the
setup
.
S
code
at
the
#
`
modelist
'
label
.
Each
video
mode
record
looks
like
:
#
.
word
MODE
-
ID
(
our
special
mode
ID
(
see
above
))
#
.
byte
rows
(
number
of
rows
)
#
.
byte
columns
(
number
of
columns
)
#
Returns
address
of
the
end
of
the
table
in
DI
,
the
end
is
marked
#
with
a
ASK_VGA
ID
.
mode_table
:
mov
di
,[
mt_end
]
!
Already
filled
?
or
di
,
di
mov
w
mt_end
,
%
di
#
Already
filled
?
or
w
%
di
,
%
di
jnz
mtab1x
lea
di
,
modelist
!
Store
standard
modes
:
mov
eax
,#
VIDEO_80x25
+
0x50190000
!
The
80
x25
mode
(
ALL
)
stos
d
mov
al
,[
adapter
]
!
CGA
/
MDA
/
HGA
--
no
more
modes
or
al
,
al
leaw
modelist
,
%
di
#
Store
standard
modes
:
mov
l
$VIDEO_80x25
+
0x50190000
,
%
eax
#
The
80
x25
mode
(
ALL
)
stos
l
mov
b
adapter
,
%
al
#
CGA
/
MDA
/
HGA
--
no
more
modes
or
b
%
al
,
%
al
jz
mtabe
dec
al
decb
%
al
jnz
mtabv
mov
eax
,#
VIDEO_8POINT
+
0x502b0000
!
The
80
x43
EGA
mode
stosd
movl
$VIDEO_8POINT
+
0x502b0000
,
%
eax
#
The
80
x43
EGA
mode
stosl
jmp
mtabe
mtab1x
:
jmp
mtab1
mtabv
:
lea
si
,
vga_modes
!
All
modes
for
std
VGA
mov
cx
,#
vga_modes_end
-
vga_modes
rep
!
I
'm unable to use movsw as I don'
t
know
how
to
store
a
half
movsb
!
of
the
expression
above
to
cx
without
using
explicit
shr
.
mtabv
:
lea
w
vga_modes
,
%
si
#
All
modes
for
std
VGA
mov
w
$vga_modes_end
-
vga_modes
,
%
cx
rep
#
I
'm unable to use movsw as I don'
t
know
how
to
store
a
half
movsb
#
of
the
expression
above
to
cx
without
using
explicit
shr
.
cmpb
[
scanning
],#
0
!
Mode
scan
requested
?
cmpb
$
0
,
scanning
#
Mode
scan
requested
?
jz
mscan1
call
mode_scan
mscan1
:
#ifdef CONFIG_VIDEO_LOCAL
call
local_modes
#endif /* CONFIG_VIDEO_LOCAL */
#ifdef CONFIG_VIDEO_VESA
call
vesa_modes
!
Detect
VESA
VGA
modes
call
vesa_modes
#
Detect
VESA
VGA
modes
#endif /* CONFIG_VIDEO_VESA */
#ifdef CONFIG_VIDEO_SVGA
cmpb
[
scanning
],#
0
!
Bypass
when
scanning
cmpb
$
0
,
scanning
#
Bypass
when
scanning
jnz
mscan2
call
svga_modes
!
Detect
SVGA
cards
&
modes
call
svga_modes
#
Detect
SVGA
cards
&
modes
mscan2
:
#endif /* CONFIG_VIDEO_SVGA */
mtabe
:
#ifdef CONFIG_VIDEO_COMPACT
lea
si
,
modelist
!
Compact
video
mode
list
if
requested
.
mov
dx
,
di
mov
di
,
s
i
cmt1
:
cmp
si
,
dx
!
Scan
all
modes
lea
w
modelist
,
%
si
mov
w
%
di
,
%
dx
mov
w
%
si
,
%
d
i
cmt1
:
cmp
w
%
dx
,
%
si
#
Scan
all
modes
jz
cmt2
lea
bx
,
modelist
!
Find
in
previous
entries
mov
cx
,(
si
+
2
)
cmt3
:
cmp
si
,
bx
leaw
modelist
,
%
bx
#
Find
in
previous
entries
movw
2
(%
si
),
%
cx
cmt3
:
cmpw
%
bx
,
%
si
jz
cmt4
cmp
cx
,(
bx
+
2
)
!
Found
=>
don
't copy this entry
cmpw
2
(%
bx
),
%
cx
#
Found
=>
don
't copy this entry
jz
cmt5
add
bx
,#
4
addw
$
4
,
%
bx
jmp
cmt3
cmt4
:
movs
d
!
Copy
entry
cmt4
:
movs
l
#
Copy
entry
jmp
cmt1
cmt5
:
add
si
,#
4
!
Skip
entry
cmt5
:
add
w
$
4
,
%
si
#
Skip
entry
jmp
cmt1
cmt2
:
#endif /* CONFIG_VIDEO_COMPACT */
mov
(
di
),#
ASK_VGA
!
End
marker
mov
[
mt_end
],
di
mtab1
:
lea
si
,
modelist
!
Returning
:
SI
=
mode
list
,
DI
=
list
end
mov
w
$ASK_VGA
,
(%
di
)
#
End
marker
mov
w
%
di
,
mt_end
mtab1
:
lea
w
modelist
,
%
si
#
SI
=
mode
list
,
DI
=
list
end
ret0
:
ret
!
Modes
usable
on
all
standard
VGAs
#
Modes
usable
on
all
standard
VGAs
vga_modes
:
.
word
VIDEO_8POINT
.
word
0x5032
!
80
x50
.
word
0x5032
#
80
x50
.
word
VIDEO_80x43
.
word
0x502b
!
80
x43
.
word
0x502b
#
80
x43
.
word
VIDEO_80x28
.
word
0x501c
!
80
x28
.
word
0x501c
#
80
x28
.
word
VIDEO_80x30
.
word
0x501e
!
80
x30
.
word
0x501e
#
80
x30
.
word
VIDEO_80x34
.
word
0x5022
!
80
x34
.
word
0x5022
#
80
x34
.
word
VIDEO_80x60
.
word
0x503c
!
80
x60
.
word
0x503c
#
80
x60
#ifdef CONFIG_VIDEO_GFX_HACK
.
word
VIDEO_GFX_HACK
.
word
VIDEO_GFX_DUMMY_RESOLUTION
#endif
vga_modes_end
:
!
!
Detect
VESA
modes
.
!
vga_modes_end
:
#
Detect
VESA
modes
.
#ifdef CONFIG_VIDEO_VESA
vesa_modes
:
cmpb
[
adapter
],#
2
!
VGA
only
cmpb
$
2
,
adapter
#
VGA
only
jnz
ret0
mov
bp
,
di
!
BP
=
original
mode
table
end
add
di
,#
0x200
!
Buffer
space
mov
ax
,#
0x4f00
!
VESA
Get
card
info
call
int
#
0x10
mov
di
,
bp
cmp
ax
,#
0x004f
!
Successful
?
movw
%
di
,
%
bp
#
BP
=
original
mode
table
end
addw
$
0x200
,
%
di
#
Buffer
space
movw
$
0x4f00
,
%
ax
#
VESA
Get
card
info
call
int
$
0x10
movw
%
bp
,
%
di
cmpw
$
0x004f
,
%
ax
#
Successful
?
jnz
ret0
cmp
(
di
+
0x200
),#
0x4556
cmpw
$
0x4556
,
0x200
(%
di
)
jnz
ret0
cmp
(
di
+
0x202
),#
0x4153
cmpw
$
0x4153
,
0x202
(%
di
)
jnz
ret0
mov
[
card_name
],#
vesa_name
!
Set
name
to
"VESA VGA"
push
gs
lgs
si
,(
di
+
0x20e
)
!
GS
:
SI
=
mode
list
mov
cx
,#
128
!
Iteration
limit
vesa1
:
seg
gs
!
Get
next
mode
in
the
list
lodsw
cmp
ax
,#
0xffff
!
End
of
the
table
?
movw
$vesa_name
,
card_name
#
Set
name
to
"VESA VGA"
pushw
%
gs
lgsw
0x20e
(%
di
),
%
si
#
GS
:
SI
=
mode
list
movw
$
128
,
%
cx
#
Iteration
limit
vesa1
:
#
gas
version
2
.9.1
,
using
BFD
version
2
.9.1.0.23
buggers
the
next
inst
.
#
XXX
:
lodsw
%
gs
:
(%
si
),
%
ax
#
Get
next
mode
in
the
list
.
byte
0x66
,
0x65
,
0xAD
cmpw
$
0xffff
,
%
ax
#
End
of
the
table
?
jz
vesar
cmp
ax
,#
0x0080
!
Check
validity
of
mode
ID
cmpw
$
0x0080
,
%
ax
#
Check
validity
of
mode
ID
jc
vesa2
or
ah
,
ah
!
Valid
IDs
are
0x0000
-
0x007f
and
0x0100
-
0x07ff
jz
vesan
!
[
Certain
BIOSes
erroneously
report
0x80
-
0xff
]
cmp
ax
,#
0x0800
orb
%
ah
,
%
ah
#
Valid
IDs
:
0x0000
-
0x007f
/
0x0100
-
0x07ff
jz
vesan
#
Certain
BIOSes
report
0x80
-
0xff
!
cmpw
$
0x0800
,
%
ax
jnc
vesae
vesa2
:
push
cx
mov
cx
,
ax
!
Get
mode
information
structure
mov
ax
,#
0x4f01
int
0x10
mov
bx
,
cx
!
BX
=
mode
number
add
bh
,#
VIDEO_FIRST_VESA
>>
8
pop
cx
cmp
ax
,#
0x004f
jnz
vesan
!
Don
't report errors (buggy BIOSES :-[ )
mov
al
,(
di
)
!
Check
capabilities
.
We
require
and
al
,#
0x19
!
a
color
text
mode
.
cmp
al
,#
0x09
vesa2
:
pushw
%
cx
movw
%
ax
,
%
cx
#
Get
mode
information
structure
movw
$
0x4f01
,
%
ax
int
$
0x10
movw
%
cx
,
%
bx
#
BX
=
mode
number
addb
$VIDEO_FIRST_VESA
>>
8
,
%
bh
popw
%
cx
cmpw
$
0x004f
,
%
ax
jnz
vesan
#
Don
't report errors (buggy BIOSES)
movb
(%
di
),
%
al
#
Check
capabilities
.
We
require
andb
$
0x19
,
%
al
#
a
color
text
mode
.
cmpb
$
0x09
,
%
al
jnz
vesan
cmp
(
di
+
8
),#
0xb800
!
Standard
video
memory
address
required
cmpw
$
0xb800
,
8
(%
di
)
#
Standard
video
memory
address
required
jnz
vesan
testb
(
di
),#
2
!
Mode
characteristics
supplied
?
mov
(
di
),
bx
!
Store
mode
number
testb
$
2
,
(%
di
)
#
Mode
characteristics
supplied
?
movw
%
bx
,
(%
di
)
#
Store
mode
number
jz
vesa3
xor
dx
,
dx
mov
bx
,(
di
+
0x12
)
!
Width
or
bh
,
bh
xorw
%
dx
,
%
dx
movw
0x12
(%
di
),
%
bx
#
Width
orb
%
bh
,
%
bh
jnz
vesan
mov
(
di
+
3
),
bl
mov
ax
,(
di
+
0x14
)
!
Height
or
ah
,
ah
movb
%
bl
,
0x3
(%
di
)
movw
0x14
(%
di
),
%
ax
#
Height
orb
%
ah
,
%
ah
jnz
vesan
mov
(
di
+
2
),
al
mul
bl
cmp
ax
,#
8193
!
Small
enough
for
Linux
console
driver
?
movb
%
al
,
2
(%
di
)
mulb
%
bl
cmpw
$
8193
,
%
ax
#
Small
enough
for
Linux
console
driver
?
jnc
vesan
jmp
vesaok
vesa3
:
sub
bx
,#
0x8108
!
This
mode
has
no
detailed
info
specified
,
jc
vesan
!
so
it
must
be
a
standard
VESA
mode
.
cmp
bx
,#
5
vesa3
:
subw
$
0x8108
,
%
bx
#
This
mode
has
no
detailed
info
specified
,
jc
vesan
#
so
it
must
be
a
standard
VESA
mode
.
cmpw
$
5
,
%
bx
jnc
vesan
mov
ax
,(
bx
+
vesa_text_mode_table
)
mov
(
di
+
2
),
ax
vesaok
:
add
di
,#
4
!
The
mode
is
valid
.
Store
it
.
vesan
:
loop
vesa1
!
Next
mode
.
Limit
exceeded
=>
error
vesae
:
lea
si
,
vesaer
movw
vesa_text_mode_table
(%
bx
),
%
ax
movw
%
ax
,
2
(%
di
)
vesaok
:
addw
$
4
,
%
di
#
The
mode
is
valid
.
Store
it
.
vesan
:
loop
vesa1
#
Next
mode
.
Limit
exceeded
=>
error
vesae
:
leaw
vesaer
,
%
si
call
prtstr
mov
di
,
bp
!
Discard
already
found
modes
.
vesar
:
pop
gs
mov
w
%
bp
,
%
di
#
Discard
already
found
modes
.
vesar
:
pop
w
%
gs
ret
!
!
Dimensions
of
standard
VESA
text
modes
!
#
Dimensions
of
standard
VESA
text
modes
vesa_text_mode_table
:
db
60
,
80
!
0108
db
25
,
132
!
0109
db
43
,
132
!
010
A
db
50
,
132
!
010
B
db
60
,
132
!
010
C
.
byte
60
,
80
#
0108
.
byte
25
,
132
#
0109
.
byte
43
,
132
#
010
A
.
byte
50
,
132
#
010
B
.
byte
60
,
132
#
010
C
#endif /* CONFIG_VIDEO_VESA */
!
!
Scan
for
video
modes
.
A
bit
dirty
,
but
should
work
.
!
#
Scan
for
video
modes
.
A
bit
dirty
,
but
should
work
.
mode_scan
:
mov
cx
,#
0x0100
!
Start
with
mode
0
scm1
:
mov
ah
,#
0
!
Test
the
mode
mov
al
,
cl
int
0x10
mov
ah
,#
0x0f
int
0x10
cmp
al
,
cl
jnz
scm2
!
Mode
not
set
mov
dx
,#
0x3c0
!
Test
if
it
's a text mode
mov
al
,#
0x10
!
Mode
bits
movw
$
0x0100
,
%
cx
#
Start
with
mode
0
scm1
:
movb
$
0
,
%
ah
#
Test
the
mode
movb
%
cl
,
%
al
int
$
0x10
movb
$
0x0f
,
%
ah
int
$
0x10
cmpb
%
cl
,
%
al
jnz
scm2
#
Mode
not
set
movw
$
0x3c0
,
%
dx
#
Test
if
it
's a text mode
movb
$
0x10
,
%
al
#
Mode
bits
call
inidx
and
al
,#
0x03
and
b
$
0x03
,
%
al
jnz
scm2
mov
dl
,#
0xce
!
Another
set
of
mode
bits
mov
al
,#
0x06
movb
$
0xce
,
%
dl
#
Another
set
of
mode
bits
movb
$
0x06
,
%
al
call
inidx
shr
al
,#
1
shr
b
%
al
jc
scm2
mov
dl
,#
0xd4
!
Cursor
location
mov
al
,#
0x0f
movb
$
0xd4
,
%
dl
#
Cursor
location
movb
$
0x0f
,
%
al
call
inidx
or
al
,
al
or
b
%
al
,
%
al
jnz
scm2
mov
ax
,
cx
!
OK
,
store
the
mode
movw
%
cx
,
%
ax
#
Ok
,
store
the
mode
stosw
seg
gs
!
Number
of
rows
mov
al
,[
0x484
]
inc
al
movb
%
gs
:
(
0x484
),
%
al
#
Number
of
rows
incb
%
al
stosb
seg
gs
!
Number
of
columns
mov
ax
,[
0x44a
]
movw
%
gs
:
(
0x44a
),
%
ax
#
Number
of
columns
stosb
scm2
:
inc
cl
scm2
:
inc
b
%
cl
jns
scm1
mov
ax
,#
0x0003
!
Return
back
to
mode
3
int
0x10
movw
$
0x0003
,
%
ax
#
Return
back
to
mode
3
int
$
0x10
ret
tstidx
:
out
dx
,
ax
!
OUT
DX
,
AX
and
inidx
inidx
:
out
dx
,
al
!
Read
from
indexed
VGA
register
inc
dx
!
AL
=
index
,
DX
=
index
reg
port
->
AL
=
data
in
al
,
dx
dec
dx
tstidx
:
out
w
%
ax
,
%
dx
#
OUT
DX
,
AX
and
inidx
inidx
:
out
b
%
al
,
%
dx
#
Read
from
indexed
VGA
register
inc
w
%
dx
#
AL
=
index
,
DX
=
index
reg
port
->
AL
=
data
in
b
%
dx
,
%
al
dec
w
%
dx
ret
!
!
Try
to
detect
type
of
SVGA
card
and
supply
(
usually
approximate
)
video
!
mode
table
for
it
.
!
#
Try
to
detect
type
of
SVGA
card
and
supply
(
usually
approximate
)
video
#
mode
table
for
it
.
#ifdef CONFIG_VIDEO_SVGA
svga_modes
:
lea
si
,
svga_table
!
Test
all
known
SVGA
adapters
lea
w
svga_table
,
%
si
#
Test
all
known
SVGA
adapters
dosvga
:
lodsw
mov
bp
,
ax
!
Default
mode
table
or
ax
,
ax
mov
w
%
ax
,
%
bp
#
Default
mode
table
or
w
%
ax
,
%
ax
jz
didsv1
lodsw
!
Pointer
to
test
routine
push
si
push
di
push
es
mov
bx
,#
0xc000
mov
es
,
bx
call
ax
!
Call
test
routine
pop
es
pop
di
pop
si
or
bp
,
bp
lodsw
#
Pointer
to
test
routine
pushw
%
si
pushw
%
di
pushw
%
es
movw
$
0xc000
,
%
bx
movw
%
bx
,
%
es
call
ax
#
Call
test
routine
popw
%
es
popw
%
di
popw
%
si
orw
%
bp
,
%
bp
jz
dosvga
mov
si
,
bp
!
Found
,
copy
the
modes
mov
ah
,[
svga_prefix
]
movw
%
bp
,
%
si
#
Found
,
copy
the
modes
movb
svga_prefix
,
%
ah
cpsvga
:
lodsb
or
al
,
al
or
b
%
al
,
%
al
jz
didsv
stosw
movsw
jmp
cpsvga
didsv
:
mov
[
card_name
],
si
!
Store
pointer
to
card
name
didsv
:
mov
w
%
si
,
card_name
#
Store
pointer
to
card
name
didsv1
:
ret
!
!
Table
of
all
known
SVGA
cards
.
For
each
card
,
we
store
a
pointer
to
!
a
table
of
video
modes
supported
by
the
card
and
a
pointer
to
a
routine
!
used
for
testing
of
presence
of
the
card
.
The
video
mode
table
is
always
!
followed
by
the
name
of
the
card
or
the
chipset
.
!
#
Table
of
all
known
SVGA
cards
.
For
each
card
,
we
store
a
pointer
to
#
a
table
of
video
modes
supported
by
the
card
and
a
pointer
to
a
routine
#
used
for
testing
of
presence
of
the
card
.
The
video
mode
table
is
always
#
followed
by
the
name
of
the
card
or
the
chipset
.
svga_table
:
.
word
ati_md
,
ati_test
.
word
oak_md
,
oak_test
...
...
@@ -1230,88 +1194,91 @@ svga_table:
.
word
tseng_md
,
tseng_test
.
word
0
!
!
Test
routines
and
mode
tables
:
!
!
S3
-
The
test
algorithm
was
taken
from
the
SuperProbe
package
!
for
XFree86
1
.2.1.
Report
bugs
to
Christoph
.
Niemann
@
linux
.
org
#
Test
routines
and
mode
tables
:
#
S3
-
The
test
algorithm
was
taken
from
the
SuperProbe
package
#
for
XFree86
1
.2.1.
Report
bugs
to
Christoph
.
Niemann
@
linux
.
org
s3_test
:
mov
cx
,#
0x0f35
!
we
store
some
constants
in
cl
/
ch
mov
dx
,#
0x03d4
movb
al
,#
0x38
mov
w
$
0x0f35
,
%
cx
#
we
store
some
constants
in
cl
/
ch
mov
w
$
0x03d4
,
%
dx
movb
$
0x38
,
%
al
call
inidx
mov
bh
,
al
!
store
current
value
of
CRT
-
register
0x38
mov
ax
,#
0x0038
call
outidx
!
disable
writing
to
special
regs
movb
al
,
cl
!
check
whether
we
can
write
special
reg
0x35
mov
b
%
al
,
%
bh
#
store
current
CRT
-
register
0x38
mov
w
$
0x0038
,
%
ax
call
outidx
#
disable
writing
to
special
regs
movb
%
cl
,
%
al
#
check
whether
we
can
write
special
reg
0x35
call
inidx
movb
bl
,
al
!
save
the
current
value
of
CRT
reg
0x35
andb
al
,#
0xf0
!
clear
bits
0
-
3
movb
ah
,
al
movb
al
,
cl
!
and
write
it
to
CRT
reg
0x35
movb
%
al
,
%
bl
#
save
the
current
value
of
CRT
reg
0x35
andb
$
0xf0
,
%
al
#
clear
bits
0
-
3
movb
%
al
,
%
ah
movb
%
cl
,
%
al
#
and
write
it
to
CRT
reg
0x35
call
outidx
call
inidx
!
now
read
it
back
andb
al
,
ch
!
clear
the
upper
4
bits
jz
s3_2
!
the
first
test
failed
.
But
we
have
a
movb
ah
,
bl
!
second
chance
mov
al
,
cl
call
inidx
#
now
read
it
back
andb
%
ch
,
%
al
#
clear
the
upper
4
bits
jz
s3_2
#
the
first
test
failed
.
But
we
have
a
movb
%
bl
,
%
ah
#
second
chance
movb
%
cl
,
%
al
call
outidx
jmp
s3_1
!
do
the
other
tests
s3_2
:
mov
ax
,
cx
!
load
ah
with
0xf
and
al
with
0x35
orb
ah
,
bl
!
set
the
upper
4
bits
of
ah
with
the
orig
value
call
outidx
!
write
...
call
inidx
!
...
and
reread
andb
al
,
cl
!
turn
off
the
upper
4
bits
push
ax
movb
ah
,
bl
!
restore
old
value
in
register
0x35
movb
al
,
cl
jmp
s3_1
#
do
the
other
tests
s3_2
:
movw
%
cx
,
%
ax
#
load
ah
with
0xf
and
al
with
0x35
orb
%
bl
,
%
ah
#
set
the
upper
4
bits
of
ah
with
the
orig
value
call
outidx
#
write
...
call
inidx
#
...
and
reread
andb
%
cl
,
%
al
#
turn
off
the
upper
4
bits
pushw
%
ax
movb
%
bl
,
%
ah
#
restore
old
value
in
register
0x35
movb
%
cl
,
%
al
call
outidx
pop
ax
cmp
al
,
ch
!
setting
lower
4
bits
was
successful
=>
bad
je
no_s3
!
writing
is
allowed
=>
this
is
not
an
S3
s3_1
:
mov
ax
,#
0x4838
!
allow
writing
to
special
regs
by
putting
call
outidx
!
magic
number
into
CRT
-
register
0x38
movb
al
,
cl
!
check
whether
we
can
write
special
reg
0x35
popw
%
ax
cmpb
%
ch
,
%
al
#
setting
lower
4
bits
was
successful
=>
bad
je
no_s3
#
writing
is
allowed
=>
this
is
not
an
S3
s3_1
:
movw
$
0x4838
,
%
ax
#
allow
writing
to
special
regs
by
putting
call
outidx
#
magic
number
into
CRT
-
register
0x38
movb
%
cl
,
%
al
#
check
whether
we
can
write
special
reg
0x35
call
inidx
movb
bl
,
a
l
andb
al
,#
0xf0
movb
ah
,
al
movb
al
,
c
l
movb
%
al
,
%
b
l
andb
$
0xf0
,
%
al
movb
%
al
,
%
ah
movb
%
cl
,
%
a
l
call
outidx
call
inidx
andb
al
,
ch
jnz
no_s3
!
no
,
we
can
't write => no S3
mov
ax
,
cx
orb
ah
,
bl
andb
%
ch
,
%
al
jnz
no_s3
#
no
,
we
can
't write => no S3
movw
%
cx
,
%
ax
orb
%
bl
,
%
ah
call
outidx
call
inidx
andb
al
,
ch
push
ax
movb
ah
,
bl
!
restore
old
value
in
register
0x35
movb
al
,
c
l
andb
%
ch
,
%
al
push
w
%
ax
movb
%
bl
,
%
ah
#
restore
old
value
in
register
0x35
movb
%
cl
,
%
a
l
call
outidx
pop
ax
cmp
al
,
ch
jne
no_s31
!
writing
not
possible
=>
no
S3
movb
al
,#
0x30
call
inidx
!
now
get
the
S3
id
...
lea
di
,
idS3
mov
cx
,#
0x10
pop
w
%
ax
cmp
b
%
ch
,
%
al
jne
no_s31
#
writing
not
possible
=>
no
S3
movb
$
0x30
,
%
al
call
inidx
#
now
get
the
S3
id
...
lea
w
idS3
,
%
di
mov
w
$
0x10
,
%
cx
repne
scasb
je
no_s31
movb
ah
,
bh
movb
al
,#
0x38
movb
%
bh
,
%
ah
movb
$
0x38
,
%
al
jmp
s3rest
no_s3
:
movb
al
,#
0x35
!
restore
CRT
register
0x35
movb
ah
,
bl
no_s3
:
movb
$
0x35
,
%
al
#
restore
CRT
register
0x35
movb
%
bl
,
%
ah
call
outidx
no_s31
:
xorw
%
bp
,
%
bp
#
Detection
failed
s3rest
:
movb
%
bh
,
%
ah
movb
$
0x38
,
%
al
#
restore
old
value
of
CRT
register
0x38
call
outidx
no_s31
:
xor
bp
,
bp
!
Detection
failed
s3rest
:
movb
ah
,
bh
movb
al
,#
0x38
!
restore
old
value
of
CRT
register
0x38
br
outidx
idS3
:
.
byte
0x81
,
0x82
,
0x90
,
0x91
,
0x92
,
0x93
,
0x94
,
0x95
.
byte
0xa0
,
0xa1
,
0xa2
,
0xa3
,
0xa4
,
0xa5
,
0xa8
,
0xb0
...
...
@@ -1322,16 +1289,16 @@ s3_md: .byte 0x54, 0x2b, 0x84
.
ascii
"S3"
.
byte
0
!
ATI
cards
.
#
ATI
cards
.
ati_test
:
lea
si
,
idat
i
mov
di
,#
0x31
mov
cx
,#
0x09
lea
w
idati
,
%
s
i
mov
w
$
0x31
,
%
di
mov
w
$
0x09
,
%
cx
repe
cmpsb
je
atiok
xor
bp
,
bp
xorw
%
bp
,
%
bp
atiok
:
ret
idati
:
.
ascii
"761295520"
...
...
@@ -1346,19 +1313,20 @@ ati_md: .byte 0x23, 0x19, 0x84
.
ascii
"ATI"
.
byte
0
!
AHEAD
#
AHEAD
ahead_test
:
mov
ax
,#
0x200f
mov
dx
,#
0x3ce
out
dx
,
a
x
inc
dx
in
al
,
dx
cmp
al
,#
0x20
mov
w
$
0x200f
,
%
ax
mov
w
$
0x3ce
,
%
dx
out
w
%
ax
,
%
d
x
inc
w
%
dx
in
b
%
dx
,
%
al
cmp
b
$
0x20
,
%
al
je
isahed
cmp
al
,#
0x21
cmpb
$
0x21
,
%
al
je
isahed
xor
bp
,
bp
xorw
%
bp
,
%
bp
isahed
:
ret
ahead_md
:
...
...
@@ -1372,23 +1340,23 @@ ahead_md:
.
ascii
"Ahead"
.
byte
0
!
Chips
&
Tech
.
#
Chips
&
Tech
.
chips_test
:
mov
dx
,#
0x3c3
in
al
,
dx
or
al
,#
0x10
out
dx
,
al
mov
dx
,#
0x104
in
al
,
dx
mov
bl
,
a
l
mov
dx
,#
0x3c3
in
al
,
dx
and
al
,#
0xef
out
dx
,
al
cmp
bl
,#
0xa5
mov
w
$
0x3c3
,
%
dx
in
b
%
dx
,
%
al
or
b
$
0x10
,
%
al
out
b
%
al
,
%
dx
mov
w
$
0x104
,
%
dx
in
b
%
dx
,
%
al
mov
b
%
al
,
%
b
l
mov
w
$
0x3c3
,
%
dx
in
b
%
dx
,
%
al
and
b
$
0xef
,
%
al
out
b
%
al
,
%
dx
cmp
b
$
0xa5
,
%
bl
je
cantok
xor
bp
,
bp
xorw
%
bp
,
%
bp
cantok
:
ret
chips_md
:
...
...
@@ -1398,50 +1366,51 @@ chips_md:
.
ascii
"Chips & Technologies"
.
byte
0
!
Cirrus
Logic
5
X0
#
Cirrus
Logic
5
X0
cirrus1_test
:
mov
dx
,#
0x3d4
mov
al
,#
0x0c
out
dx
,
al
inc
dx
in
al
,
dx
mov
bl
,
a
l
xor
al
,
al
out
dx
,
al
dec
dx
mov
al
,#
0x1f
out
dx
,
al
inc
dx
in
al
,
dx
mov
bh
,
al
xor
ah
,
ah
shl
al
,#
4
mov
cx
,
a
x
mov
al
,
bh
shr
al
,#
4
add
cx
,
a
x
shl
cx
,#
8
add
cx
,#
6
mov
ax
,
c
x
mov
dx
,#
0x3c4
out
dx
,
a
x
inc
dx
in
al
,
dx
and
al
,
al
mov
w
$
0x3d4
,
%
dx
mov
b
$
0x0c
,
%
al
out
b
%
al
,
%
dx
inc
w
%
dx
in
b
%
dx
,
%
al
mov
b
%
al
,
%
b
l
xor
b
%
al
,
%
al
out
b
%
al
,
%
dx
dec
w
%
dx
mov
b
$
0x1f
,
%
al
out
b
%
al
,
%
dx
inc
w
%
dx
in
b
%
dx
,
%
al
mov
b
%
al
,
%
bh
xor
b
%
ah
,
%
ah
shl
b
$
4
,
%
al
mov
w
%
ax
,
%
c
x
mov
b
%
bh
,
%
al
shr
b
$
4
,
%
al
add
w
%
ax
,
%
c
x
shl
w
$
8
,
%
cx
add
w
$
6
,
%
cx
mov
w
%
cx
,
%
a
x
mov
w
$
0x3c4
,
%
dx
out
w
%
ax
,
%
d
x
inc
w
%
dx
in
b
%
dx
,
%
al
and
b
%
al
,
%
al
jnz
nocirr
mov
al
,
bh
out
dx
,
al
in
al
,
dx
cmp
al
,#
0x01
movb
%
bh
,
%
al
outb
%
al
,
%
dx
inb
%
dx
,
%
al
cmpb
$
0x01
,
%
al
je
iscirr
nocirr
:
xor
bp
,
bp
iscirr
:
mov
dx
,#
0x3d4
mov
al
,
bl
xor
ah
,
ah
shl
ax
,#
8
add
ax
,#
0x0c
out
dx
,
ax
nocirr
:
xorw
%
bp
,
%
bp
iscirr
:
movw
$
0x3d4
,
%
dx
movb
%
bl
,
%
al
xorb
%
ah
,
%
ah
shlw
$
8
,
%
ax
addw
$
0x0c
,
%
ax
outw
%
ax
,
%
dx
ret
cirrus1_md
:
...
...
@@ -1453,46 +1422,49 @@ cirrus1_md:
.
ascii
"Cirrus Logic 5X0"
.
byte
0
!
Cirrus
Logic
54
XX
#
Cirrus
Logic
54
XX
cirrus5_test
:
mov
dx
,#
0x3c4
mov
al
,#
6
mov
w
$
0x3c4
,
%
dx
mov
b
$
6
,
%
al
call
inidx
mov
bl
,
al
!
BL
=
backup
mov
ax
,#
6
mov
b
%
al
,
%
bl
#
BL
=
backup
mov
w
$
6
,
%
ax
call
tstidx
cmp
al
,#
0x0f
cmp
b
$
0x0f
,
%
al
jne
c5fail
mov
ax
,#
0x1206
movw
$
0x1206
,
%
ax
call
tstidx
cmp
al
,#
0x12
cmp
b
$
0x12
,
%
al
jne
c5fail
mov
al
,#
0x1e
movb
$
0x1e
,
%
al
call
inidx
mov
bh
,
al
mov
ah
,
b
h
and
ah
,#
0xc0
mov
al
,#
0x1e
mov
b
%
al
,
%
bh
mov
b
%
bh
,
%
a
h
and
b
$
0xc0
,
%
ah
mov
b
$
0x1e
,
%
al
call
tstidx
and
al
,#
0x3f
and
b
$
0x3f
,
%
al
jne
c5xx
mov
al
,#
0x1e
mov
ah
,
bh
or
ah
,#
0x3f
movb
$
0x1e
,
%
al
movb
%
bh
,
%
ah
orb
$
0x3f
,
%
ah
call
tstidx
xor
al
,#
0x3f
and
al
,#
0x3f
xor
b
$
0x3f
,
%
al
and
b
$
0x3f
,
%
al
c5xx
:
pushf
mov
al
,#
0x1e
mov
ah
,
b
h
out
dx
,
a
x
mov
b
$
0x1e
,
%
al
mov
b
%
bh
,
%
a
h
out
w
%
ax
,
%
d
x
popf
je
c5done
c5fail
:
xor
bp
,
bp
c5done
:
mov
al
,#
6
mov
ah
,
bl
out
dx
,
ax
c5fail
:
xorw
%
bp
,
%
bp
c5done
:
movb
$
6
,
%
al
movb
%
bl
,
%
ah
outw
%
ax
,
%
dx
ret
cirrus5_md
:
...
...
@@ -1502,37 +1474,42 @@ cirrus5_md:
.
ascii
"Cirrus Logic 54XX"
.
byte
0
!
Cirrus
Logic
64
XX
--
no
known
extra
modes
,
but
must
be
identified
,
because
!
it
'
s
misidentified
by
the
Ahead
test
.
#
Cirrus
Logic
64
XX
--
no
known
extra
modes
,
but
must
be
identified
,
because
#
it
'
s
misidentified
by
the
Ahead
test
.
cirrus6_test
:
mov
dx
,#
0x3ce
mov
al
,#
0x0a
mov
w
$
0x3ce
,
%
dx
mov
b
$
0x0a
,
%
al
call
inidx
mov
bl
,
al
!
BL
=
backup
mov
ax
,#
0xce0a
mov
b
%
al
,
%
bl
#
BL
=
backup
mov
w
$
0xce0a
,
%
ax
call
tstidx
or
al
,
al
or
b
%
al
,
%
al
jne
c2fail
mov
ax
,#
0xec0a
movw
$
0xec0a
,
%
ax
call
tstidx
cmp
al
,#
0x01
cmp
b
$
0x01
,
%
al
jne
c2fail
mov
al
,#
0xaa
call
inidx
!
4
X
,
5
X
,
7
X
and
8
X
are
valid
64
XX
chip
IDs
shr
al
,#
4
sub
al
,#
4
movb
$
0xaa
,
%
al
call
inidx
#
4
X
,
5
X
,
7
X
and
8
X
are
valid
64
XX
chip
ID
's.
shrb
$
4
,
%
al
subb
$
4
,
%
al
jz
c6done
dec
al
decb
%
al
jz
c6done
sub
al
,#
2
subb
$
2
,
%
al
jz
c6done
dec
al
decb
%
al
jz
c6done
c2fail
:
xor
bp
,
bp
c6done
:
mov
al
,#
0x0a
mov
ah
,
bl
out
dx
,
ax
c2fail
:
xorw
%
bp
,
%
bp
c6done
:
movb
$
0x0a
,
%
al
movb
%
bl
,
%
ah
outw
%
ax
,
%
dx
ret
cirrus6_md
:
...
...
@@ -1540,23 +1517,25 @@ cirrus6_md:
.
ascii
"Cirrus Logic 64XX"
.
byte
0
!
Everex
/
Trident
#
Everex
/
Trident
everex_test
:
mov
ax
,#
0x7000
xor
bx
,
bx
int
0x10
cmp
al
,#
0x70
mov
w
$
0x7000
,
%
ax
xor
w
%
bx
,
%
bx
int
$
0x10
cmp
b
$
0x70
,
%
al
jne
noevrx
shr
dx
,#
4
cmp
dx
,#
0x678
shrw
$
4
,
%
dx
cmpw
$
0x678
,
%
dx
je
evtrid
cmp
dx
,#
0x236
cmpw
$
0x236
,
%
dx
jne
evrxok
evtrid
:
lea
bp
,
trident_md
evtrid
:
leaw
trident_md
,
%
bp
evrxok
:
ret
noevrx
:
xor
bp
,
bp
noevrx
:
xor
w
%
bp
,
%
bp
ret
everex_md
:
...
...
@@ -1574,28 +1553,27 @@ everex_md:
.
ascii
"Everex/Trident"
.
byte
0
!
Genoa
.
#
Genoa
.
genoa_test
:
lea
si
,
idgenoa
!
Check
Genoa
'clues'
xor
ax
,
ax
seg
es
mov
al
,[
0x37
]
mov
di
,
ax
mov
cx
,#
0x04
dec
si
dec
di
l1
:
inc
si
inc
di
mov
al
,(
si
)
test
al
,
al
leaw
idgenoa
,
%
si
#
Check
Genoa
'clues'
xorw
%
ax
,
%
ax
movb
%
es
:
(
0x37
),
%
al
movw
%
ax
,
%
di
movw
$
0x04
,
%
cx
decw
%
si
decw
%
di
l1
:
incw
%
si
incw
%
di
movb
(%
si
),
%
al
testb
%
al
,
%
al
jz
l2
seg
es
cmp
al
,(
di
)
cmp
b
%
es
:
(%
di
),
%
al
l2
:
loope
l1
or
cx
,
cx
or
w
%
cx
,
%
cx
je
isgen
xor
bp
,
bp
xorw
%
bp
,
%
bp
isgen
:
ret
idgenoa
:
.
byte
0x77
,
0x00
,
0x99
,
0x66
...
...
@@ -1616,16 +1594,16 @@ genoa_md:
.
ascii
"Genoa"
.
byte
0
!
OAK
#
OAK
oak_test
:
lea
si
,
idoakvga
mov
di
,#
0x08
mov
cx
,#
0x08
lea
w
idoakvga
,
%
si
mov
w
$
0x08
,
%
di
mov
w
$
0x08
,
%
cx
repe
cmpsb
je
isoak
xor
bp
,
bp
xorw
%
bp
,
%
bp
isoak
:
ret
idoakvga
:
.
ascii
"OAK VGA "
...
...
@@ -1638,16 +1616,16 @@ oak_md: .byte 0x4e, 0x3c, 0x50
.
ascii
"OAK"
.
byte
0
!
WD
Paradise
.
#
WD
Paradise
.
paradise_test
:
lea
si
,
idparadise
mov
di
,#
0x7d
mov
cx
,#
0x04
lea
w
idparadise
,
%
si
mov
w
$
0x7d
,
%
di
mov
w
$
0x04
,
%
cx
repe
cmpsb
je
ispara
xor
bp
,
bp
xorw
%
bp
,
%
bp
ispara
:
ret
idparadise
:
.
ascii
"VGA="
...
...
@@ -1661,30 +1639,32 @@ paradise_md:
.
ascii
"Paradise"
.
byte
0
!
Trident
.
#
Trident
.
trident_test
:
mov
dx
,#
0x3c4
mov
al
,#
0x0e
out
dx
,
al
inc
dx
in
al
,
dx
xchg
ah
,
al
xor
al
,
al
out
dx
,
al
in
al
,
dx
xchg
al
,
ah
mov
bl
,
al
!
Strange
thing
...
in
the
book
this
wasn
't
and
bl
,#
0x02
!
necessary
but
it
worked
on
my
card
which
jz
setb2
!
is
a
trident
.
Without
it
the
screen
goes
and
al
,#
0xfd
!
blurred
...
jmp
clrb2
!
setb2
:
or
al
,#
0x02
!
clrb2
:
out
dx
,
al
and
ah
,#
0x0f
cmp
ah
,#
0x02
movw
$
0x3c4
,
%
dx
movb
$
0x0e
,
%
al
outb
%
al
,
%
dx
incw
%
dx
inb
%
dx
,
%
al
xchgb
%
al
,
%
ah
xorb
%
al
,
%
al
outb
%
al
,
%
dx
inb
%
dx
,
%
al
xchgb
%
ah
,
%
al
movb
%
al
,
%
bl
#
Strange
thing
...
in
the
book
this
wasn
't
andb
$
0x02
,
%
bl
#
necessary
but
it
worked
on
my
card
which
jz
setb2
#
is
a
trident
.
Without
it
the
screen
goes
#
blurred
...
andb
$
0xfd
,
%
al
jmp
clrb2
setb2
:
orb
$
0x02
,
%
al
clrb2
:
outb
%
al
,
%
dx
andb
$
0x0f
,
%
ah
cmpb
$
0x02
,
%
ah
je
istrid
xor
bp
,
bp
xorw
%
bp
,
%
bp
istrid
:
ret
trident_md
:
...
...
@@ -1699,21 +1679,21 @@ trident_md:
.
ascii
"Trident"
.
byte
0
!
Tseng
.
#
Tseng
.
tseng_test
:
mov
dx
,#
0x3cd
in
al
,
dx
!
Could
things
be
this
simple
?
:
-)
mov
bl
,
a
l
mov
al
,#
0x55
out
dx
,
al
in
al
,
dx
mov
ah
,
al
mov
al
,
b
l
out
dx
,
al
cmp
ah
,#
0x55
mov
w
$
0x3cd
,
%
dx
in
b
%
dx
,
%
al
#
Could
things
be
this
simple
!
:
-)
mov
b
%
al
,
%
b
l
mov
b
$
0x55
,
%
al
out
b
%
al
,
%
dx
in
b
%
dx
,
%
al
mov
b
%
al
,
%
ah
mov
b
%
bl
,
%
a
l
out
b
%
al
,
%
dx
cmp
b
$
0x55
,
%
ah
je
istsen
isnot
:
xor
bp
,
bp
isnot
:
xorw
%
bp
,
%
bp
istsen
:
ret
tseng_md
:
...
...
@@ -1727,40 +1707,41 @@ tseng_md:
.
ascii
"Tseng"
.
byte
0
!
Video7
.
#
Video7
.
video7_test
:
mov
dx
,#
0x3cc
in
al
,
dx
mov
dx
,#
0x3b4
and
al
,#
0x01
mov
w
$
0x3cc
,
%
dx
in
b
%
dx
,
%
al
mov
w
$
0x3b4
,
%
dx
and
b
$
0x01
,
%
al
jz
even7
mov
dx
,#
0x3d4
even7
:
mov
al
,#
0x0c
out
dx
,
al
inc
dx
in
al
,
dx
mov
bl
,
al
mov
al
,#
0x55
out
dx
,
al
in
al
,
dx
dec
dx
mov
al
,#
0x1f
out
dx
,
al
inc
dx
in
al
,
dx
mov
bh
,
al
dec
dx
mov
al
,#
0x0c
out
dx
,
al
inc
dx
mov
al
,
bl
out
dx
,
al
mov
al
,#
0x55
xor
al
,#
0xea
cmp
al
,
bh
movw
$
0x3d4
,
%
dx
even7
:
movb
$
0x0c
,
%
al
outb
%
al
,
%
dx
incw
%
dx
inb
%
dx
,
%
al
movb
%
al
,
%
bl
movb
$
0x55
,
%
al
outb
%
al
,
%
dx
inb
%
dx
,
%
al
decw
%
dx
movb
$
0x1f
,
%
al
outb
%
al
,
%
dx
incw
%
dx
inb
%
dx
,
%
al
movb
%
al
,
%
bh
decw
%
dx
movb
$
0x0c
,
%
al
outb
%
al
,
%
dx
incw
%
dx
movb
%
bl
,
%
al
outb
%
al
,
%
dx
movb
$
0x55
,
%
al
xorb
$
0xea
,
%
al
cmpb
%
bh
,
%
al
jne
isnot
movb
[
svga_prefix
],#
VIDEO_FIRST_V7
>>
8
!
Use
special
mode
switching
movb
$VIDEO_FIRST_V7
>>
8
,
$svga_prefix
#
Use
special
mode
switching
ret
video7_md
:
...
...
@@ -1774,16 +1755,16 @@ video7_md:
.
ascii
"Video 7"
.
byte
0
!
Realtek
VGA
#
Realtek
VGA
realtek_test
:
lea
si
,
idrtvga
mov
di
,#
0x45
mov
cx
,#
0x0b
lea
w
idrtvga
,
%
si
mov
w
$
0x45
,
%
di
mov
w
$
0x0b
,
%
cx
repe
cmpsb
je
isrt
xor
bp
,
bp
xorw
%
bp
,
%
bp
isrt
:
ret
idrtvga
:
.
ascii
"REALTEK VGA"
...
...
@@ -1800,170 +1781,154 @@ realtek_md:
#endif /* CONFIG_VIDEO_SVGA */
!
!
User
-
defined
local
mode
table
(
VGA
only
)
!
#
User
-
defined
local
mode
table
(
VGA
only
)
#ifdef CONFIG_VIDEO_LOCAL
local_modes
:
lea
si
,
local_mode_table
lea
w
local_mode_table
,
%
si
locm1
:
lodsw
or
ax
,
ax
or
w
%
ax
,
%
ax
jz
locm2
stosw
movsw
jmp
locm1
locm2
:
ret
!
This
is
the
table
of
local
video
modes
which
can
be
supplied
manually
!
by
the
user
.
Each
entry
consists
of
mode
ID
(
word
)
and
dimensions
!
(
byte
for
column
count
and
another
byte
for
row
count
)
.
These
modes
!
are
placed
before
all
SVGA
and
VESA
modes
and
override
them
if
table
!
compacting
is
enabled
.
The
table
must
end
with
a
zero
word
followed
!
by
NUL
-
terminated
video
adapter
name
.
locm2
:
ret
#
This
is
the
table
of
local
video
modes
which
can
be
supplied
manually
#
by
the
user
.
Each
entry
consists
of
mode
ID
(
word
)
and
dimensions
#
(
byte
for
column
count
and
another
byte
for
row
count
)
.
These
modes
#
are
placed
before
all
SVGA
and
VESA
modes
and
override
them
if
table
#
compacting
is
enabled
.
The
table
must
end
with
a
zero
word
followed
#
by
NUL
-
terminated
video
adapter
name
.
local_mode_table
:
.
word
0x0100
!
Example
:
40
x25
.
word
0x0100
#
Example
:
40
x25
.
byte
25
,
40
.
word
0
.
ascii
"Local"
.
byte
0
#endif /* CONFIG_VIDEO_LOCAL */
!
!
Read
a
key
and
return
the
ASCII
code
in
al
,
scan
code
in
ah
!
getkey
:
xor
ah
,
ah
int
0x16
#
Read
a
key
and
return
the
ASCII
code
in
al
,
scan
code
in
ah
getkey
:
xorb
%
ah
,
%
ah
int
$
0x16
ret
!
!
Read
a
key
with
a
timeout
of
30
seconds
.
The
hardware
clock
is
used
to
get
!
the
time
.
!
#
Read
a
key
with
a
timeout
of
30
seconds
.
#
The
hardware
clock
is
used
to
get
the
time
.
getkt
:
call
gettime
add
al
,#
30
!
Wait
30
seconds
cmp
al
,#
60
add
b
$
30
,
%
al
#
Wait
30
seconds
cmp
b
$
60
,
%
al
jl
lminute
sub
al
,#
60
subb
$
60
,
%
al
lminute
:
mov
cl
,
al
again
:
mov
ah
,#
0x01
int
0x16
jnz
getkey
!
key
pressed
,
so
get
it
movb
%
al
,
%
cl
again
:
movb
$
0x01
,
%
ah
int
$
0x16
jnz
getkey
#
key
pressed
,
so
get
it
call
gettime
cmp
al
,
c
l
cmp
b
%
cl
,
%
a
l
jne
again
mov
al
,#
0x20
!
timeout
,
return
default
char
`
space
'
ret
!
!
Flush
the
keyboard
buffer
!
movb
$
0x20
,
%
al
#
timeout
,
return
`
space
'
ret
flush
:
mov
ah
,#
0x01
int
0x16
#
Flush
the
keyboard
buffer
flush
:
movb
$
0x01
,
%
ah
int
$
0x16
jz
empty
xor
ah
,
ah
int
0x16
xorb
%
ah
,
%
ah
int
$
0x16
jmp
flush
empty
:
ret
!
!
Print
hexadecimal
number
.
!
empty
:
ret
prthw
:
push
ax
mov
al
,
ah
#
Print
hexadecimal
number
.
prthw
:
pushw
%
ax
movb
%
ah
,
%
al
call
prthb
pop
ax
prthb
:
push
ax
shr
al
,#
4
pop
w
%
ax
prthb
:
push
w
%
ax
shr
b
$
4
,
%
al
call
prthn
pop
ax
and
al
,#
0x0f
prthn
:
cmp
al
,#
0x0a
pop
w
%
ax
and
b
$
0x0f
,
%
al
prthn
:
cmp
b
$
0x0a
,
%
al
jc
prth1
add
al
,#
0x07
prth1
:
add
al
,#
0x30
br
prtchr
!
!
Print
decimal
number
(
AL
)
.
!
prtdec
:
push
ax
push
cx
xor
ah
,
ah
!
Clear
ah
mov
cl
,#
0x0a
idiv
cl
cmp
al
,#
0x09
addb
$
0x07
,
%
al
prth1
:
addb
$
0x30
,
%
al
jmp
prtchr
#
Print
decimal
number
in
al
prtdec
:
pushw
%
ax
pushw
%
cx
xorb
%
ah
,
%
ah
movb
$
0x0a
,
%
cl
idivb
%
cl
cmpb
$
0x09
,
%
al
jbe
lt100
call
prtdec
jmp
skip10
lt100
:
add
al
,#
0x30
lt100
:
addb
$
0x30
,
%
al
call
prtchr
skip10
:
mov
al
,
ah
add
al
,#
0x30
skip10
:
mov
b
%
ah
,
%
al
add
b
$
0x30
,
%
al
call
prtchr
pop
cx
pop
ax
pop
w
%
cx
pop
w
%
ax
ret
!
!
VIDEO_SELECT
-
only
variables
!
mt_end
:
.
word
0
!
End
of
video
mode
table
if
built
edit_buf
:
.
space
6
!
Line
editor
buffer
card_name
:
.
word
0
!
Pointer
to
adapter
name
scanning
:
.
byte
0
!
Performing
mode
scan
do_restore
:
.
byte
0
!
Screen
contents
altered
during
mode
change
svga_prefix
:
.
byte
VIDEO_FIRST_BIOS
>>
8
!
Default
prefix
for
BIOS
modes
graphic_mode
:
.
byte
0
!
Graphic
mode
with
a
linear
frame
buffer
!
!
Messages
:
!
#
VIDEO_SELECT
-
only
variables
mt_end
:
.
word
0
#
End
of
video
mode
table
if
built
edit_buf
:
.
space
6
#
Line
editor
buffer
card_name
:
.
word
0
#
Pointer
to
adapter
name
scanning
:
.
byte
0
#
Performing
mode
scan
do_restore
:
.
byte
0
#
Screen
contents
altered
during
mode
change
svga_prefix
:
.
byte
VIDEO_FIRST_BIOS
>>
8
#
Default
prefix
for
BIOS
modes
graphic_mode
:
.
byte
0
#
Graphic
mode
with
a
linear
frame
buffer
#
Status
messages
keymsg
:
.
ascii
"Press <RETURN> to see video modes available, "
.
ascii
"<SPACE> to continue or wait 30 secs"
db
0x0d
,
0x0a
,
0
listhdr
:
db
0x0d
,
0x0a
.
byte
0x0d
,
0x0a
,
0
listhdr
:
.
byte
0x0d
,
0x0a
.
ascii
"Mode: COLSxROWS:"
crlft
:
db
0x0d
,
0x0a
,
0
prompt
:
db
0x0d
,
0x0a
.
ascii
"Enter mode number or `scan': "
db
0
unknt
:
.
ascii
"Unknown mode ID. Try again."
db
0
crlft
:
.
byte
0x0d
,
0x0a
,
0
prompt
:
.
byte
0x0d
,
0x0a
.
asciz
"Enter mode number or `scan': "
unknt
:
.
asciz
"Unknown mode ID. Try again."
badmdt
:
.
ascii
"You passed an undefined mode number."
db
0x0d
,
0x0a
,
0
.
byte
0x0d
,
0x0a
,
0
vesaer
:
.
ascii
"Error: Scanning of VESA modes failed. Please "
.
ascii
"report to <mj@ucw.cz>."
db
0x0d
,
0x0a
,
0
old_name
:
.
ascii
"CGA/MDA/HGA"
db
0
ega_name
:
.
ascii
"EGA"
db
0
.
byte
0x0d
,
0x0a
,
0
old_name
:
.
asciz
"CGA/MDA/HGA"
ega_name
:
.
asciz
"EGA"
svga_name
:
.
ascii
" "
vga_name
:
.
ascii
"VGA"
db
0
vesa_name
:
.
ascii
"VESA"
db
0
name_bann
:
.
ascii
"Video adapter: "
db
0
#endif /* CONFIG_VIDEO_SELECT */
vga_name
:
.
asciz
"VGA"
vesa_name
:
.
asciz
"VESA"
!
!
Other
variables
:
!
name_bann
:
.
asciz
"Video adapter: "
#endif /* CONFIG_VIDEO_SELECT */
adapter
:
.
byte
0
!
Video
adapter
:
0
=
CGA
/
MDA
/
HGA
,
1
=
EGA
,
2
=
VGA
video_segment
:
.
word
0xb800
!
Video
memory
segment
force_size
:
.
word
0
!
Use
this
size
instead
of
the
one
in
BIOS
vars
#
Other
variables
:
adapter
:
.
byte
0
#
Video
adapter
:
0
=
CGA
/
MDA
/
HGA
,
1
=
EGA
,
2
=
VGA
video_segment
:
.
word
0xb800
#
Video
memory
segment
force_size
:
.
word
0
#
Use
this
size
instead
of
the
one
in
BIOS
vars
arch/i386/defconfig
View file @
90ff4d27
...
...
@@ -242,6 +242,52 @@ CONFIG_DUMMY=m
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_EISA=y
# CONFIG_PCNET32 is not set
# CONFIG_ACENIC is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
# CONFIG_DE4X5 is not set
# CONFIG_DEC_ELCP is not set
# CONFIG_DGRS is not set
CONFIG_EEXPRESS_PRO100=y
# CONFIG_NE2K_PCI is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
#
# Token Ring driver support
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
#
# PCMCIA network devices
#
CONFIG_PCMCIA_PCNET=y
# CONFIG_PCMCIA_3C589 is not set
CONFIG_PCMCIA_RAYCS=y
CONFIG_PCMCIA_NETCARD=y
#
# Amateur Radio support
...
...
drivers/char/qpmouse.c
View file @
90ff4d27
...
...
@@ -42,7 +42,7 @@
#include <asm/system.h>
#include <asm/semaphore.h>
#include
"pc_keyb.h"
/* mouse enable command.. */
#include
<linux/pc_keyb.h>
/* mouse enable command.. */
/*
...
...
@@ -134,7 +134,7 @@ static void qp_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
}
queue
->
head
=
head
;
if
(
queue
->
fasync
)
kill_fasync
(
queue
->
fasync
,
SIGIO
);
kill_fasync
(
queue
->
fasync
,
SIGIO
,
POLL_IN
);
wake_up_interruptible
(
&
queue
->
proc_list
);
}
...
...
drivers/net/Config.in
View file @
90ff4d27
...
...
@@ -130,9 +130,9 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
bool ' EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA
if [ "$CONFIG_NET_EISA" = "y" ]; then
tristate ' AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
#
tristate ' Adaptec Starfire support (EXPERIMENTAL)' CONFIG_ADAPTEC_STARFIRE
fi
#
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
#
tristate ' Adaptec Starfire support (EXPERIMENTAL)' CONFIG_ADAPTEC_STARFIRE
#
fi
tristate ' Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC
if [ "$CONFIG_ACENIC" != "n" ]; then
bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I
...
...
drivers/scsi/imm.c
View file @
90ff4d27
...
...
@@ -166,16 +166,9 @@ int imm_detect(Scsi_Host_Template * host)
*/
imm_hosts
[
i
].
mode
=
IMM_NIBBLE
;
if
(
modes
&
PARPORT_MODE_
PCPS2
)
if
(
modes
&
PARPORT_MODE_
TRISTATE
)
imm_hosts
[
i
].
mode
=
IMM_PS2
;
if
(
modes
&
PARPORT_MODE_PCECPPS2
)
{
w_ecr
(
ppb
,
0x20
);
imm_hosts
[
i
].
mode
=
IMM_PS2
;
}
if
(
modes
&
PARPORT_MODE_PCECPEPP
)
w_ecr
(
ppb
,
0x80
);
/* Done configuration */
imm_pb_release
(
i
);
...
...
drivers/video/fbmem.c
View file @
90ff4d27
...
...
@@ -459,6 +459,11 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
for
(
i
=
0
;
i
<
MAX_NR_CONSOLES
;
i
++
)
set_con2fb_map
(
i
,
con2fb
.
framebuffer
);
return
0
;
case
FBIOBLANK
:
if
(
info
->
blank
==
0
)
return
-
EINVAL
;
(
*
info
->
blank
)(
arg
,
info
);
return
0
;
default:
return
fb
->
fb_ioctl
(
inode
,
file
,
cmd
,
arg
,
PROC_CONSOLE
(
info
),
info
);
...
...
fs/partitions/msdos.c
View file @
90ff4d27
...
...
@@ -26,6 +26,7 @@
#include <linux/major.h>
#include <linux/string.h>
#include <linux/blk.h>
#include <linux/ide.h>
/* IDE xlate */
#include <asm/system.h>
...
...
include/asm-alpha/keyboard.h
View file @
90ff4d27
...
...
@@ -37,6 +37,31 @@ extern unsigned char pckbd_sysrq_xlate[128];
#define SYSRQ_KEY 0x54
/* resource allocation */
#define kbd_request_region()
#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
"keyboard", NULL)
/* How to access the keyboard macros on this platform. */
#define kbd_read_input() inb(KBD_DATA_REG)
#define kbd_read_status() inb(KBD_STATUS_REG)
#define kbd_write_output(val) outb(val, KBD_DATA_REG)
#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
/* Some stoneage hardware needs delays after some operations. */
#define kbd_pause() do { } while(0)
/*
* Machine specific bits for the PS/2 driver
*/
#define AUX_IRQ 12
#define aux_request_irq(hand, dev_id) \
request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
#endif
/* __KERNEL__ */
#endif
/* __ASMalpha_KEYBOARD_H */
include/asm-alpha/uaccess.h
View file @
90ff4d27
...
...
@@ -487,6 +487,15 @@ extern inline long strlen_user(const char *str)
return
access_ok
(
VERIFY_READ
,
str
,
0
)
?
__strlen_user
(
str
)
:
0
;
}
/* Returns: 0 if exception before NUL or reaching the supplied limit (N),
* a value greater than N if the limit would be exceeded, else strlen. */
extern
long
__strnlen_user
(
const
char
*
,
long
);
extern
inline
long
strnlen_user
(
const
char
*
str
,
long
n
)
{
return
access_ok
(
VERIFY_READ
,
str
,
0
)
?
__strnlen_user
(
str
,
n
)
:
0
;
}
/*
* About the exception table:
*
...
...
include/linux/fb.h
View file @
90ff4d27
...
...
@@ -26,6 +26,7 @@
/* #define FBIOSWITCH_MONIBIT 0x460E */
#define FBIOGET_CON2FBMAP 0x460F
#define FBIOPUT_CON2FBMAP 0x4610
#define FBIOBLANK 0x4611
/* arg: 0 or vesa level + 1 */
#define FB_TYPE_PACKED_PIXELS 0
/* Packed Pixels */
#define FB_TYPE_PLANES 1
/* Non interleaved planes */
...
...
include/linux/ide.h
View file @
90ff4d27
...
...
@@ -46,9 +46,6 @@
#ifndef OK_TO_RESET_CONTROLLER
/* 1 needed for good error recovery */
#define OK_TO_RESET_CONTROLLER 1
/* 0 for use with AH2372A/B interface */
#endif
#ifndef FAKE_FDISK_FOR_EZDRIVE
/* 1 to help linux fdisk with EZDRIVE */
#define FAKE_FDISK_FOR_EZDRIVE 1
/* 0 to reduce kernel size */
#endif
#ifndef FANCY_STATUS_DUMPS
/* 1 for human-readable drive errors */
#define FANCY_STATUS_DUMPS 1
/* 0 to reduce kernel size */
#endif
...
...
@@ -262,9 +259,7 @@ typedef struct ide_drive_s {
unsigned
nice2
:
1
;
/* flag: give a share in our own bandwidth */
unsigned
doorlocking
:
1
;
/* flag: for removable only: door lock/unlock works */
unsigned
autotune
:
2
;
/* 1=autotune, 2=noautotune, 0=default */
#if FAKE_FDISK_FOR_EZDRIVE
unsigned
remap_0_to_1
:
1
;
/* flag: partitioned with ezdrive */
#endif
/* FAKE_FDISK_FOR_EZDRIVE */
unsigned
remap_0_to_1
:
2
;
/* 0=remap if ezdrive, 1=remap, 2=noremap */
unsigned
ata_flash
:
1
;
/* 1=present, 0=default */
byte
media
;
/* disk, cdrom, tape, floppy, ... */
select_t
select
;
/* basic drive/head select reg value */
...
...
@@ -282,8 +277,9 @@ typedef struct ide_drive_s {
byte
sect
;
/* "real" sectors per track */
byte
bios_head
;
/* BIOS/fdisk/LILO number of heads */
byte
bios_sect
;
/* BIOS/fdisk/LILO sectors per track */
unsigned
short
bios_cyl
;
/* BIOS/fdisk/LILO number of cyls */
unsigned
short
cyl
;
/* "real" number of cyls */
unsigned
int
bios_cyl
;
/* BIOS/fdisk/LILO number of cyls */
unsigned
int
cyl
;
/* "real" number of cyls */
unsigned
long
capacity
;
/* total number of sectors */
unsigned
int
drive_data
;
/* for use by tuneproc/selectproc as needed */
void
*
hwif
;
/* actually (ide_hwif_t *) */
wait_queue_head_t
wqueue
;
/* used to wait for drive in open() */
...
...
@@ -624,21 +620,19 @@ int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeou
/*
* This routine is called from the partition-table code in genhd.c
* to "convert" a drive to a logical geometry with fewer than 1024 cyls.
*
* The second parameter, "xparm", determines exactly how the translation
* will be handled:
* 0 = convert to CHS with fewer than 1024 cyls
* using the same method as Ontrack DiskManager.
* 1 = same as "0", plus offset everything by 63 sectors.
* -1 = similar to "0", plus redirect sector 0 to sector 1.
* >1 = convert to a CHS geometry with "xparm" heads.
*
* Returns 0 if the translation was not possible, if the device was not
* an IDE disk drive, or if a geometry was "forced" on the commandline.
* Returns 1 if the geometry translation was successful.
*/
int
ide_xlate_1024
(
kdev_t
,
int
,
int
,
const
char
*
);
/*
* Convert kdev_t structure into ide_drive_t * one.
*/
ide_drive_t
*
get_info_ptr
(
kdev_t
i_rdev
);
/*
* Return the current idea about the total capacity of this drive.
*/
unsigned
long
current_capacity
(
ide_drive_t
*
drive
);
/*
* Start a reset operation for an IDE interface.
* The caller should return immediately after invoking this.
...
...
include/linux/sched.h
View file @
90ff4d27
...
...
@@ -823,8 +823,8 @@ extern inline int task_on_runqueue(struct task_struct *p)
extern
inline
void
unhash_process
(
struct
task_struct
*
p
)
{
if
(
task_on_runqueue
(
p
))
BUG
();
nr_threads
--
;
write_lock_irq
(
&
tasklist_lock
);
nr_threads
--
;
unhash_pid
(
p
);
REMOVE_LINKS
(
p
);
write_unlock_irq
(
&
tasklist_lock
);
...
...
include/linux/tty.h
View file @
90ff4d27
...
...
@@ -326,6 +326,7 @@ struct tty_struct {
#define TTY_HW_COOK_OUT 14
#define TTY_HW_COOK_IN 15
#define TTY_PTY_LOCK 16
#define TTY_NO_WRITE_SPLIT 17
#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
...
...
kernel/fork.c
View file @
90ff4d27
...
...
@@ -592,6 +592,12 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
struct
task_struct
*
p
;
DECLARE_MUTEX_LOCKED
(
sem
);
if
(
clone_flags
&
CLONE_PID
)
{
/* This is only allowed from the boot up thread */
if
(
current
->
pid
)
return
-
EPERM
;
}
current
->
vfork_sem
=
&
sem
;
p
=
alloc_task_struct
();
...
...
@@ -610,8 +616,9 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
}
/*
* Counter atomicity is protected by
* the kernel lock
* Counter increases are protected by
* the kernel lock so nr_threads can't
* increase under us (but it may decrease).
*/
if
(
nr_threads
>=
max_threads
)
goto
bad_fork_cleanup_count
;
...
...
@@ -711,9 +718,9 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
write_lock_irq
(
&
tasklist_lock
);
SET_LINKS
(
p
);
hash_pid
(
p
);
nr_threads
++
;
write_unlock_irq
(
&
tasklist_lock
);
nr_threads
++
;
wake_up_process
(
p
);
/* do this last */
++
total_forks
;
...
...
@@ -735,8 +742,6 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
__MOD_DEC_USE_COUNT
(
p
->
exec_domain
->
module
);
if
(
p
->
binfmt
&&
p
->
binfmt
->
module
)
__MOD_DEC_USE_COUNT
(
p
->
binfmt
->
module
);
nr_threads
--
;
bad_fork_cleanup_count:
if
(
p
->
user
)
free_uid
(
p
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment