feat: ajout de code en realmode pour initialisation du pmode et préparation du chargement du noyau

This commit is contained in:
Nicolas Hordé 2018-12-30 12:25:20 +01:00
parent 620f63d101
commit 21bc3d2e3d
7 changed files with 372 additions and 9 deletions

41
include/setup.h Normal file
View File

@ -0,0 +1,41 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "types.h"
typedef struct entrye820 {
u64 addr;
u64 size;
u32 type;
} entrye820 __attribute__((packed));
typedef struct miniregs {
union {
struct {
u32 eax;
u32 ebx;
u32 ecx;
u32 edx;
u32 esi;
u32 edi;
u32 ebp;
u32 eflags;
};
struct {
u16 ax, hax;
u16 bx, hbx;
u16 cx, hcx;
u16 dx, hdx;
u16 si, hsi;
u16 di, hdi;
u16 bp, hbp;
u16 flags, hflags;
};
struct {
u8 bl, bh, hbx2, hbx3;
u8 dl, dh, hdx2, hdx3;
u8 cl, ch, hcx2, hcx3;
u8 al, ah, hax2, hax3;
};
};
} miniregs __attribute__ ((packed));

View File

@ -1,34 +1,35 @@
GCC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m32 -fno-pie -no-pie -c -o
GCCREAL=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m16 -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -mstack-alignment=4 -mno-80387 -mno-fp-ret-in-387 -c -o
ASM=gcc -nostdinc -ffreestanding -fno-builtin -m32 -c -fno-pie -no-pie
LINK=ld -m elf_i386 -n -o
CONVERT=dos2unix
INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl
REMOVE=rm -f
CHANGEPERM=chmod 644
NM=nm
ZOFFSET=sed -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p'
VOFFSET=sed -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
all: system.sys
system.sys: setup.bin system.bin
system.sys: realmode/setup.bin system.bin
$(NM) system.bin|$VOFFSET>voffset.h
$(NM) setup.bin|$ZOFFSET>zoffset.h
tools/build setup.bin system.bin zoffset.h system.sys
sync
togit: clean indent
system.bin: system.o ../lib/libs.o
$(LINK) -T linker.lds multiboot.o system.o ../lib/libs.o
$(LINK) -T system.ld system.o ../lib/libs.o
setup.bin: setup.o
$(LINK) $@ $^
$(OBJDUMP)
setup.o:
$(GCCREAL) $@ $^
realmode/setup.bin:
make -C realmode
system.o:
$(GCC) $@ $^
clean:
make -C realmode clean
$(REMOVE) *.o
$(REMOVE) *.out
$(REMOVE) *.bin
@ -38,6 +39,7 @@ clean:
sync
indent:
make -C realmode indent
$(CHANGEPERM) *.c
$(CONVERT) *.c
$(INDENT) *.c

36
system/realmode/makefile Normal file
View File

@ -0,0 +1,36 @@
GCC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../../include -m16 -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 -c -o
ASM=gcc -nostdinc -ffreestanding -fno-builtin -m16 -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 -c -o
LINK=ld -m elf_i386 -n -o
CONVERT=dos2unix
INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl
REMOVE=rm -f
CHANGEPERM=chmod 644
all: setup.bin
sync
setup.bin: setupc.o setup.o
$(LINK) -T setup.ld setupc.o setup.o
$(OBJDUMP)
setupc.o: setup.c
$(GCC) $@ $^
setup.o: setup.S
$(ASM) $@ $^
clean:
$(REMOVE) *.o
$(REMOVE) *.out
$(REMOVE) *.bin
$(REMOVE) *.sys
$(REMOVE) *.s
$(REMOVE) *.c~
sync
indent:
$(CHANGEPERM) *.c
$(CONVERT) *.c
$(INDENT) *.c
$(REMOVE) *.c~
sync

3
system/realmode/setup.S Normal file
View File

@ -0,0 +1,3 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */

217
system/realmode/setup.c Normal file
View File

@ -0,0 +1,217 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "types.h"
#include "asm.h"
#include "setup.h"
struct params {
entrye820 *e820_table;
u32 e820_numbers;
u8 kbflag;
} params;
#define EFLAGS_CF 0x00000001
#define LOOPS_8042 100000
#define FF_8042 32
#define LOOPS_A20_ENABLE 255
#define LOOPS_DELAY 32768
#define SMAP 0x534d4150
#define interrupt(num, regs) ({\
asm("pushal\n\
mov %[eflagsregs],%%eax\n\
pushl %%eax\n\
popfl\n\
mov %[eaxregs],%%eax\n\
mov %[ebxregs],%%ebx\n\
mov %[ecxregs],%%ecx\n\
mov %[edxregs],%%edx\n\
mov %[esiregs],%%esi\n\
mov %[ediregs],%%edi\n\
mov %[ebpregs],%%ebp\n\
int %[numregs]\n\
pushfl\n\
popl %%eax\n\
mov %%eax,%[eflagsregs]\n\
mov %%eax,%[eaxregs]\n\
mov %%ebx,%[ebxregs]\n\
mov %%ecx,%[ecxregs]\n\
mov %%edx,%[edxregs]\n\
mov %%esi,%[esiregs]\n\
mov %%edi,%[ediregs]\n\
mov %%ebp,%[ebpregs]\n\
popal":[eaxregs] "+m" (regs.eax),[ebxregs] "+m" (regs.ebx),[ecxregs] "+m" (regs.ecx),[edxregs] "+m" (regs.edx),[esiregs] "+m" (regs.esi),[ediregs] "+m" (regs.edi),[ebpregs] "+m" (regs.ebp),[eflagsregs] "+m" (regs.eflags):[numregs] "i" (num):);})
u8 initmemory(void)
{
u32 count = 0;
miniregs reg;
entrye820 *desc = params.e820_table;
static struct entrye820 buf;
do {
reg.ax = 0xe820;
reg.cx = sizeof(buf);
reg.edx = SMAP;
reg.di = &buf;
interrupt(0x15, reg);
if (reg.eflags & EFLAGS_CF)
break;
if (reg.eax != SMAP)
{
count = 0;
break;
}
*desc++ = buf;
count++;
} while (reg.ebx && count < ARRAY_SIZE(params.e820_table));
return params.e820_numbers= count;
}
void showchar(u8 achar)
{
miniregs reg;
reg.bx = 0x0007;
reg.cx = 0x0001;
reg.ah = 0x0e;
reg.al = achar;
interrupt(0x10, reg); /* INT 10 - VIDEO - TELETYPE OUTPUT */
}
void showstr(u8 *str)
{
while (*str!='\000')
showchar(*str++);
}
u8 gettime(void)
{
miniregs reg;
reg.ah = 0x02;
interrupt(0x1a, reg); /* TIME - GET REAL-TIME CLOCK TIME (AT,XT286,PS) */
return reg.dh;
}
u8 waitchar(void)
{
miniregs reg;
reg.ah = 0x00;
interrupt(0x16, reg); /* INT 16 - KEYBOARD - GET KEYSTROKE */
return reg.al;
}
void initkeyboard(void)
{
miniregs reg;
reg.ah = 0x02;
interrupt(0x16, reg); /* INT 16 - KEYBOARD - GET SHIFT FLAGS */
params.kbflag=reg.al;
reg.ah = 0x03;
reg.al = 0x05;
reg.bx = 0x00;
interrupt(0x16, reg); /* INT 16 - KEYBOARD - SET TYPEMATIC RATE AND DELAY */
}
u8 empty8042(void)
{
u8 status;
u32 loops = LOOPS_8042;
u8 ffs = FF_8042;
while (loops--) {
iodelay();
status = inb(0x64);
if (status == 0xff) {
if (!--ffs)
return NULL;
}
if (status & 1) {
io_delay();
(void)inb(0x60);
} else if (!(status & 2)) {
return 1;
}
}
return NULL;
}
void iodelay(void)
{
//asm("outb %%al,$0x80" ::);
for(u32 loop=LOOPS_DELAY;loop>0;loop--) nop();
}
u8 testA20(void)
{
asm("xorw %%cx, %%cx\n\
decw %%cx\n\
movw %%cx, %%gs\n\
movw $0x4000, %%cx\n\
movw %%fs:(0x200), %%ax\n\
pushw %%ax\n\
1:\n\
incw %%ax\n\
movw %%ax, %%fs:(0x200)\n\
call iodelay\n\
cmpw %%gs:(0x210), %%ax\n\
loope 1b\n\
popw %%fs:(0x200)\n\
xor %%ax,%%ax\n\
je 2f\n\
mov $0x1,%%ax\n\
2:":::"ax","cx");
}
void enableA20kbc(void)
{
empty8042();
outb(0xd1, 0x64);
empty8042();
outb(0xdf, 0x60);
empty8042();
outb(0xff, 0x64);
empty8042();
}
void enableA20fast(void)
{
u8 port;
port = inb(0x92);
port |= 0x02;
port &= ~0x01;
outb(port, 0x92);
}
u8 enableA20(void)
{
int loops = LOOPS_A20_ENABLE;
int kbcerr;
while (loops--) {
if (testA20())
return 1;
kbcerr = empty8042();
if (testA20())
return 1;
if (!kbcerr) {
enableA20kbc();
if (testA20())
return 1;
}
enableA20fast();
if (testA20())
return NULL;
}
return 1;
}
void main(void)
{
showstr("Chargement de COS2000 - mode reel");
initparams();
initheap();
initmemory();
initkeyboard();
initvideo();
initpmode();
}

64
system/realmode/setup.ld Normal file
View File

@ -0,0 +1,64 @@
/*
* setup.ld
*
* Linker script for the i386 setup code
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0;
.bstext : { *(.bstext) }
.bsdata : { *(.bsdata) }
. = 495;
.header : { *(.header) }
.entrytext : { *(.entrytext) }
.inittext : { *(.inittext) }
.initdata : { *(.initdata) }
__end_init = .;
.text : { *(.text) }
.text32 : { *(.text32) }
. = ALIGN(16);
.rodata : { *(.rodata*) }
.videocards : {
video_cards = .;
*(.videocards)
video_cards_end = .;
}
. = ALIGN(16);
.data : { *(.data*) }
.signature : {
setup_sig = .;
LONG(0x5a5aaa55)
}
. = ALIGN(16);
.bss :
{
__bss_start = .;
*(.bss)
__bss_end = .;
}
. = ALIGN(16);
_end = .;
/DISCARD/ : { *(.note*) }
/*
* The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
*/
. = ASSERT(_end <= 0x8000, "Setup too big!");
. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
/* Necessary for the very-old-loader check to work... */
. = ASSERT(__end_init <= 5*512, "init sections too big!");
}