Skip to content

Commit 4c7af0d

Browse files
committed
switch video mode hack by dropping to real mode to call the video bios works!
1 parent 2f15433 commit 4c7af0d

File tree

5 files changed

+103
-75
lines changed

5 files changed

+103
-75
lines changed

src/boot/boot2.s

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,5 +553,76 @@ kbc_wait_write:
553553

554554
numbuf: .space 16
555555

556+
557+
# this is not boot loader code. It's called later on by the main
558+
# kernel code in 32bit protected mode. It's placed here because
559+
# it needs to be in base memory as it returns and runs in real mode.
560+
561+
.code32
562+
.align 4
563+
# place to save the protected mode IDTR pseudo-descriptor
564+
# with sidt, so that it can be restored before returning
565+
.short 0
566+
saved_idtr:
567+
idtlim: .short 0
568+
idtaddr:.long 0
569+
# real mode IDTR pseudo-descriptor pointing to the IVT at addr 0
570+
.short 0
571+
rmidt: .short 0x3ff
572+
.long 0
573+
574+
# drop back to unreal mode to set video mode
575+
.global set_mode13h
576+
set_mode13h:
577+
pushal
578+
cli
579+
# save protected mode IDTR and replace it with the real mode vectors
580+
sidt (saved_idtr)
581+
lidt (rmidt)
582+
583+
# long jump to load code selector for 16bit code (6)
584+
ljmp $0x30,$0f
585+
0:
586+
.code16
587+
# disable protection
588+
mov %cr0, %eax
589+
and $0xfffe, %ax
590+
mov %eax, %cr0
591+
# load cs <- 0
592+
ljmp $0,$0f
593+
0: # zero data segments
594+
xor %ax, %ax
595+
mov %ax, %ds
596+
mov %ax, %es
597+
mov %ax, %ss
598+
nop
599+
600+
# switch video mode by calling the video bios
601+
mov $0x13, %ax
602+
int $0x10
603+
604+
# re-enable protection
605+
mov %cr0, %eax
606+
or $1, %ax
607+
mov %eax, %cr0
608+
# long jump to load code selector for 32bit code (1)
609+
ljmp $0x8,$0f
610+
0:
611+
.code32
612+
# set data selector (2) to all segment regs
613+
mov $0x10, %ax
614+
mov %ax, %ds
615+
mov %ax, %es
616+
mov %ax, %ss
617+
nop
618+
619+
# restore 32bit interrupt descriptor table
620+
lidt (saved_idtr)
621+
sti
622+
popal
623+
ret
624+
625+
626+
# buffer used by the track loader ... to load tracks.
556627
.align 16
557628
buffer:

src/segm.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum {TYPE_DATA, TYPE_CODE};
4343
#define TSS_TYPE_BITS (9 << 8)
4444

4545
static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type);
46+
static void segm_desc16(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type);
4647
static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl);
4748

4849
/* these functions are implemented in segm-asm.S */
@@ -52,7 +53,7 @@ void set_task_reg(uint16_t tss_selector);
5253

5354

5455
/* our global descriptor table */
55-
static desc_t gdt[6] __attribute__((aligned(8)));
56+
static desc_t gdt[NUM_SEGMENTS] __attribute__((aligned(8)));
5657

5758

5859
void init_segm(void)
@@ -62,6 +63,7 @@ void init_segm(void)
6263
segm_desc(gdt + SEGM_KDATA, 0, 0xffffffff, 0, TYPE_DATA);
6364
segm_desc(gdt + SEGM_UCODE, 0, 0xffffffff, 3, TYPE_CODE);
6465
segm_desc(gdt + SEGM_UDATA, 0, 0xffffffff, 3, TYPE_DATA);
66+
segm_desc16(gdt + SEGM_CODE16, 0, 0xffff, 0, TYPE_CODE);
6567

6668
set_gdt((uint32_t)gdt, sizeof gdt - 1);
6769

@@ -98,6 +100,22 @@ static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int
98100
desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN | BIT_BIG;
99101
}
100102

103+
static void segm_desc16(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type)
104+
{
105+
desc->d[0] = limit & 0xffff; /* low order 16bits of limit */
106+
desc->d[1] = base & 0xffff; /* low order 16bits of base */
107+
108+
/* third 16bit part contains the last 8 bits of base, the 2 priviledge
109+
* level bits starting on bit 13, present flag on bit 15, and type bits
110+
* starting from bit 8
111+
*/
112+
desc->d[2] = ((base >> 16) & 0xff) | ((dpl & 3) << 13) | BIT_PRESENT |
113+
BIT_NOSYS | (type == TYPE_DATA ? BIT_WR : (BIT_RD | BIT_CODE));
114+
115+
/* 16bit descriptors have the upper word 0 */
116+
desc->d[3] = 0;
117+
}
118+
101119
static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl)
102120
{
103121
desc->d[0] = limit & 0xffff;

src/segm.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
#ifndef SEGM_H_
1919
#define SEGM_H_
2020

21-
#define SEGM_KCODE 1
22-
#define SEGM_KDATA 2
23-
#define SEGM_UCODE 3
24-
#define SEGM_UDATA 4
25-
#define SEGM_TASK 5
21+
enum {
22+
SEGM_KCODE = 1,
23+
SEGM_KDATA = 2,
24+
SEGM_UCODE,
25+
SEGM_UDATA,
26+
SEGM_TASK,
27+
SEGM_CODE16,
28+
29+
NUM_SEGMENTS
30+
};
2631

27-
#ifndef ASM
2832
void init_segm(void);
2933

3034
uint16_t selector(int idx, int rpl);
3135

3236
void set_tss(uint32_t addr);
33-
#endif /* ASM */
3437

3538

3639
#endif /* SEGM_H_ */

src/startup.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
.extern _bss_end
2222
.extern pcboot_main
2323

24+
# move the stack to the top of the conventional memory
25+
movl $0x80000, %esp
26+
2427
# zero the BSS section
2528
xor %eax, %eax
2629
mov $_bss_start, %edi

src/vbioshack.s

Lines changed: 0 additions & 67 deletions
This file was deleted.

0 commit comments

Comments
 (0)