Re: empty_zero_page+setup on intel?

Martin Mares (mj@atrey.karlin.mff.cuni.cz)
Sat, 30 May 1998 11:12:55 +0200


Hi,

> EXT_MEM_K is what is called 'unused1' in struct screen_info.
> However, there is also unused2, unused3 which I guess you should
> not touch.

`unused2' and `unused3' are really unused and free, `unused1' should be renamed
to `reserved' or `dontuse'.

> However, BEHIND screen_info and BEFORE APM_BIOS_INFO there is what is
> defined in arch/i386/kernel/head.S:
>
> #define CL_MAGIC_ADDR 0x90020
> #define CL_OFFSET 0x90022
>
> which is equivalent to
>
> #define CL_MAGIC_ADDR (*(unsigned short *) (PARAM+0x20))
> #define CL_OFFSET (*(unsigned short *) (PARAM+0x22))
>
> If you overwrite that, the commandline will not be copied !!

Now I see that someone who was implementing the VESA frame-buffer
initialization (now present in VGER CVS only) did not realize this and happily
extended the screen_info structure. As it seems everything between 0x24 and
0x3f is not used, so I reserve it for struct screen_info and change it to
provide the correct holes at 0x20--0x23. [patch attached]

> Next 512 bytes (offset 0x200) is the arch/i386/boot/setup.S header.
> This header was intended to be extendable for future needs (there is
> a header version for this), but someone without knowing this did place
>
> #define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0x220))
>
> directly within this header :-(((

The kernel currently uses only first 4 bytes of the structure and only
first 16 bytes contain useful information, I propose moving this structure
at 0xa0 and limiting it to 16 bytes. [patch attached]

> Ok, in order to not do the work twice, I'll append a summary, that should
> perhaps go some where under linux/Documents.

That's exactly I was going to do... ;-) [well, at least for one year...]

> Summary of empty_zero_page layout (kernel point of view)
> -------------------------------------------------------
>
> Offset Type Description
> ------ ---- -----------
> 0 18 bytes struct screen_info, SCREEN_INFO
> ATTENTION, overlaps the following !!!
> 2 unsigned short EXT_MEM_K, extended memory size in Kb (from int 0x15)
> 0x20 unsigned short CL_MAGIC, commandline magic number (=0xA33F)
> 0x22 unsigned short CL_OFFSET, commandline offset
> Address of commandline is calculated:
> 0x90000 + contents of CL_OFFSET
> (only taken, when CL_MAGIC = 0xA33F)
> 0x40 20 bytes struct apm_bios_info, APM_BIOS_INFO
> 0x80 16 bytes hd0-disk-parameter from intvector 0x41
> 0x90 16 bytes hd1-disk-parameter from intvector 0x46

0xa0 16 bytes System description table truncated to 16 bytes.
0xb0 ... 0x1df Free. Add more parameters here if you really need them.

> 0x1e0 unsigned long ALT_MEM_K, alternative mem check, in Kb
> 0x1f1 char size of setup.S, number of sectors
> 0x1f2 unsigned short MOUNT_ROOT_RDONLY (if !=0)
> 0x1f4 unsigned short size of compressed kernel-part in the
> (b)zImage-file (in 16 byte units, rounded up)
> 0x1f6 unsigned short swap_dev (unused AFAIK)
> 0x1f8 unsigned short RAMDISK_FLAGS
> 0x1fa unsigned short VGA-Mode (old one)
> 0x1fc unsigned short ORIG_ROOT_DEV (high=Major, low=minor)
> 0x1ff char AUX_DEVICE_INFO
>
> 0x200 setup.S header

0x200: short jump to start of setup code aka "reserved" field.

> 0x202 4 bytes Signature for SETUP-header, ="HdrS"
> 0x206 unsigned short Version number of header format

Current version is 0x0201...

> 0x208 8 bytes (used by setup.S)

0x208 8 bytes (used by setup.S for communication with boot loaders, look there)

> 0x210 char LOADER_TYPE, = 0, old one
> else it is set by the loader:
> 0xTV: T=0 for LILO
> 1 for Loadlin
> 2 for bootsect-loader
> 3 for SYSLINUX
> 4 for ETHERBOOT
> V = version
> 0x211 char loadflags:
> bit0 = 1: kernel is loaded high (bzImage)

bit7 = 1 Heap and pointer (see below) set by boot loader.

> 0x212

0x212 uns. short (setup.S)

> 0x214 unsigned long KERNEL_START, where the loader started the kernel
> 0x218 unsigned long INITRD_START, address of loaded ramdisk image
> 0x21c unsigned long INITRD_SIZE, size in bytes of ramdisk image

0x220 4 bytes (setup.S)
0x224 uns. short setup.S heap end pointer

> 0x220 ??? struct sys_desc_table_struct, SYS_DESC_TABLE
> NOTE: This structure of variable size
> overlays the setup.S header, which originally
> has been designed to be expandable in the future.
> IMHO this should be fixed before 2.2 !

Moved, see above...

0x226 - 0x7ff setup.S code.

> 0x800 string, 2K max COMMAND_LINE, the kernel commandline as
> copied using CL_OFFSET.
> Note: this will be copied once more setup.c
> into a local buffer which is only 256 bytes long.
> ( #define COMMAND_LINE_SIZE 256 )

Have a nice fortnight

-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
"Spelling checkers at maximum!  Fire!"

--- arch/i386/boot/setup.S.mj Sat May 30 11:02:49 1998 +++ arch/i386/boot/setup.S Sat May 30 11:03:40 1998 @@ -345,7 +345,7 @@ mov ds,ax mov ds,ax xor ax,ax - mov [0x220], ax ! set table length to 0 + mov [0xa0], ax ! set table length to 0 mov ah, #0xc0 stc int 0x15 ! puts feature table at es:bx @@ -357,9 +357,13 @@ sub ax, #DELTA_INITSEG ! aka #INITSEG mov es,ax mov si,bx - mov di,#0x220 + mov di,#0xa00 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 +sysdesc_ok: rep movsb pop ds --- arch/i386/boot/video.S.mj Sat May 30 11:05:37 1998 +++ arch/i386/boot/video.S Sat May 30 11:09:56 1998 @@ -68,22 +68,23 @@ #define VIDEO_RECALC 0x8000 ! Positions of various video parameters passed to the kernel -#define PARAM_CURSOR_POS 0 -#define PARAM_VIDEO_PAGE 4 -#define PARAM_VIDEO_MODE 6 -#define PARAM_VIDEO_COLS 7 -#define PARAM_VIDEO_EGA_BX 10 -#define PARAM_VIDEO_LINES 14 -#define PARAM_HAVE_VGA 15 -#define PARAM_FONT_POINTS 16 +! (see also include/linux/tty.h) +#define PARAM_CURSOR_POS 0x00 +#define PARAM_VIDEO_PAGE 0x04 +#define PARAM_VIDEO_MODE 0x06 +#define PARAM_VIDEO_COLS 0x07 +#define PARAM_VIDEO_EGA_BX 0x0a +#define PARAM_VIDEO_LINES 0x0e +#define PARAM_HAVE_VGA 0x0f +#define PARAM_FONT_POINTS 0x10 -#define PARAM_LFB_WIDTH 18 -#define PARAM_LFB_HEIGHT 20 -#define PARAM_LFB_DEPTH 22 -#define PARAM_LFB_BASE 24 -#define PARAM_LFB_SIZE 28 -#define PARAM_LFB_LINELENGTH 32 -#define PARAM_LFB_COLORS 34 +#define PARAM_LFB_WIDTH 0x12 +#define PARAM_LFB_HEIGHT 0x14 +#define PARAM_LFB_DEPTH 0x16 +#define PARAM_LFB_BASE 0x18 +#define PARAM_LFB_SIZE 0x1c +#define PARAM_LFB_LINELENGTH 0x24 +#define PARAM_LFB_COLORS 0x26 ! Define DO_STORE according to CONFIG_VIDEO_RETAIN #ifdef CONFIG_VIDEO_RETAIN --- arch/i386/kernel/setup.c.mj Sat May 30 11:04:04 1998 +++ arch/i386/kernel/setup.c Sat May 30 11:05:10 1998 @@ -87,13 +87,12 @@ * This is set up by the setup-routine at boot-time */ #define PARAM empty_zero_page +#define SCREEN_INFO (*(struct screen_info *) (PARAM+0)) #define EXT_MEM_K (*(unsigned short *) (PARAM+2)) #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0)) -#ifdef CONFIG_APM -#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64)) -#endif +#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40)) #define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80)) -#define SCREEN_INFO (*(struct screen_info *) (PARAM+0)) +#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0)) #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2)) #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8)) #define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC)) @@ -102,7 +101,6 @@ #define KERNEL_START (*(unsigned long *) (PARAM+0x214)) #define INITRD_START (*(unsigned long *) (PARAM+0x218)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) -#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0x220)) #define COMMAND_LINE ((char *) (PARAM+2048)) #define COMMAND_LINE_SIZE 256 --- include/linux/tty.h.mj Sat May 30 11:05:21 1998 +++ include/linux/tty.h Sat May 30 11:08:41 1998 @@ -40,34 +40,36 @@ */ struct screen_info { - unsigned char orig_x; - unsigned char orig_y; - unsigned char unused1[2]; - unsigned short orig_video_page; - unsigned char orig_video_mode; - unsigned char orig_video_cols; - unsigned short unused2; - unsigned short orig_video_ega_bx; - unsigned short unused3; - unsigned char orig_video_lines; - unsigned char orig_video_isVGA; - unsigned short orig_video_points; + unsigned char orig_x; /* 0x00 */ + unsigned char orig_y; /* 0x01 */ + unsigned short dontuse1; /* 0x02 -- EXT_MEM_K sits here */ + unsigned short orig_video_page; /* 0x04 */ + unsigned char orig_video_mode; /* 0x06 */ + unsigned char orig_video_cols; /* 0x07 */ + unsigned short unused2; /* 0x08 */ + unsigned short orig_video_ega_bx; /* 0x0a */ + unsigned short unused3; /* 0x0c */ + unsigned char orig_video_lines; /* 0x0e */ + unsigned char orig_video_isVGA; /* 0x0f */ + unsigned short orig_video_points; /* 0x10 */ /* VESA graphic mode -- linear frame buffer */ - unsigned short lfb_width; - unsigned short lfb_height; - unsigned short lfb_depth; - unsigned long lfb_base; - unsigned long lfb_size; - unsigned short lfb_linelength; - unsigned char red_size; - unsigned char red_pos; - unsigned char green_size; - unsigned char green_pos; - unsigned char blue_size; - unsigned char blue_pos; - unsigned char rsvd_size; - unsigned char rsvd_pos; + unsigned short lfb_width; /* 0x12 */ + unsigned short lfb_height; /* 0x14 */ + unsigned short lfb_depth; /* 0x16 */ + unsigned long lfb_base; /* 0x18 */ + unsigned long lfb_size; /* 0x1c */ + unsigned short dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */ + unsigned short lfb_linelength; /* 0x24 */ + unsigned char red_size; /* 0x26 */ + unsigned char red_pos; /* 0x27 */ + unsigned char green_size; /* 0x28 */ + unsigned char green_pos; /* 0x29 */ + unsigned char blue_size; /* 0x2a */ + unsigned char blue_pos; /* 0x2b */ + unsigned char rsvd_size; /* 0x2c */ + unsigned char rsvd_pos; /* 0x2d */ + /* 0x2e -- 0x3f reserved for future expansion */ }; extern struct screen_info screen_info;

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu