大更新

This commit is contained in:
xiaoyi1212 2024-07-14 00:54:27 +08:00
parent 4ed9674bde
commit 49f205ea9d
49 changed files with 4216 additions and 260 deletions

10
apps/Makefile Normal file
View File

@ -0,0 +1,10 @@
default: Makefile
make -r -C libs
make -r -C init
make -r -C base_service
clean:
rm ../isodir/apps/*
make -r -C libs clean
make -r -C init clean
make -r -C base_service clean

View File

@ -0,0 +1,14 @@
OBJS_PACK = out/service.obj
include ../def.mk
default: $(OBJS_PACK)
$(LINK) $(OBJS_PACK) $(BASIC_LIB_C) -o ../../isodir/apps/service.bin
out/%.obj : %.c Makefile
$(C) -c $*.c -o out/$*.obj
out/%.obj : %.cpp Makefile
$(CPP) -c $*.cpp -o out/$*.obj
out/%.obj : %.asm Makefile
nasm -f elf $*.asm -o out/$*.obj
clean:
rm out/*

View File

@ -0,0 +1,7 @@
#include "../include/stdio.h"
int main(){
while (1);
put_char('A');
return 0;
}

16
apps/def.mk Normal file
View File

@ -0,0 +1,16 @@
CFLAGS = -m32 -I$(INCLUDE_PATH) -nostdinc -nolibc -nostdlib -ffreestanding -fno-stack-protector -Qn -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fomit-frame-pointer -finput-charset=UTF-8 -fexec-charset=GB2312 -march=pentium -Qn -O0 -w
CPPFLAGS = -m32 -I$(INCLUDE_PATH) -nostdinc -nolibc -nostdlib -ffreestanding -fno-exceptions -fno-stack-protector -Qn -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fomit-frame-pointer -finput-charset=UTF-8 -fexec-charset=GB2312 -Qn -O3 -march=pentium -fno-rtti -w
CC = gcc
C = $(CC) $(CFLAGS)
CPP = $(CC) $(CPPFLAGS)
INCLUDE_PATH := ../include
NASM = nasm
LIBS_PATH := ../libo
LD = ld
LD_FLAGS = -Ttext 0xb0000010 -m elf_i386 -static -e main
LINK = $(LD) $(LD_FLAGS)
BASIC_LIB_C = $(LIBS_PATH)/libp.a

6
apps/include/stdio.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef CRASHPOWEROS_STDIO_H
#define CRASHPOWEROS_STDIO_H
void put_char(char c);
#endif

14
apps/init/Makefile Normal file
View File

@ -0,0 +1,14 @@
OBJS_PACK = out/init.obj
include ../def.mk
default: $(OBJS_PACK)
$(LINK) $(OBJS_PACK) $(BASIC_LIB_C) -o ../../isodir/apps/init.bin
out/%.obj : %.c Makefile
$(C) -c $*.c -o out/$*.obj
out/%.obj : %.cpp Makefile
$(CPP) -c $*.cpp -o out/$*.obj
out/%.obj : %.asm Makefile
nasm -f elf $*.asm -o out/$*.obj
clean:
rm out/*

7
apps/init/init.c Normal file
View File

@ -0,0 +1,7 @@
#include "../include/stdio.h"
int main(){
while (1);
put_char('A');
return 0;
}

14
apps/libs/Makefile Normal file
View File

@ -0,0 +1,14 @@
OBJS_PACK = out/syscall.obj
default : $(OBJS_PACK)
ar rv ../libo/libp.a $(OBJS_PACK)
out/%.obj : %.c Makefile
gcc -m32 -I../include -nostdinc -nostdlib -fno-builtin -ffreestanding -fno-stack-protector -Qn -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fomit-frame-pointer -march=pentium -O0 -w -c $*.c -o out/$*.obj
out/%.obj : %.cpp Makefile
gcc -m32 -I../include -nostdinc -nostdlib -fno-builtin -ffreestanding -fno-stack-protector -Qn -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fomit-frame-pointer -march=pentium -O0 -w -c $*.cpp -o out/$*.obj
out/%.obj : %.asm Makefile
nasm -f elf $*.asm -o out/$*.obj
clean:
rm out/*
rm ../libo/*

11
apps/libs/syscall.asm Normal file
View File

@ -0,0 +1,11 @@
global put_char
put_char:
push edx
push eax
mov edx,[ss:esp+12]
mov eax,0x01
int 80h
pop eax
pop edx
ret

12
bochsrc.txt Normal file
View File

@ -0,0 +1,12 @@
megs: 2048
vga: extension=vbe, update_freq=15
ata1-master: type=cdrom, path=cpos.iso, status=inserted
#ata0-master: type=disk, path=disk.img, mode=flat, cylinders=2, heads=16, spt=63
ata2: enabled=false
ata3: enabled=false
boot: cdrom
display_library: win32, options="gui_debug"
#vgaromimage: file=/usr/share/vgabios/vgabios.bin

View File

@ -89,7 +89,7 @@ def build_kernel(): # 构建内核本体
def build_data(): # 构建常用工具
print("Building util source code...")
for file in os.listdir(cd + dir_ + src + 'util'):
cmd = cd + gcc + "-O2 " + src + "util" + dir_ + file + " -o " + "target" + dir_ + file.split(".")[0] + ".o"
cmd = cd + gcc + "-O0 " + src + "util" + dir_ + file + " -o " + "target" + dir_ + file.split(".")[0] + ".o"
e = os.system(cmd)
if e != 0:
return -1
@ -132,7 +132,7 @@ def linker(): # 交叉编译链接
for file in os.listdir(cd + dir_ + 'target'):
source_file = source_file + " target" + dir_ + file
return os.system(
cd + "/i686_elf_tools/bin/i686-elf-g++.exe -T linker.ld -o isodir" + dir_ + "sys" + dir_ + "kernel.elf -ffreestanding -O2 -nostdlib " + source_file + " -lgcc")
cd + "/i686_elf_tools/bin/i686-elf-g++.exe -T linker.ld -o isodir" + dir_ + "sys" + dir_ + "kernel.elf -ffreestanding -nostdlib " + source_file + " -lgcc")
def launch():

View File

@ -33,4 +33,5 @@ longjmp:
inc eax ; else: goto lable 1
.1: ; let longjmp's ret addr as setjmp's ret addr
mov [esp + 0], ecx ; ret addr = ecx = setjmp's next code
ret
ret

View File

@ -56,10 +56,8 @@ int acpi_enable() {
}
// check enable status
if (i < 300) {
printf("[acpi]: Enable ACPI\n");
return 0;
} else {
printf("Counld't enable ACPI\n");
return -1;
}
}
@ -89,10 +87,8 @@ int acpi_disable() {
}
if (i < 300) {
printf("ACPI Disable!\n");
return 0;
} else {
printf("Could't disable ACPI\n");
return -1;
}
}
@ -140,7 +136,6 @@ void power_off() {
if (!SCI_EN)
return;
while (1) {
printf("[acpi] send power off command!\n");
io_out16((uint32_t) PM1a_CNT, SLP_TYPa | SLP_EN);
if (!PM1b_CNT) {
io_out16((uint32_t) PM1b_CNT, SLP_TYPb | SLP_EN);
@ -180,17 +175,12 @@ static void AcpiPowerInit() {
if (PM1b_ENABLE_REG == len)
PM1b_ENABLE_REG = 0;
printf("[acpi]: Setting Power event listener...\n");
io_out16(PM1a_ENABLE_REG, (1 << 8));
if (PM1b_ENABLE_REG) {
io_out16((uint16_t)
PM1b_ENABLE_REG, (uint8_t)(1 << 8));
}
printf("ACPI : SCI_INT %08x\n", (uint8_t)
facp->SCI_INT);
register_interrupt_handler(facp->SCI_INT, AcpiPowerHandler);
}
@ -217,7 +207,6 @@ uint8_t *AcpiCheckRSDPtr(void *ptr) {
// check signature
if (!memcmp(sign, bptr, 8)) {
printf("[acpi] rsdp found at %0x\n", bptr);
rsdp_address = bptr;
for (i = 0; i < sizeof(acpi_rsdptr_t); i++) {
check += *bptr;
@ -255,7 +244,7 @@ static int AcpiSysInit() {
rsdt = (acpi_rsdt_t *) AcpiGetRSDPtr();
if (!rsdt || AcpiCheckHeader(rsdt, "RSDT") < 0) {
printf("No ACPI\n");
return -1;
return false;
}
entrys = rsdt->length - HEADER_SIZE / 4;
@ -315,7 +304,7 @@ static int AcpiSysInit() {
} else {
printf("[acpi] no found DSDT table\n");
}
return 0;
return true;
}
++p;
}
@ -323,9 +312,8 @@ static int AcpiSysInit() {
}
void acpi_install() {
AcpiSysInit();
klogf(AcpiSysInit(),"Load acpi driver.\n");
acpi_enable_flag = !acpi_enable();
// power init
hpet_initialize();
AcpiPowerInit();
}
@ -383,14 +371,10 @@ void hpet_initialize() {
printf("can not found acpi hpet table\n");
}
printf("[acpi-hpet]: OEM: %s | Version: %d\n",hpet->oem,hpet->oemVersion);
hpetInfo = (HpetInfo *) hpet->hpetAddress.address;
uint32_t counterClockPeriod = hpetInfo->generalCapabilities >> 32;
hpetPeriod = counterClockPeriod / 1000000;
hpetInfo->generalConfiguration |= 1; // 启用hpet
printf("[acpi]: hpet successfully enabled.\n");
}

View File

@ -68,7 +68,6 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
// 2- Disable IRQs:
ide_write(ATA_PRIMARY, ATA_REG_CONTROL, 2);
ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);
logk("w1\n");
// 3- Detect ATA-ATAPI Devices:
for (int i = 0; i < 2; i++)
for (j = 0; j < 2; j++) {
@ -78,20 +77,15 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
// (I) Select Drive:
ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j << 4)); // Select Drive.
sleep(1); // Wait 1ms for drive select to work.
logk("I\n");
// (II) Send ATA Identify Command:
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
sleep(1); // This function should be implemented in your OS. which waits
// for 1 ms. it is based on System Timer Device Driver.
logk("II\n");
// (III) Polling:
if (ide_read(i, ATA_REG_STATUS) == 0)
continue; // If Status = 0, No Device.
logk("III\n");
while (1) {
logk("read ide....\n");
status = ide_read(i, ATA_REG_STATUS);
logk("read ok\n");
if ((status & ATA_SR_ERR)) {
err = 1;
break;
@ -101,7 +95,6 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
}
// (IV) Probe for ATAPI Devices:
logk("IV\n");
if (err != 0) {
unsigned char cl = ide_read(i, ATA_REG_LBA1);
unsigned char ch = ide_read(i, ATA_REG_LBA2);
@ -118,11 +111,9 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
}
// (V) Read Identification Space of the Device:
logk("V\n");
ide_read_buffer(i, ATA_REG_DATA, (unsigned int) ide_buf, 128);
// (VI) Read Device Parameters:
logk("VI\n");
ide_devices[count].Reserved = 1;
ide_devices[count].Type = type;
ide_devices[count].Channel = i;
@ -135,7 +126,6 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
*((unsigned int *) (ide_buf + ATA_IDENT_COMMANDSETS));
// (VII) Get Size:
logk("VII\n");
if (ide_devices[count].CommandSets & (1 << 26))
// Device uses 48-Bit Addressing:
ide_devices[count].Size =
@ -147,7 +137,6 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
// (VIII) String indicates model of device (like Western Digital HDD and
// SONY DVD-RW...):
logk("VIII\n");
for (k = 0; k < 40; k += 2) {
ide_devices[count].Model[k] = ide_buf[ATA_IDENT_MODEL + k + 1];
ide_devices[count].Model[k + 1] = ide_buf[ATA_IDENT_MODEL + k];
@ -161,10 +150,12 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
vdisk vd;
for (int i = 0; i < 4; i++)
if (ide_devices[i].Reserved == 1) {
/*
logkf(" %d Found %s Drive %dMB - %s\n", i,
(const char *[]) {"ATA", "ATAPI"}[ide_devices[i].Type], /* Type */
ide_devices[i].Size / 1024 / 2, /* Size */
(const char *[]) {"ATA", "ATAPI"}[ide_devices[i].Type],
ide_devices[i].Size / 1024 / 2,
ide_devices[i].Model);
*/
strcpy(vd.DriveName, ide_devices[i].Model);
if(ide_devices[i].Type == IDE_ATAPI) {
vd.flag = 2;
@ -175,7 +166,7 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
vd.Read = Read;
vd.Write = Write;
vd.size = ide_devices[i].Size;
printf("[Disk-(%c)]: Size: %dMB | %s | Name: %s\n", register_vdisk(vd), vd.size,(const char *[]) {"ATA", "ATAPI"}[ide_devices[i].Type], vd.DriveName);
klogf(true,"Disk-(%c) Size: %dMB | %s | Name: %s\n", register_vdisk(vd), vd.size,(const char *[]) {"ATA", "ATAPI"}[ide_devices[i].Type], vd.DriveName);
}
}
@ -242,21 +233,17 @@ unsigned char ide_polling(unsigned char channel, unsigned int advanced_check) {
// (II) Wait for BSY to be cleared:
// -------------------------------------------------
logk("II\n");
int a = ide_read(channel, ATA_REG_STATUS);
while (a & ATA_SR_BSY) {
logkf("a=%d\n", a & ATA_SR_BSY); // Wait for BSY to be zero.
a = ide_read(channel, ATA_REG_STATUS);
sleep(1);
}
logk("II OK\n");
if (advanced_check) {
unsigned char state =
ide_read(channel, ATA_REG_STATUS); // Read Status Register.
// (III) Check For Errors:
// -------------------------------------------------
logk("III\n");
if (state & ATA_SR_ERR)
return 2; // Error.
@ -356,7 +343,6 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
ide_write(channel, ATA_REG_CONTROL,
channels[channel].nIEN = (ide_irq_invoked = 0x0) + 0x02);
// (I) Select one from LBA28, LBA48 or CHS;
logkf("I %02x\n", channels[channel].nIEN);
if (lba >= 0x10000000) { // Sure Drive should support LBA in this case, or
// you are giving a wrong LBA.
// LBA48:
@ -393,14 +379,11 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
(63); // Head number is written to HDDEVSEL lower 4-bits.
}
// (II) See if drive supports DMA or not;
logk("II\n");
dma = 0; // We don't support DMA
// (III) Wait if the drive is busy;
logk("III\n");
while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY) {
} // Wait if busy.
// (IV) Select Drive from the controller;
logk("IV\n");
if (lba_mode == 0)
ide_write(channel, ATA_REG_HDDEVSEL,
0xA0 | (slavebit << 4) | head); // Drive & CHS.
@ -443,7 +426,6 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
if (lba_mode == 2 && dma == 1 && direction == 1)
cmd = ATA_CMD_WRITE_DMA_EXT;
ide_write(channel, ATA_REG_COMMAND, cmd); // Send the Command.
logk("IV1\n");
if (dma)
if (direction == 0);
// DMA Read.
@ -457,7 +439,6 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
if (err = ide_polling(channel, 1))
return err; // Polling, set error and exit if there is.
logkf("words=%d bus=%d\n", words, bus);
for (int h = 0; h < words; h++) {
unsigned short a = io_in16(bus);
word_[i * words + h] = a;
@ -489,21 +470,17 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
}
void ide_wait_irq() {
logk("WAITING\n");
while (!ide_irq_invoked);
ide_irq_invoked = 0;
logk("IDE_WAIT_IRQ!\n");
}
void ide_irq() {
logk("ide irq.\n");
ide_irq_invoked = 1;
}
unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
unsigned char numsects, unsigned short selector,
unsigned int edi) {
logk("cdrom read.\n");
unsigned int channel = ide_devices[drive].Channel;
unsigned int slavebit = ide_devices[drive].Drive;
unsigned int bus = channels[channel].base;
@ -516,7 +493,6 @@ unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
channels[channel].nIEN = ide_irq_invoked = 0x0);
// (I): Setup SCSI Packet:
// ------------------------------------------------------------------
logk("CDROM I\n");
atapi_packet[0] = ATAPI_CMD_READ;
atapi_packet[1] = 0x0;
atapi_packet[2] = (lba >> 24) & 0xFF;
@ -531,12 +507,9 @@ unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
atapi_packet[11] = 0x0; // (II): Select the drive:
// ------------------------------------------------------------------
ide_write(channel, ATA_REG_HDDEVSEL, slavebit << 4);
logk("CDROM II\n");
// (III): Delay 400 nanoseconds for select to complete:
for (int i = 0; i < 4000; i++);
logk("CDROM III\n");
// ------------------------------------------------------------------
logk("CDROM IV\n");
for (int i = 0; i < 4; i++)
ide_read(channel,
ATA_REG_ALTSTATUS); // Reading the Alternate Status port wastes
@ -547,7 +520,6 @@ unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
0); // PIO mode.
// (V): Tell the Controller the size of buffer:
// ------------------------------------------------------------------
logk("CDROM V\n");
ide_write(channel, ATA_REG_LBA1,
(words * 2) & 0xFF); // Lower Byte of Sector Size.
ide_write(channel, ATA_REG_LBA2,
@ -563,20 +535,17 @@ unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
// (VIII): Sending the packet data:
// ------------------------------------------------------------------
logk("CDROM VIII\n");
uint16_t *_atapi_packet = atapi_packet;
for (int i = 0; i < 6; i++) {
io_out16(bus, _atapi_packet[i]);
}
// (IX): Receiving Data:
// ------------------------------------------------------------------
logk("CDROM IX\n");
uint16_t *_word = edi;
for (i = 0; i < numsects; i++) {
ide_wait_irq(); // Wait for an IRQ.
if (err = ide_polling(channel, 1))
return err; // Polling and return if error.
logkf("CDROM words = %d\n", words);
insl(bus, _word + i * words, words / 2);
}
@ -609,7 +578,6 @@ void ide_read_sectors(unsigned char drive, unsigned char numsects,
else {
unsigned char err;
if (ide_devices[drive].Type == IDE_ATA) {
logk("Will Read.\n");
err = ide_ata_access(ATA_READ, drive, lba, numsects, es, edi);
} else if (ide_devices[drive].Type == IDE_ATAPI)

View File

@ -119,18 +119,25 @@ static void default_handle(uint32_t key,int release,char c){
void init_keyboard(){
key_status = (KEY_STATUS*) alloc(sizeof(KEY_STATUS));
if(key_status == NULL) goto error;
key_status->is_shift = 0;
key_char_queue = create_queue();
head_listener = (struct key_listener*) kmalloc(sizeof(struct key_listener));
if(head_listener == NULL) goto error;
head_listener->func = default_handle;
head_listener->lid = 0;
head_listener->next = NULL;
register_interrupt_handler(0x21,handle_keyboard_input);
klogf(true,"Load PS/2 Keyboard device.\n");
return;
error:
klogf(false,"Load PS/2 Keyboard device.\n");
}
int handle_keyboard_input(){
int handle_keyboard_input(registers_t *reg){
unsigned char status = read_port(KEYBOARD_STATUS_PORT);
uint32_t key = read_port(KEYBOARD_DATA_PORT);
int release = key & 0xb10000000;

91
src/driver/mouse.c Normal file
View File

@ -0,0 +1,91 @@
#include "../include/mouse.h"
#include "../include/io.h"
#include "../include/isr.h"
#include "../include/printf.h"
uint8_t mouse_cycle = 0; //unsigned char
int8_t mouse_byte[3]; //signed char
int8_t mouse_x = 0; //signed char
int8_t mouse_y = 0; //signed char
static void wait_KBC_sendready(void) {
for (;;) {
if ((io_in8(0x0064) & 0x02) == 0) {
break;
}
}
return;
}
static void mouse_handler(registers_t *a_r) {
switch (mouse_cycle) {
case 0:
mouse_byte[0] = io_in8(0x60);
mouse_cycle++;
break;
case 1:
mouse_byte[1] = io_in8(0x60);
mouse_cycle++;
break;
case 2:
mouse_byte[2] = io_in8(0x60);
mouse_x = mouse_byte[1];
mouse_y = mouse_byte[2];
mouse_cycle = 0;
break;
}
printf("Mouse Mov: %d %d\n",mouse_x,mouse_y);
}
void mouse_wait(uint8_t a_type) {
unsigned int _time_out = 100000;
if (a_type == 0) {
while (_time_out--) {
if ((io_in8(0x64) & 1) == 1) {
return;
}
}
return;
} else {
while (_time_out--) {
if ((io_in8(0x64) & 2) == 0) {
return;
}
}
return;
}
}
void mouse_write(uint8_t a_write) {
mouse_wait(1);
io_out8(0x64, 0xD4);
mouse_wait(1);
io_out8(0x60, a_write);
}
uint8_t mouse_read() {
mouse_wait(0);
return io_in8(0x60);
}
void mouse_reset() {
mouse_write(0xff);
}
void mouse_install() {
wait_KBC_sendready();
io_out8(0x0064, 0xd4);
wait_KBC_sendready();
io_out8(0x0060, 0xf4);
mouse_write(0xf3);
mouse_write(200);
mouse_write(0xf3);
mouse_write(100);
mouse_write(0xf3);
mouse_write(80);
mouse_write(0xf2);
logkf("mouseId=%d\n", mouse_read());
register_interrupt_handler(12,mouse_handler);
}

View File

@ -104,7 +104,6 @@ void pci_config(unsigned int bus, unsigned int f, unsigned int equipment, unsign
}
void init_pci(){
printf("[\035kernel\036]: Loading pci device...\n");
int PCI_NUM = 0;
PCI_ADDR_BASE = kmalloc(1 * 1024 * 1024);
@ -155,6 +154,5 @@ void init_pci(){
}
}
}
printf("[pci]: Device Loaded: %d\n",PCI_NUM);
klogf(true,"PCI device loaded: %d\n",PCI_NUM);
}

View File

@ -28,6 +28,16 @@ static void copy_char(uint32_t *vram, int off_x, int off_y, int x, int y, int x1
}
}
void drawPixel(uint32_t x, uint32_t y, uint32_t color) {
if (x >= width
|| y >= height) {
return;
}
color = (color & 0xff) << 16 | (color & 0xff00) | (color & 0xff0000) >> 16;
uint32_t *p = (uint32_t *)screen + y * width + x;
*p = color;
}
void vbe_scroll() {
if (cx > c_width) {
cx = 0;
@ -198,7 +208,8 @@ void initVBE(multiboot_t *info) {
width = info->framebuffer_width;
height = info->framebuffer_height;
color = 0xc6c6c6;
back_color = 0x1c1c1c;
//back_color = 0x1c1c1c;
back_color = 0x000000;
c_width = width / 9;
c_height = height / 16;

View File

@ -16,6 +16,7 @@ int init_vdisk() {
for (int i = 0; i < 26; i++) {
vdisk_ctl[i].flag = 0; // 设置为未使用
}
klogf(true,"VDisk interface initialize.\n");
}
int register_vdisk(vdisk vd) {

View File

@ -85,6 +85,7 @@ int get_directory_max(struct FAT_FILEINFO *directory, vfs_t *vfs) {
}
}
}
void file_loadfile(int clustno, int size, char *buf, int *fat, vfs_t *vfs) {
if (!size) {
return;
@ -168,15 +169,7 @@ void file_savefile(int clustno, int size, char *buf, int *fat,
}
void *img = kmalloc(alloc_size);
memclean((char *)img, alloc_size);
memcpy(img, buf, size); // 把要写入的数据复制到新请求的内存地址
// for (int i = 0; i != (alloc_size / get_dm(vfs).ClustnoBytes); i++) {
// uint32_t sec = (get_dm(vfs).FileDataAddress +
// (clustno - 2) * get_dm(vfs).ClustnoBytes) /
// get_dm(vfs).SectorBytes;
// Disk_Write(sec, get_dm(vfs).ClustnoBytes / get_dm(vfs).SectorBytes,
// img + i * get_dm(vfs).ClustnoBytes, vfs->disk_number);
// clustno = fat[clustno];
// }
memcpy(img, buf, size);
int flag = 0, a, num = 0, sec_start = 0;
for (int i = 0; i != (alloc_size / get_dm(vfs).ClustnoBytes); i++) {
uint32_t sec = (get_dm(vfs).FileDataAddress +

View File

@ -10,6 +10,7 @@
vfs_t vfsstl[26];
vfs_t vfsMount_Stl[26];
vfs_t *vfs_now;
bool hasFS;
static vfs_t *drive2fs(uint8_t drive) {
for (int i = 0; i < 26; i++) {
@ -71,7 +72,6 @@ static void insert_str1(char *str, char *insert_str1, int pos) {
}
bool vfs_mount_disk(uint8_t disk_number, uint8_t drive) {
printf("Mount DISK ---- %02x\n", disk_number);
for (int i = 0; i < 26; i++) {
if (vfsMount_Stl[i].flag == 1 &&
(vfsMount_Stl[i].drive == drive ||
@ -95,6 +95,9 @@ bool vfs_mount_disk(uint8_t disk_number, uint8_t drive) {
seat->drive = drive;
seat->disk_number = disk_number;
seat->flag = 1;
printf("Disk %c mount success!\n",disk_number);
return true;
}
@ -400,10 +403,10 @@ void init_vfs() {
// PDEBUG("Set vfsstl[%d] & vfsMount_Stl[%d] OK.", i, i);
}
vfs_now = NULL;
klogf(true,"Virtual File System initialize.\n");
}
bool vfs_register_fs(vfs_t vfs) {
printf("Register file system: %s\n", vfs.FSName);
vfs_t *seat;
seat = findSeat(vfsstl);
if (!seat) {
@ -411,5 +414,6 @@ bool vfs_register_fs(vfs_t vfs) {
return false;
}
*seat = vfs;
klogf(true,"Register file system: %s\n",vfs.FSName);
return true;
}

27
src/include/bmp.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef CRASHPOWEROS_BMP_H
#define CRASHPOWEROS_BMP_H
#include "common.h"
typedef struct {
uint16_t magic;
uint32_t fileSize;
uint32_t reserved;
uint32_t bmpDataOffset;
// bmp信息头开始
uint32_t bmpInfoSize;
uint32_t frameWidth;
uint32_t frameHeight;
uint16_t reservedValue; // 必须为0x0001
uint16_t bitsPerPixel;
uint32_t compressionMode;
uint32_t frameSize;
uint32_t horizontalResolution;
uint32_t verticalResolution;
uint32_t usedColorCount;
uint32_t importantColorCount;
} __attribute__((packed)) Bmp;
void display(Bmp *bmp,uint32_t x, uint32_t y, bool isTransparent);
#endif

View File

@ -2,7 +2,11 @@
#define CRASHPOWEROS_COMMON_H
#define OS_NAME "CoolPotOS"
#define OS_VERSION "v0.2.5"
#define OS_VERSION "v0.2.9"
// b 0x211972
// b 0x20d0a6
#define LONG_MAX 9223372036854775807L
#define LONG_MIN -9223372036854775808L

View File

@ -5,6 +5,8 @@
#define GDT_LENGTH 6
#define SA_RPL3 3
typedef struct gdt_entry_t {
uint16_t limit_low; // 段基址 | 低16位置
uint16_t base_low; // 段基址 | 高16位置
@ -121,12 +123,38 @@ typedef struct tss_table {
uint16_t iomap_base;
} tss_entry;
typedef struct intr_frame_t {
unsigned edi;
unsigned esi;
unsigned ebp;
// 虽然 pushad 把 esp 也压入,但 esp 是不断变化的,所以会被 popad 忽略
unsigned esp_dummy;
unsigned ebx;
unsigned edx;
unsigned ecx;
unsigned eax;
unsigned gs;
unsigned fs;
unsigned es;
unsigned ds;
unsigned eip;
unsigned cs;
unsigned eflags;
unsigned esp;
unsigned ss;
} intr_frame_t;
void write_tss(int32_t num, uint16_t ss0, uint32_t esp0);
void set_kernel_stack(uintptr_t stack);
void set_tss_ss0(uintptr_t ss);
void gdt_install();
void idt_install();
void idt_use_reg(uint8_t num,uint32_t base);
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags);
#endif //CRASHPOWEROS_DESCRIPTION_TABLE_H

6
src/include/desktop.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef CRASHPOWEROS_DESKTOP_H
#define CRASHPOWEROS_DESKTOP_H
void menu_sel();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -105,6 +105,6 @@ int cur_task();
void vbe_draw_char(char c,int32_t x,int32_t y);
void draw_rect(int x0, int y0, int x1, int y1, int c);
void initVBE(multiboot_t *multiboot);
void drawPixel(uint32_t x, uint32_t y, uint32_t color);
#endif

10
src/include/heap.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef CRASHPOWEROS_HEAP_H
#define CRASHPOWEROS_HEAP_H
#include "task.h"
void *user_alloc(struct task_struct *user_t, size_t size);
void use_free(struct task_struct *user_t,void *block);
void *use_sbrk(struct task_struct *user_t,int incr);
#endif

View File

@ -6,15 +6,23 @@
#include "isr.h"
#define KHEAP_INITIAL_SIZE 0xf00000
#define KHEAP_START 0xc0000000
#define KHEAP_START 0xa0000000
#define STACK_SIZE 32768
#define USER_START 0xb0000000
#define USER_END (USER_START + 0xf00000)
#define USER_HEAP_END (USER_END - STACK_SIZE)
#define US_B_START 0xe0000000
#define US_B_END 0xe1000000
#define INDEX_FROM_BIT(a) (a / (8*4))
#define OFFSET_FROM_BIT(a) (a % (8*4))
typedef char ALIGN[16];
#include "multiboot.h"
#include "common.h"
typedef struct page {
uint32_t present: 1;
@ -24,17 +32,17 @@ typedef struct page {
uint32_t dirty: 1;
uint32_t unused: 7;
uint32_t frame: 20;
} page_t;
}__attribute__((packaged)) page_t;
typedef struct page_table {
page_t pages[1024];
} page_table_t;
}__attribute__((packaged)) page_table_t;
typedef struct page_directory {
page_table_t *tables[1024];
uint32_t tablesPhysical[1024];
uint32_t physicalAddr;
} page_directory_t;
}__attribute__((packaged)) page_directory_t;
typedef union header {
struct {
@ -57,7 +65,7 @@ void *memmove(void *dest, const void *src, size_t num);
void switch_page_directory(page_directory_t *dir);
page_t *get_page(uint32_t address, int make, page_directory_t *dir);
page_t *get_page(uint32_t address, int make, page_directory_t *dir,bool ist);
void alloc_frame(page_t *page, int is_kernel, int is_writable);

12
src/include/mouse.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef CRASHPOWEROS_MOUSE_H
#define CRASHPOWEROS_MOUSE_H
#include "common.h"
uint8_t mouse_read();
void mouse_reset();
void mouse_wait(uint8_t a_type);
void mouse_write(uint8_t a_write);
void mouse_install();
#endif

View File

@ -1,4 +1,13 @@
#ifndef CRASHPOWEROS_PANIC_H
#define CRASHPOWEROS_PANIC_H
enum PANIC_TYPE{
ILLEGAL_KERNEL_STATUS,
OUT_OF_MEMORY,
KERNEL_PAGE_FAULT
};
void panic_pane(char* msg,enum PANIC_TYPE type);
void init_eh();
#endif

View File

@ -5,6 +5,8 @@
#include <stdint.h>
#include <stdarg.h>
#include "common.h"
int vsprintf(char *buf, const char *fmt, va_list args);
int sprintf(char *buf, const char *fmt, ...);
void printf(const char *formet, ...);
@ -14,5 +16,6 @@ void putchar(char c);
void logk(char *message);
void logkf(char *formet,...);
void screen_clear();
void klogf(bool isok,char* fmt,...);
#endif //CRASHPOWEROS_PRINTF_H

View File

@ -2,6 +2,11 @@
#define CRASHPOWEROS_TASK_H
#include "memory.h"
#include "vfs.h"
typedef struct {
int (*main)(int argc,char* * argv);
}user_func_t;
typedef
enum task_state {
@ -25,8 +30,14 @@ struct context {
struct task_struct {
volatile task_state state; // 进程当前状态
int pid; // 进程标识符
int mem_size; //内存利用率
char *name; // 进程名
void *stack; // 进程的内核栈地址
header_t *head;
header_t *tail;
bool isUser;
uint32_t program_break;
uint32_t program_break_end;
page_directory_t *pgd_dir; // 进程页表
struct context context; // 上下文信息
struct task_struct *next; // 链表指针
@ -60,4 +71,7 @@ void start_task(struct task_struct *task);
int get_procs();
void switch_to_user_mode(uint32_t func);
int32_t user_process(char* path, char *name);
#endif //CRASHPOWEROS_TASK_H

View File

@ -45,6 +45,10 @@ void set_kernel_stack(uintptr_t stack) {
tss.esp0 = stack;
}
void set_tss_ss0(uintptr_t ss){
tss.ss0 = ss;
}
void gdt_install() {
gdt_ptr.limit = sizeof(gdt_entry_t) * GDT_LENGTH - 1;
gdt_ptr.base = (uint32_t)&gdt_entries;

66
src/kernel/heap.c Normal file
View File

@ -0,0 +1,66 @@
#include "../include/heap.h"
#include "../include/printf.h"
extern struct task_struct *current;
static header_t *use_get_free_block(struct task_struct *user_t, size_t size) {
header_t *curr = user_t->head;
while (curr) {
if (curr->s.is_free && curr->s.size >= size) return curr;
curr = curr->s.next;
}
return NULL;
}
void *use_sbrk(struct task_struct *user_t,int incr) {
if (user_t->program_break + incr >= (user_t->program_break_end)) return (void *) -1;
void *prev_break = user_t->program_break;
user_t->program_break += incr;
return prev_break;
}
void *user_alloc(struct task_struct *user_t, size_t size) {
uint32_t total_size;
void *block;
header_t *header;
if (!size) return NULL;
header = use_get_free_block(user_t,size);
if (header) {
header->s.is_free = 0;
return (void *) (header + 1);
}
total_size = sizeof(header_t) + size;
block = use_sbrk(user_t,total_size);
if (block == (void *) -1) return NULL;
header = block;
header->s.size = size;
header->s.is_free = 0;
header->s.next = NULL;
if (!user_t->head) user_t->head = header;
if (user_t->tail) user_t->tail->s.next = header;
user_t->tail = header;
return (void *) (header + 1);
}
void use_free(struct task_struct *user_t,void *block) {
header_t *header, *tmp;
if (!block) return;
header = (header_t *) block - 1;
if ((char *) block + header->s.size == user_t->program_break) {
if (user_t->head == user_t->tail) user_t->head = user_t->tail = NULL;
else {
tmp = user_t->head;
while (tmp) {
if (tmp->s.next == user_t->tail) {
tmp->s.next = NULL;
user_t->tail = tmp;
}
tmp = tmp->s.next;
}
}
use_sbrk(user_t,0 - sizeof(header_t) - header->s.size);
return;
}
header->s.is_free = 1;
}

View File

@ -9,6 +9,15 @@ idt_ptr_t idt_ptr;
extern void idt_flush(uint32_t);
void idt_use_reg(uint8_t num,uint32_t base){
idt_entries[num].base_low = base & 0xFFFF;
idt_entries[num].base_high = (base >> 16) & 0xFFFF; // 拆成低位和高位
idt_entries[num].sel = 0x08;
idt_entries[num].always0 = 0;
idt_entries[num].flags = 0x8E | 0x60;
}
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
idt_entries[num].base_low = base & 0xFFFF;
idt_entries[num].base_high = (base >> 16) & 0xFFFF; // 拆成低位和高位

View File

@ -18,12 +18,16 @@
#include "../include/vfs.h"
#include "../include/fat.h"
#include "../include/iso9660.h"
#include "../include/panic.h"
#include "../include/mouse.h"
#include "../include/desktop.h"
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
extern uint32_t end;
extern int status;
extern vdisk vdisk_ctl[10];
extern bool hasFS;
uint32_t placement_address = (uint32_t) & end;
void reset_kernel(){
@ -38,6 +42,8 @@ void shutdown_kernel(){
kill_all_task();
clock_sleep(10);
power_off();
}
uint32_t memory_all(){
@ -70,59 +76,72 @@ void kernel_main(multiboot_t *multiboot) {
}
initVBE(multiboot);
printf("[kernel]: VBE driver load success!\n");
printf("CPOS_Kernel %s (GRUB Multiboot) on an i386.\n",OS_VERSION);
printf("Memory Size: %dMB\n",(multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1);
printf("Graphics[ width: %d | height: %d | address: %08x ]\n",multiboot->framebuffer_width,multiboot->framebuffer_height,multiboot->framebuffer_addr);
gdt_install();
idt_install();
printf("[kernel]: description table config success!\n");
init_timer(1);
acpi_install();
printf("[kernel]: ACPI enable success!\n");
init_page(multiboot);
printf("[kernel]: page set success!\n");
init_sched();
printf("[kernel]: task load success!\n");
init_keyboard();
printf("[kernel]: Keyboard driver load success!\n");
init_pit();
io_sti();
init_pci();
printf("[kernel]: PCI driver load success!\n");
init_vdisk();
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000);
printf("[kernel]: Disk driver load success!\n");
init_vfs();
Register_fat_fileSys();
printf("iso\n");
init_iso9660();
printf("[kernel]: FileSystem load success!\n");
syscall_install();
char disk_id = '0';
for (int i = 0; i < 10; i++) {
if (vdisk_ctl[i].flag) {
vdisk vd = vdisk_ctl[i];
char id = i + ('A');
vfs_mount_disk(id,id);
if(vfs_mount_disk(id,id)){
disk_id = id;
klogf(true,"Mount disk: %c\n",disk_id);
}
}
}
init_eh();
hasFS = false;
if(disk_id != '0'){
if(vfs_change_disk(disk_id)){
klogf(true,"Chang default mounted disk.\n");
hasFS = true;
}
} else klogf(false,"Unable to find available IDE devices.\n");
//vfs_mount_disk('A','A');
if(vfs_change_disk('A'))
printf("[FileSystem]: Change disk win!\n");
if(pcnet_find_card()){
bool pcnet_init = pcnet_find_card();
klogf(pcnet_init,"Enable network device pcnet.\n");
if(pcnet_init){
//init_pcnet_card();
} else printf("[kernel]: Cannot found pcnet.\n");
print_cpu_id();
}
klogf(true,"Kernel load done!\n");
printf("\n\n");
clock_sleep(25);
int pid = kernel_thread(setup_shell, NULL, "CPOS-Shell");
kernel_thread(check_task,&pid,"CPOS-SHELL-CHECK");
// vfs_change_disk('B');
vfs_change_path("apps");
user_process("init.bin","User-Init");
user_process("service.bin","Service");
print_proc();
//menu_sel();
//uint32_t pid = kernel_thread(setup_shell,NULL,"CPOS-Shell");
//kernel_thread(check_task,&pid,"CPOS-SC");
//panic_pane("Proccess out of memory error!",OUT_OF_MEMORY);
for (;;) {
io_hlt();

View File

@ -1,10 +1,13 @@
#include "../include/memory.h"
#include "../include/task.h"
#include "../include/printf.h"
header_t *head = NULL, *tail = NULL; // 内存块链表
extern page_directory_t *current_directory;
extern uint32_t end; // declared in linker.ld
static uint32_t placement_address = (uint32_t) &end;
void *program_break, *program_break_end;
extern struct task_struct *current;
uint32_t memory_usage(){
header_t *curr = head;
@ -36,7 +39,7 @@ static uint32_t kmalloc_int(size_t sz, uint32_t align, uint32_t *phys) {
void *addr = alloc(sz); // 直接mallocalign丢掉了
if (phys) {
// 需要物理地址,先找到对应页
page_t *page = get_page((uint32_t) addr, 0, current_directory);
page_t *page = get_page((uint32_t) addr, 0, current_directory,false);
*phys = page->frame * 0x1000 + ((uint32_t) addr & 0x00000FFF);
}
return (uint32_t) addr;
@ -113,7 +116,6 @@ void kfree(void *block) {
header_t *header, *tmp;
if (!block) return;
header = (header_t *) block - 1;
if ((char *) block + header->s.size == program_break) {
if (head == tail) head = tail = NULL;
else {

View File

@ -51,7 +51,9 @@ uint32_t first_frame() {
}
void alloc_frame(page_t *page, int is_kernel, int is_writable) {
if (page->frame) return;
if (page->present) {
return;
}
else {
uint32_t idx = first_frame();
if (idx == (uint32_t) - 1) {
@ -61,6 +63,7 @@ void alloc_frame(page_t *page, int is_kernel, int is_writable) {
}
set_frame(idx * 0x1000);
memset(page,0,4);
page->present = 1; // 现在这个页存在了
page->rw = is_writable ? 1 : 0; // 是否可写由is_writable决定
page->user = is_kernel ? 0 : 1; // 是否为用户态由is_kernel决定
@ -93,12 +96,9 @@ void page_flush(page_directory_t *dir){
}
void page_switch(page_directory_t *dir){
io_cli();
current_directory = dir;
logkf("TablePhy: %08x | KERPhy: %08x\n",(&dir->tablesPhysical),kernel_directory->tablesPhysical);
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical)); // 设置cr3寄存器切换页表
logk("Switch directory win!\n");
io_sti();
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical));
}
void switch_page_directory(page_directory_t *dir) {
@ -111,17 +111,23 @@ void switch_page_directory(page_directory_t *dir) {
asm volatile("mov %0, %%cr0" : : "r"(cr0));
}
page_t *get_page(uint32_t address, int make, page_directory_t *dir) {
page_t *get_page(uint32_t address, int make, page_directory_t *dir,bool ist) {
address /= 0x1000;
uint32_t table_idx = address / 1024;
if (dir->tables[table_idx]) return &dir->tables[table_idx]->pages[address % 1024];
if (dir->tables[table_idx]){
page_t *pgg = &dir->tables[table_idx]->pages[address % 1024];
return pgg;
}
else if (make) {
uint32_t tmp;
dir->tables[table_idx] = (page_table_t *) kmalloc_ap(sizeof(page_table_t), &tmp);
dir->tables[table_idx] = (page_table_t *) kmalloc_i_ap(sizeof(page_table_t), &tmp);
memset(dir->tables[table_idx], 0, 0x1000);
dir->tablesPhysical[table_idx] = tmp | 0x7;
return &dir->tables[table_idx]->pages[address % 1024];
page_t *pgg = &dir->tables[table_idx]->pages[address % 1024];
return pgg;
} else return 0;
}
@ -141,11 +147,11 @@ void page_fault(registers_t *regs) {
if (present) {
printf("Type: present;\n\taddress: %x \n", faulting_address);
} else if (rw) {
printf("Type: read-only;\n\taddress: %x", faulting_address);
printf("Type: read-only;\n\taddress: %x\n", faulting_address);
} else if (us) {
printf("Type: user-mode;\n\taddres: %x", faulting_address);
printf("Type: user-mode;\n\taddres: %x\n", faulting_address);
} else if (reserved) {
printf("Type: reserved;\n\taddress: %x", faulting_address);
printf("Type: reserved;\n\taddress: %x\n", faulting_address);
} else if (id) {
printf("Type: decode address;\n\taddress: %x\n", faulting_address);
}
@ -162,7 +168,7 @@ void page_fault(registers_t *regs) {
}
static page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) {
page_table_t *table = (page_table_t *) kmalloc_ap(sizeof(page_table_t), physAddr);
page_table_t *table = (page_table_t *) kmalloc_i_ap(sizeof(page_table_t), physAddr);
memset(table, 0, sizeof(page_directory_t));
int i;
@ -220,25 +226,35 @@ void init_page(multiboot_t *mboot) {
while (i < placement_address + 0x30000) {
// 内核部分对ring3而言可读不可写 | 无偏移页表映射
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
alloc_frame(get_page(i, 1, kernel_directory,false), 1, 1);
i += 0x1000;
}
unsigned int j = mboot->framebuffer_addr,size = mboot->framebuffer_height * mboot->framebuffer_width*mboot->framebuffer_bpp;
while (j <= mboot->framebuffer_addr + size){
alloc_frame_line(get_page(j,1,kernel_directory),j,0,0);
alloc_frame_line(get_page(j,1,kernel_directory,false),j,1,1);
j += 0x1000;
}
for (int i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i++) {
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
alloc_frame(get_page(i, 1, kernel_directory,false), 1, 1);
}
register_interrupt_handler(14, page_fault);
switch_page_directory(clone_directory(kernel_directory));
switch_page_directory(kernel_directory);
program_break = (void *) KHEAP_START;
program_break_end = (void *) (KHEAP_START + KHEAP_INITIAL_SIZE);
klogf(true,"Memory manager is enable\n"
"Kernel: 0x00 - 0x%08x "
"Framebuffer: 0x%08x - 0x%08x "
"KernelHeap: 0x%08x - 0x%08x "
"BaseFrame: 0x%08x\n",
placement_address + 0x30000,
mboot->framebuffer_addr,mboot->framebuffer_addr + size,
KHEAP_START,KHEAP_START + KHEAP_INITIAL_SIZE,
frames);
}

89
src/kernel/panic.c Normal file
View File

@ -0,0 +1,89 @@
#include "../include/panic.h"
#include "../include/task.h"
#include "../include/isr.h"
#include "../include/io.h"
#include "../include/printf.h"
#include "../include/bmp.h"
#include "../include/vfs.h"
#include "../include/timer.h"
#include "../include/graphics.h"
#include "../include/acpi.h"
extern struct task_struct *current;
extern uint32_t *screen;
extern uint32_t back_color;
extern uint32_t color;
extern int32_t cx;
extern int32_t cy;
extern uint32_t c_width;
extern uint32_t c_height;
Bmp *panic_bmp;
static GP_13(registers_t *reg){
if(current->pid == 0){
printf("Kernel PANIC(#GP), Please restart your CPOS Kernel.\n");
while(1) io_hlt();
}else {
task_kill(current->pid);
}
}
static UD_6(registers_t *reg){
if(current->pid == 0){
printf("Kernel PANIC(#GP), Please restart your CPOS Kernel.\n");
while(1) io_hlt();
}else {
task_kill(current->pid);
}
}
void panic_pane(char* msg,enum PANIC_TYPE type){
io_cli();
kill_all_task();
back_color = 0x1e90ff;
color = 0xffffff;
screen_clear();
if(panic_bmp != NULL)
display(panic_bmp,0,0,true);
cx = 10;
cy = c_height - 10;
register uint32_t ebx asm("ebx");
register uint32_t ecx asm("ecx");
printf("%s: %s\n",type == ILLEGAL_KERNEL_STATUS ? "ILLEGAL_KERNEL_STATUS" : (type == OUT_OF_MEMORY ? "OUT_OF_MEMORY" :(type == KERNEL_PAGE_FAULT ? "KERNEL_PAGE_FAULT" : "UNKOWN_ERROR")),msg);
cx = 10;
printf("EAX: %08x | EBX: %08x | ECX: %08x | ESP: %08x | EBP: %08x | EDI: %08x | ESI: %08x\n",current,ebx,ecx,current->context.esp
,current->context.ebp,current->context.edi,current->context.esi);
printf("\n\n");
cx = 10;
printf("Restarting your system...\n");
for (int i = 90; i < 1200; i++) {
for (int j = 650; j < 670; j++) {
drawPixel(i,j,0xffffff);
}
sleep(1);
}
sleep(100);
power_reset();
while (1) io_hlt();
}
void init_eh(){
register_interrupt_handler(13,GP_13);
register_interrupt_handler(6,UD_6);
if(vfs_change_disk('B')){
uint32_t size = vfs_filesize("panic.bmp");
panic_bmp = NULL;
if(size == -1){
klogf(false,"Enable graphics user interface panic.\n");
} else{
Bmp *bmp = kmalloc(size);
vfs_readfile("panic.bmp",bmp);
panic_bmp = bmp;
klogf(true,"Enable graphics user interface panic.\n");
}
}
}

View File

@ -1,32 +1,16 @@
#include "../include/syscall.h"
#include "../include/printf.h"
#include "../include/isr.h"
#include "../include/description_table.h"
#include "../include/graphics.h"
void syscall_handler(registers_t *regs){
if (regs->eax >= SYSCALL_NUM)
return;
void *location = NULL;//syscalls[regs->eax];
printf("Syscall Win: %08x\n",regs->eax);
int ret;
asm volatile (" \
push %1; \
push %2; \
push %3; \
push %4; \
push %5; \
call *%6; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
" : "=a" (ret) : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (location));
regs->eax = ret;
void syscall_handler(registers_t regs){
if(regs.eax == 0x01){
putchar((regs.edx));
}
return;
}
void syscall_install(){
register_interrupt_handler(0x80,syscall_handler);
idt_use_reg(80, syscall_handler);
}

View File

@ -3,6 +3,15 @@
#include "../include/graphics.h"
#include "../include/io.h"
#include "../include/description_table.h"
#include "../include/vfs.h"
#include "../include/timer.h"
#include "../include/shell.h"
#include "../include/heap.h"
#include "../include/elf.h"
#define SA_RPL_MASK 0xFFFC
#define SA_TI_MASK 0xFFFB
#define GET_SEL(cs, rpl) ((cs & SA_RPL_MASK & SA_TI_MASK) | (rpl))
struct task_struct *running_proc_head = NULL;
struct task_struct *wait_proc_head = NULL;
@ -13,139 +22,143 @@ extern page_directory_t *kernel_directory;
extern void switch_to(struct context *prev, struct context *next);
int now_pid = 0;
int can_sche = 1;
struct task_struct* get_current(){
struct task_struct *get_current() {
return current;
}
void print_proc_t(int *i,struct task_struct *base,struct task_struct *cur,int is_print){
if(cur->pid == base->pid){
if(is_print){
void print_proc_t(int *i, struct task_struct *base, struct task_struct *cur, int is_print) {
if (cur->pid == base->pid) {
if (is_print) {
switch (cur->state) {
case TASK_RUNNABLE:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Running");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Running");
break;
case TASK_SLEEPING:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Sleeping");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Sleeping");
break;
case TASK_UNINIT:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Init");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Init");
break;
case TASK_ZOMBIE:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Zombie");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Zombie");
break;
case TASK_DEATH:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Death");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Death");
break;
}
}
(*i)++;
} else{
if(is_print){
} else {
if (is_print) {
switch (cur->state) {
case TASK_RUNNABLE:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Running");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Running");
break;
case TASK_SLEEPING:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Sleeping");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Sleeping");
break;
case TASK_UNINIT:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Init");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Init");
break;
case TASK_ZOMBIE:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Zombie");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Zombie");
break;
case TASK_DEATH:
printf("%-17s %-2d %s\n",cur->name,cur->pid,"Death");
printf("%-17s %-2d %s %d\n", cur->name, cur->pid, "Death");
break;
}
}
(*i)++;
print_proc_t(i,base,cur->next,is_print);
print_proc_t(i, base, cur->next, is_print);
}
}
int get_procs(){
int get_procs() {
int index = 0;
print_proc_t(&index,current,current->next,0);
print_proc_t(&index, current, current->next, 0);
return index;
}
void print_proc(){
void print_proc() {
int index = 0;
print_proc_t(&index,current,current->next,1);
print_proc_t(&index, current, current->next, 1);
printf("====---------------[Processes]----------------====\n");
printf("Name Pid Status [All Proc: %d]\n\n",index);
printf("Name Pid Status MemUsage [All Proc: %d]\n\n", index);
}
static void found_task(int pid,struct task_struct *head,struct task_struct *base,struct task_struct **argv,int first){
static void
found_task(int pid, struct task_struct *head, struct task_struct *base, struct task_struct **argv, int first) {
struct task_struct *t = base;
if(t == NULL){
if (t == NULL) {
argv = NULL;
return;
}
if(t->pid == pid){
if (t->pid == pid) {
*argv = t;
return;
} else{
if(!first)
if(head->pid == t->pid){
} else {
if (!first)
if (head->pid == t->pid) {
argv = NULL;
return;
}
found_task(pid,head,t->next,argv,0);
found_task(pid, head, t->next, argv, 0);
}
}
struct task_struct* found_task_pid(int pid){
struct task_struct *found_task_pid(int pid) {
struct task_struct *argv = NULL;
found_task(pid,running_proc_head,running_proc_head,&argv,1);
if(argv == NULL){
printf("Cannot found task Pid:[%d].\n",pid);
found_task(pid, running_proc_head, running_proc_head, &argv, 1);
if (argv == NULL) {
printf("Cannot found task Pid:[%d].\n", pid);
return NULL;
}
return argv;
}
void wait_task(struct task_struct *task){
void wait_task(struct task_struct *task) {
task->state = TASK_SLEEPING;
}
void start_task(struct task_struct *task){
void start_task(struct task_struct *task) {
task->state = TASK_RUNNABLE;
}
void task_kill(int pid){
void task_kill(int pid) {
io_cli();
struct task_struct *argv = found_task_pid(pid);
if(argv == NULL){
printf("Cannot found task Pid:[%d].\n",pid);
if (argv == NULL) {
printf("Cannot found task Pid:[%d].\n", pid);
return;
}
if(argv->pid == 0){
printf("[\033kernel\036]: Taskkill cannot terminate kernel processes.\n");
if (argv->pid == 0) {
printf("\033ff3030;[kernel]: Taskkill cannot terminate kernel processes.\033c6c6c6;\n");
return;
}
argv->state = TASK_DEATH;
printf("Taskkill process PID:%d Name:%s\n", current->pid, current->name);
printf("Task [%s] exit code: -130.\n",argv->name);
printf("Task [%s] exit code: -130.\n", argv->name);
io_sti();
kfree(argv);
struct task_struct *head = running_proc_head;
struct task_struct *last = NULL;
while (1){
if(head->pid == argv->pid){
while (1) {
if (head->pid == argv->pid) {
last->next = argv->next;
io_sti();
return;
}
last = head;
head = head->next;
}
io_cli();
}
void schedule() {
if (current) {
if(current->next->state == TASK_SLEEPING){
if (current && can_sche) {
if (current->next->state == TASK_SLEEPING) {
change_task_to(current->next->next);
return;
}
@ -159,22 +172,122 @@ void change_task_to(struct task_struct *next) {
current = next;
page_switch(current->pgd_dir);
set_kernel_stack(current->stack);
set_kernel_stack(current->stack + STACK_SIZE); // 没有 TSACK_SIZE
switch_to(&(prev->context), &(current->context));
}
}
void n() {
printf("Hello! User!\n");
for(;;);
}
int32_t user_process(char *path, char *name){
can_sche = 0;
if(path == NULL){
printf("Cannot create process! exec path is NULL\n");
return -1;
}
uint32_t size = vfs_filesize(path);
if(size == -1){
printf("Cannot font exec file\n");
return -1;
}
io_cli();
int32_t kernel_thread(int (*fn)(void *), void *arg,char* name) {
struct task_struct *new_task = (struct task_struct *) kmalloc(STACK_SIZE);
assert(new_task != NULL, "kern_thread: kmalloc error");
assert(new_task != NULL, "user_pcb: kmalloc error");
// 将栈低端结构信息初始化为 0
memset(new_task,0, sizeof(struct task_struct));
memset(new_task, 0, sizeof(struct task_struct));
new_task->state = TASK_RUNNABLE;
new_task->stack = current;
new_task->pid = now_pid++;
new_task->pgd_dir = clone_directory(current->pgd_dir) ;
page_directory_t *page = clone_directory(kernel_directory);
new_task->pgd_dir = page;
new_task->mem_size = 0;
new_task->program_break = USER_START;
new_task->program_break_end = USER_HEAP_END;
new_task->name = name;
new_task->isUser = 1;
io_sti();
page_switch(page);
for (int i = USER_START; i < USER_END;i++) {
page_t *pg = get_page(i,1,page, false);
alloc_frame(pg,0,1);
}
char* buffer = user_alloc(new_task,size);
memset(buffer,0,size);
vfs_readfile(path,buffer);
Elf32_Ehdr *ehdr = buffer;
if(!elf32Validate(ehdr)){
printf("Unknown exec file format.\n");
return -1;
}
uint32_t main = load_elf(ehdr,page);
printf("Main ADDRESS: %08x\n",main);
uint32_t *stack_top = (uint32_t * )((uint32_t) new_task + STACK_SIZE);
*(--stack_top) = (uint32_t) main;
*(--stack_top) = (uint32_t) kthread_exit;
*(--stack_top) = (uint32_t) switch_to_user_mode;
new_task->context.esp = (uint32_t) new_task + STACK_SIZE - sizeof(uint32_t) * 3;
// 设置新任务的标志寄存器未屏蔽中断,很重要
new_task->context.eflags = 0x200;
new_task->next = running_proc_head;
page_switch(kernel_directory);
// 找到当前进任务队列,插入到末尾
struct task_struct *tailt = running_proc_head;
assert(tailt != NULL, "Must init sched!");
while (tailt->next != running_proc_head) {
tailt = tailt->next;
}
tailt->next = new_task;
can_sche = 1;
io_sti();
return new_task->pid;
}
int32_t kernel_thread(int (*fn)(void *), void *arg, char *name) {
io_cli();
struct task_struct *new_task = (struct task_struct *) kmalloc(STACK_SIZE);
assert(new_task != NULL, "kern_thread: kmalloc error");
// 将栈低端结构信息初始化为 0
memset(new_task, 0, sizeof(struct task_struct));
new_task->state = TASK_RUNNABLE;
new_task->stack = current;
new_task->pid = now_pid++;
new_task->pgd_dir = kernel_directory;
new_task->mem_size = 0;
new_task->isUser = 0;
extern header_t *head;
extern header_t *tail;
extern void *program_break;
extern void *program_break_end;
current->head = head;
current->tail = tail;
current->program_break = program_break;
current->program_break_end = program_break_end;
new_task->name = name;
@ -191,14 +304,14 @@ int32_t kernel_thread(int (*fn)(void *), void *arg,char* name) {
new_task->next = running_proc_head;
// 找到当前进任务队列,插入到末尾
struct task_struct *tail = running_proc_head;
assert(tail != NULL, "Must init sched!");
struct task_struct *tailt = running_proc_head;
assert(tailt != NULL, "Must init sched!");
while (tail->next != running_proc_head) {
tail = tail->next;
while (tailt->next != running_proc_head) {
tailt = tailt->next;
}
tail->next = new_task;
tailt->next = new_task;
io_sti();
return new_task->pid;
}
@ -209,18 +322,64 @@ void kthread_exit() {
while (1);
}
void kill_all_task(){
void kill_all_task() {
struct task_struct *head = running_proc_head;
while (1){
while (1) {
head = head->next;
if(head == NULL || head->pid == running_proc_head->pid){
if (head == NULL || head->pid == running_proc_head->pid) {
return;
}
if(head->pid == current->pid) continue;
if (head->pid == current->pid) continue;
task_kill(head->pid);
}
}
#define SA_RPL3 3
void A() {
printf("USE3 HELLO!\n");
asm("hlt");
for(;;);
}
void switch_to_user_mode(uint32_t func) {
io_cli();
set_kernel_stack(current->stack + STACK_SIZE);
unsigned esp = USER_END;
current->context.eflags = (0 << 12 | 0b10 | 1 << 9);
intr_frame_t iframe;
iframe.edi = 1;
iframe.esi = 2;
iframe.ebp = 3;
iframe.esp_dummy = 4;
iframe.ebx = 5;
iframe.edx = 6;
iframe.ecx = 7;
iframe.eax = 8;
iframe.gs = GET_SEL(4 * 8, SA_RPL3);
iframe.ds = GET_SEL(4 * 8, SA_RPL3);
iframe.es = GET_SEL(4 * 8, SA_RPL3);
iframe.fs = GET_SEL(4 * 8, SA_RPL3);
iframe.ss = GET_SEL(4 * 8, SA_RPL3);
iframe.cs = GET_SEL(3 * 8, SA_RPL3);
iframe.eip = func; //用户可执行程序入口
iframe.eflags = (0 << 12 | 0b10 | 1 << 9);
iframe.esp = esp; // 设置用户态堆栈
intr_frame_t *a = &iframe;
asm volatile("movl %0, %%esp\n"
"popa\n"
"pop %%gs\n"
"pop %%fs\n"
"pop %%es\n"
"pop %%ds\n"
"iret" ::"m"(a));
}
void init_sched() {
// 为当前执行流创建信息结构体 该结构位于当前执行流的栈最低端
current = (struct task_struct *) kmalloc(sizeof(struct task_struct));
@ -230,8 +389,19 @@ void init_sched() {
current->stack = current; // 该成员指向栈低地址
current->pgd_dir = kernel_directory;
current->name = "CPOS-System";
current->mem_size = 0;
current->next = current;
current->isUser = 0;
extern header_t *head;
extern header_t *tail;
extern void *program_break;
extern void *program_break_end;
current->head = head;
current->tail = tail;
current->program_break = program_break;
current->program_break_end = program_break_end;
running_proc_head = current;
klogf(true,"Load task schedule. | KernelTaskName: %s PID: %d\n",current->name,current->pid);
}

View File

@ -58,7 +58,6 @@ void init_pit(void) {
}
void init_timer(uint32_t timer) {
printf("REG TIMER INT: %d, function address: %08x.\n",IRQ0, &timer_handle);
register_interrupt_handler(IRQ0, &timer_handle);
uint32_t divisor = 1193180 / timer;

5
src/sysapp/desktop.c Normal file
View File

@ -0,0 +1,5 @@
#include "../include/desktop.h"
void menu_sel(){
}

View File

@ -1 +0,0 @@
#include "../include/panic.h"

View File

@ -12,6 +12,7 @@
extern Queue *key_char_queue;
extern vdisk vdisk_ctl[10];
extern bool hasFS;
char getc() {
while (key_char_queue->size == 0x00) {
@ -134,6 +135,11 @@ void cmd_mkdir(int argc, char **argv) {
return;
}
if(!hasFS){
printf("Cannot find fs in this disk.\n");
return;
}
vfs_file *file = get_cur_file(argv[1]);
if(file != NULL){
@ -152,6 +158,11 @@ void cmd_del(int argc, char **argv) {
return;
}
if(!hasFS){
printf("Cannot find fs in this disk.\n");
return;
}
vfs_file *file = get_cur_file(argv[1]);
if(file == NULL){
@ -213,6 +224,10 @@ void cmd_cd(int argc, char **argv) {
print("[Shell-CD]: If there are too few parameters, please specify the path.\n");
return;
}
if(!hasFS){
printf("Cannot find fs in this disk.\n");
return;
}
if (vfs_change_path(argv[1]) == 0) printf("Invalid path.\n");
}
@ -229,6 +244,11 @@ void cmd_type(int argc,char ** argv){
print("[Shell-TYPE]: If there are too few parameters, please specify the path.\n");
return;
}
if(!hasFS){
printf("Cannot find fs in this disk.\n");
return;
}
char *buffer;
buffer = (char*) kmalloc(vfs_filesize(argv[1]));
@ -335,7 +355,7 @@ void setup_shell() {
screen_clear();
printf("Welcome to %s %s (CPOS Kernel x86_64)\n"
printf("Welcome to %s %s (CPOS Kernel i386)\n"
"\n"
" * SourceCode: https://github.com/xiaoyi1212/CoolPotOS\n"
" * Website: https://github.com/plos-clan\n"
@ -360,7 +380,15 @@ void setup_shell() {
char *buffer[255];
while (1) {
vfs_getPath(buffer);
if(hasFS) vfs_getPath(buffer);
else{
buffer[0] = 'n';
buffer[1] = 'o';
buffer[2] = '_';
buffer[3] = 'f';
buffer[4] = 's';
buffer[5] = '\0';
}
printf("\03343cd80;%s@localhost: \0334169E1;%s\\\033c6c6c6;$ ", user1, buffer);
if (gets(com, MAX_COMMAND_LEN) <= 0) continue;
argc = cmd_parse(com, argv, ' ');
@ -414,6 +442,6 @@ void setup_shell() {
print("disk[list|<ID>|cg<ID>]List or view disks.\n");
print("cd <path> Change shell top directory.\n");
print("sb3 <name> Player a wav sound file.\n");
} else printf("\033[Shell]: Unknown command '%s'.\n", argv[0]);
} else printf("\033ff3030;[Shell]: Unknown command '%s'.\033c6c6c6;\n", argv[0]);
}
}

23
src/util/bmp.c Normal file
View File

@ -0,0 +1,23 @@
#include "../include/bmp.h"
#include "../include/graphics.h"
void display(Bmp *bmp,uint32_t x, uint32_t y, bool isTransparent) {
if (bmp->magic != 0x4d42 || bmp->bitsPerPixel != 24)
return;
uint8_t *data = (uint8_t *)bmp + bmp->bmpDataOffset;
for (uint32_t yOffset = 0; yOffset < bmp->frameHeight; ++yOffset) {
for (uint32_t xOffset = 0; xOffset < bmp->frameWidth; ++xOffset) {
uint32_t offset = (yOffset * bmp->frameWidth + xOffset) * 3;
uint8_t b = data[offset + 0];
uint8_t g = data[offset + 1];
uint8_t r = data[offset + 2];
uint32_t color = (r << 16) | (g << 8) | b;
if (isTransparent && color == 0)
continue;
drawPixel(x + xOffset, y + bmp->frameHeight - 1 - yOffset, color);
}
}
return;
}

56
src/util/elf.c Normal file
View File

@ -0,0 +1,56 @@
#include "../include/elf.h"
#include "../include/common.h"
#define MAX(a, b) a > b ? a : b
static uint32_t div_round_up(uint32_t num, uint32_t size) {
return (num + size - 1) / size;
}
bool elf32Validate(Elf32_Ehdr *hdr) {
return hdr->e_ident[EI_MAG0] == ELFMAG0 && hdr->e_ident[EI_MAG1] == ELFMAG1 &&
hdr->e_ident[EI_MAG2] == ELFMAG2 && hdr->e_ident[EI_MAG3] == ELFMAG3;
}
void load_segment(Elf32_Phdr *phdr,page_directory_t *pdt, void *elf) {
unsigned int p = div_round_up(phdr->p_memsz, 0x1000);
int d = phdr->p_paddr;
if (d & 0x00000fff) {
unsigned e = d + phdr->p_memsz;
d = d & 0xfffff000;
e &= 0xfffff000;
p = (e - d) / 0x1000 + 1;
}
for (unsigned i = 0; i < p; i++) {
alloc_frame(get_page(d + i * 0x1000,1,pdt,false),0,1);
}
memcpy(phdr->p_vaddr, elf + phdr->p_offset, phdr->p_filesz);
if (phdr->p_memsz > phdr->p_filesz) { // 这个是bss段
memset(phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
}
}
uint32_t load_elf(Elf32_Ehdr *hdr,page_directory_t *pdt) {
Elf32_Phdr *phdr = (Elf32_Phdr *)((uint32_t)hdr + hdr->e_phoff);
for (int i = 0; i < hdr->e_phnum; i++) {
load_segment(phdr,pdt, (void *)hdr);
phdr++;
}
return hdr->e_entry;
}
void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr) {
uint8_t *p = (uint8_t *)elfhdr;
for (int i = 0; i < elfhdr->e_shnum; i++) {
Elf32_Shdr *shdr =
(Elf32_Shdr *)(p + elfhdr->e_shoff + sizeof(Elf32_Shdr) * i);
if (shdr->sh_type != SHT_PROGBITS || !(shdr->sh_flags & SHF_ALLOC)) {
continue;
}
for (int i = 0; i < shdr->sh_size; i++) {
ptr[shdr->sh_addr + i] = p[shdr->sh_offset + i];
}
}
}

View File

@ -304,6 +304,20 @@ void printf(const char *formet, ...) {
va_end(ap);
}
void klogf(bool isok,char* fmt,...){
int len;
va_list ap;
va_start(ap, fmt);
char *buf[1024] = {0};
len = vsprintf(buf, fmt, ap);
if(isok){
printf("[ \03300ee76;OK\033c6c6c6; ]: %s",buf);
} else{
printf("[\033ee6363;FAILED\033c6c6c6;]: %s",buf);
}
}
void screen_clear(){
if(vbe_status){
vbe_clear();
@ -333,6 +347,6 @@ void logkf(char *formet,...){
}
void logk(char *message){
for (size_t i = 0; i < strlen(message); i++)
write_serial(message[i]);
for (size_t i = 0; i < strlen(message); i++);
//write_serial(message[i]);
}