大更新

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(): # 构建常用工具 def build_data(): # 构建常用工具
print("Building util source code...") print("Building util source code...")
for file in os.listdir(cd + dir_ + src + 'util'): 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) e = os.system(cmd)
if e != 0: if e != 0:
return -1 return -1
@ -132,7 +132,7 @@ def linker(): # 交叉编译链接
for file in os.listdir(cd + dir_ + 'target'): for file in os.listdir(cd + dir_ + 'target'):
source_file = source_file + " target" + dir_ + file source_file = source_file + " target" + dir_ + file
return os.system( 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(): def launch():

View File

@ -33,4 +33,5 @@ longjmp:
inc eax ; else: goto lable 1 inc eax ; else: goto lable 1
.1: ; let longjmp's ret addr as setjmp's ret addr .1: ; let longjmp's ret addr as setjmp's ret addr
mov [esp + 0], ecx ; ret addr = ecx = setjmp's next code 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 // check enable status
if (i < 300) { if (i < 300) {
printf("[acpi]: Enable ACPI\n");
return 0; return 0;
} else { } else {
printf("Counld't enable ACPI\n");
return -1; return -1;
} }
} }
@ -89,10 +87,8 @@ int acpi_disable() {
} }
if (i < 300) { if (i < 300) {
printf("ACPI Disable!\n");
return 0; return 0;
} else { } else {
printf("Could't disable ACPI\n");
return -1; return -1;
} }
} }
@ -140,7 +136,6 @@ void power_off() {
if (!SCI_EN) if (!SCI_EN)
return; return;
while (1) { while (1) {
printf("[acpi] send power off command!\n");
io_out16((uint32_t) PM1a_CNT, SLP_TYPa | SLP_EN); io_out16((uint32_t) PM1a_CNT, SLP_TYPa | SLP_EN);
if (!PM1b_CNT) { if (!PM1b_CNT) {
io_out16((uint32_t) PM1b_CNT, SLP_TYPb | SLP_EN); io_out16((uint32_t) PM1b_CNT, SLP_TYPb | SLP_EN);
@ -180,17 +175,12 @@ static void AcpiPowerInit() {
if (PM1b_ENABLE_REG == len) if (PM1b_ENABLE_REG == len)
PM1b_ENABLE_REG = 0; PM1b_ENABLE_REG = 0;
printf("[acpi]: Setting Power event listener...\n");
io_out16(PM1a_ENABLE_REG, (1 << 8)); io_out16(PM1a_ENABLE_REG, (1 << 8));
if (PM1b_ENABLE_REG) { if (PM1b_ENABLE_REG) {
io_out16((uint16_t) io_out16((uint16_t)
PM1b_ENABLE_REG, (uint8_t)(1 << 8)); 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); register_interrupt_handler(facp->SCI_INT, AcpiPowerHandler);
} }
@ -217,7 +207,6 @@ uint8_t *AcpiCheckRSDPtr(void *ptr) {
// check signature // check signature
if (!memcmp(sign, bptr, 8)) { if (!memcmp(sign, bptr, 8)) {
printf("[acpi] rsdp found at %0x\n", bptr);
rsdp_address = bptr; rsdp_address = bptr;
for (i = 0; i < sizeof(acpi_rsdptr_t); i++) { for (i = 0; i < sizeof(acpi_rsdptr_t); i++) {
check += *bptr; check += *bptr;
@ -255,7 +244,7 @@ static int AcpiSysInit() {
rsdt = (acpi_rsdt_t *) AcpiGetRSDPtr(); rsdt = (acpi_rsdt_t *) AcpiGetRSDPtr();
if (!rsdt || AcpiCheckHeader(rsdt, "RSDT") < 0) { if (!rsdt || AcpiCheckHeader(rsdt, "RSDT") < 0) {
printf("No ACPI\n"); printf("No ACPI\n");
return -1; return false;
} }
entrys = rsdt->length - HEADER_SIZE / 4; entrys = rsdt->length - HEADER_SIZE / 4;
@ -315,7 +304,7 @@ static int AcpiSysInit() {
} else { } else {
printf("[acpi] no found DSDT table\n"); printf("[acpi] no found DSDT table\n");
} }
return 0; return true;
} }
++p; ++p;
} }
@ -323,9 +312,8 @@ static int AcpiSysInit() {
} }
void acpi_install() { void acpi_install() {
AcpiSysInit(); klogf(AcpiSysInit(),"Load acpi driver.\n");
acpi_enable_flag = !acpi_enable(); acpi_enable_flag = !acpi_enable();
// power init
hpet_initialize(); hpet_initialize();
AcpiPowerInit(); AcpiPowerInit();
} }
@ -383,14 +371,10 @@ void hpet_initialize() {
printf("can not found acpi hpet table\n"); 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; hpetInfo = (HpetInfo *) hpet->hpetAddress.address;
uint32_t counterClockPeriod = hpetInfo->generalCapabilities >> 32; uint32_t counterClockPeriod = hpetInfo->generalCapabilities >> 32;
hpetPeriod = counterClockPeriod / 1000000; hpetPeriod = counterClockPeriod / 1000000;
hpetInfo->generalConfiguration |= 1; // 启用hpet 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: // 2- Disable IRQs:
ide_write(ATA_PRIMARY, ATA_REG_CONTROL, 2); ide_write(ATA_PRIMARY, ATA_REG_CONTROL, 2);
ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2); ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);
logk("w1\n");
// 3- Detect ATA-ATAPI Devices: // 3- Detect ATA-ATAPI Devices:
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
for (j = 0; j < 2; j++) { 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: // (I) Select Drive:
ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j << 4)); // Select Drive. ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j << 4)); // Select Drive.
sleep(1); // Wait 1ms for drive select to work. sleep(1); // Wait 1ms for drive select to work.
logk("I\n");
// (II) Send ATA Identify Command: // (II) Send ATA Identify Command:
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY); ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
sleep(1); // This function should be implemented in your OS. which waits sleep(1); // This function should be implemented in your OS. which waits
// for 1 ms. it is based on System Timer Device Driver. // for 1 ms. it is based on System Timer Device Driver.
logk("II\n");
// (III) Polling: // (III) Polling:
if (ide_read(i, ATA_REG_STATUS) == 0) if (ide_read(i, ATA_REG_STATUS) == 0)
continue; // If Status = 0, No Device. continue; // If Status = 0, No Device.
logk("III\n");
while (1) { while (1) {
logk("read ide....\n");
status = ide_read(i, ATA_REG_STATUS); status = ide_read(i, ATA_REG_STATUS);
logk("read ok\n");
if ((status & ATA_SR_ERR)) { if ((status & ATA_SR_ERR)) {
err = 1; err = 1;
break; break;
@ -101,7 +95,6 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
} }
// (IV) Probe for ATAPI Devices: // (IV) Probe for ATAPI Devices:
logk("IV\n");
if (err != 0) { if (err != 0) {
unsigned char cl = ide_read(i, ATA_REG_LBA1); unsigned char cl = ide_read(i, ATA_REG_LBA1);
unsigned char ch = ide_read(i, ATA_REG_LBA2); 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: // (V) Read Identification Space of the Device:
logk("V\n");
ide_read_buffer(i, ATA_REG_DATA, (unsigned int) ide_buf, 128); ide_read_buffer(i, ATA_REG_DATA, (unsigned int) ide_buf, 128);
// (VI) Read Device Parameters: // (VI) Read Device Parameters:
logk("VI\n");
ide_devices[count].Reserved = 1; ide_devices[count].Reserved = 1;
ide_devices[count].Type = type; ide_devices[count].Type = type;
ide_devices[count].Channel = i; 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)); *((unsigned int *) (ide_buf + ATA_IDENT_COMMANDSETS));
// (VII) Get Size: // (VII) Get Size:
logk("VII\n");
if (ide_devices[count].CommandSets & (1 << 26)) if (ide_devices[count].CommandSets & (1 << 26))
// Device uses 48-Bit Addressing: // Device uses 48-Bit Addressing:
ide_devices[count].Size = 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 // (VIII) String indicates model of device (like Western Digital HDD and
// SONY DVD-RW...): // SONY DVD-RW...):
logk("VIII\n");
for (k = 0; k < 40; k += 2) { for (k = 0; k < 40; k += 2) {
ide_devices[count].Model[k] = ide_buf[ATA_IDENT_MODEL + k + 1]; ide_devices[count].Model[k] = ide_buf[ATA_IDENT_MODEL + k + 1];
ide_devices[count].Model[k + 1] = ide_buf[ATA_IDENT_MODEL + k]; 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; vdisk vd;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
if (ide_devices[i].Reserved == 1) { if (ide_devices[i].Reserved == 1) {
/*
logkf(" %d Found %s Drive %dMB - %s\n", i, logkf(" %d Found %s Drive %dMB - %s\n", i,
(const char *[]) {"ATA", "ATAPI"}[ide_devices[i].Type], /* Type */ (const char *[]) {"ATA", "ATAPI"}[ide_devices[i].Type],
ide_devices[i].Size / 1024 / 2, /* Size */ ide_devices[i].Size / 1024 / 2,
ide_devices[i].Model); ide_devices[i].Model);
*/
strcpy(vd.DriveName, ide_devices[i].Model); strcpy(vd.DriveName, ide_devices[i].Model);
if(ide_devices[i].Type == IDE_ATAPI) { if(ide_devices[i].Type == IDE_ATAPI) {
vd.flag = 2; vd.flag = 2;
@ -175,7 +166,7 @@ void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
vd.Read = Read; vd.Read = Read;
vd.Write = Write; vd.Write = Write;
vd.size = ide_devices[i].Size; 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: // (II) Wait for BSY to be cleared:
// ------------------------------------------------- // -------------------------------------------------
logk("II\n");
int a = ide_read(channel, ATA_REG_STATUS); int a = ide_read(channel, ATA_REG_STATUS);
while (a & ATA_SR_BSY) { 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); a = ide_read(channel, ATA_REG_STATUS);
sleep(1); sleep(1);
} }
logk("II OK\n");
if (advanced_check) { if (advanced_check) {
unsigned char state = unsigned char state =
ide_read(channel, ATA_REG_STATUS); // Read Status Register. ide_read(channel, ATA_REG_STATUS); // Read Status Register.
// (III) Check For Errors: // (III) Check For Errors:
// ------------------------------------------------- // -------------------------------------------------
logk("III\n");
if (state & ATA_SR_ERR) if (state & ATA_SR_ERR)
return 2; // Error. return 2; // Error.
@ -356,7 +343,6 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
ide_write(channel, ATA_REG_CONTROL, ide_write(channel, ATA_REG_CONTROL,
channels[channel].nIEN = (ide_irq_invoked = 0x0) + 0x02); channels[channel].nIEN = (ide_irq_invoked = 0x0) + 0x02);
// (I) Select one from LBA28, LBA48 or CHS; // (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 if (lba >= 0x10000000) { // Sure Drive should support LBA in this case, or
// you are giving a wrong LBA. // you are giving a wrong LBA.
// LBA48: // 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. (63); // Head number is written to HDDEVSEL lower 4-bits.
} }
// (II) See if drive supports DMA or not; // (II) See if drive supports DMA or not;
logk("II\n");
dma = 0; // We don't support DMA dma = 0; // We don't support DMA
// (III) Wait if the drive is busy; // (III) Wait if the drive is busy;
logk("III\n");
while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY) { while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY) {
} // Wait if busy. } // Wait if busy.
// (IV) Select Drive from the controller; // (IV) Select Drive from the controller;
logk("IV\n");
if (lba_mode == 0) if (lba_mode == 0)
ide_write(channel, ATA_REG_HDDEVSEL, ide_write(channel, ATA_REG_HDDEVSEL,
0xA0 | (slavebit << 4) | head); // Drive & CHS. 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) if (lba_mode == 2 && dma == 1 && direction == 1)
cmd = ATA_CMD_WRITE_DMA_EXT; cmd = ATA_CMD_WRITE_DMA_EXT;
ide_write(channel, ATA_REG_COMMAND, cmd); // Send the Command. ide_write(channel, ATA_REG_COMMAND, cmd); // Send the Command.
logk("IV1\n");
if (dma) if (dma)
if (direction == 0); if (direction == 0);
// DMA Read. // DMA Read.
@ -457,7 +439,6 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
if (err = ide_polling(channel, 1)) if (err = ide_polling(channel, 1))
return err; // Polling, set error and exit if there is. 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++) { for (int h = 0; h < words; h++) {
unsigned short a = io_in16(bus); unsigned short a = io_in16(bus);
word_[i * words + h] = a; word_[i * words + h] = a;
@ -489,21 +470,17 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
} }
void ide_wait_irq() { void ide_wait_irq() {
logk("WAITING\n");
while (!ide_irq_invoked); while (!ide_irq_invoked);
ide_irq_invoked = 0; ide_irq_invoked = 0;
logk("IDE_WAIT_IRQ!\n");
} }
void ide_irq() { void ide_irq() {
logk("ide irq.\n");
ide_irq_invoked = 1; ide_irq_invoked = 1;
} }
unsigned char ide_atapi_read(unsigned char drive, unsigned int lba, unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
unsigned char numsects, unsigned short selector, unsigned char numsects, unsigned short selector,
unsigned int edi) { unsigned int edi) {
logk("cdrom read.\n");
unsigned int channel = ide_devices[drive].Channel; unsigned int channel = ide_devices[drive].Channel;
unsigned int slavebit = ide_devices[drive].Drive; unsigned int slavebit = ide_devices[drive].Drive;
unsigned int bus = channels[channel].base; 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); channels[channel].nIEN = ide_irq_invoked = 0x0);
// (I): Setup SCSI Packet: // (I): Setup SCSI Packet:
// ------------------------------------------------------------------ // ------------------------------------------------------------------
logk("CDROM I\n");
atapi_packet[0] = ATAPI_CMD_READ; atapi_packet[0] = ATAPI_CMD_READ;
atapi_packet[1] = 0x0; atapi_packet[1] = 0x0;
atapi_packet[2] = (lba >> 24) & 0xFF; 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: atapi_packet[11] = 0x0; // (II): Select the drive:
// ------------------------------------------------------------------ // ------------------------------------------------------------------
ide_write(channel, ATA_REG_HDDEVSEL, slavebit << 4); ide_write(channel, ATA_REG_HDDEVSEL, slavebit << 4);
logk("CDROM II\n");
// (III): Delay 400 nanoseconds for select to complete: // (III): Delay 400 nanoseconds for select to complete:
for (int i = 0; i < 4000; i++); for (int i = 0; i < 4000; i++);
logk("CDROM III\n");
// ------------------------------------------------------------------ // ------------------------------------------------------------------
logk("CDROM IV\n");
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
ide_read(channel, ide_read(channel,
ATA_REG_ALTSTATUS); // Reading the Alternate Status port wastes 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. 0); // PIO mode.
// (V): Tell the Controller the size of buffer: // (V): Tell the Controller the size of buffer:
// ------------------------------------------------------------------ // ------------------------------------------------------------------
logk("CDROM V\n");
ide_write(channel, ATA_REG_LBA1, ide_write(channel, ATA_REG_LBA1,
(words * 2) & 0xFF); // Lower Byte of Sector Size. (words * 2) & 0xFF); // Lower Byte of Sector Size.
ide_write(channel, ATA_REG_LBA2, 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: // (VIII): Sending the packet data:
// ------------------------------------------------------------------ // ------------------------------------------------------------------
logk("CDROM VIII\n");
uint16_t *_atapi_packet = atapi_packet; uint16_t *_atapi_packet = atapi_packet;
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
io_out16(bus, _atapi_packet[i]); io_out16(bus, _atapi_packet[i]);
} }
// (IX): Receiving Data: // (IX): Receiving Data:
// ------------------------------------------------------------------ // ------------------------------------------------------------------
logk("CDROM IX\n");
uint16_t *_word = edi; uint16_t *_word = edi;
for (i = 0; i < numsects; i++) { for (i = 0; i < numsects; i++) {
ide_wait_irq(); // Wait for an IRQ. ide_wait_irq(); // Wait for an IRQ.
if (err = ide_polling(channel, 1)) if (err = ide_polling(channel, 1))
return err; // Polling and return if error. return err; // Polling and return if error.
logkf("CDROM words = %d\n", words);
insl(bus, _word + i * words, words / 2); insl(bus, _word + i * words, words / 2);
} }
@ -609,7 +578,6 @@ void ide_read_sectors(unsigned char drive, unsigned char numsects,
else { else {
unsigned char err; unsigned char err;
if (ide_devices[drive].Type == IDE_ATA) { if (ide_devices[drive].Type == IDE_ATA) {
logk("Will Read.\n");
err = ide_ata_access(ATA_READ, drive, lba, numsects, es, edi); err = ide_ata_access(ATA_READ, drive, lba, numsects, es, edi);
} else if (ide_devices[drive].Type == IDE_ATAPI) } 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(){ void init_keyboard(){
key_status = (KEY_STATUS*) alloc(sizeof(KEY_STATUS)); key_status = (KEY_STATUS*) alloc(sizeof(KEY_STATUS));
if(key_status == NULL) goto error;
key_status->is_shift = 0; key_status->is_shift = 0;
key_char_queue = create_queue(); key_char_queue = create_queue();
head_listener = (struct key_listener*) kmalloc(sizeof(struct key_listener)); head_listener = (struct key_listener*) kmalloc(sizeof(struct key_listener));
if(head_listener == NULL) goto error;
head_listener->func = default_handle; head_listener->func = default_handle;
head_listener->lid = 0; head_listener->lid = 0;
head_listener->next = NULL; head_listener->next = NULL;
register_interrupt_handler(0x21,handle_keyboard_input); 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); unsigned char status = read_port(KEYBOARD_STATUS_PORT);
uint32_t key = read_port(KEYBOARD_DATA_PORT); uint32_t key = read_port(KEYBOARD_DATA_PORT);
int release = key & 0xb10000000; 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(){ void init_pci(){
printf("[\035kernel\036]: Loading pci device...\n");
int PCI_NUM = 0; int PCI_NUM = 0;
PCI_ADDR_BASE = kmalloc(1 * 1024 * 1024); PCI_ADDR_BASE = kmalloc(1 * 1024 * 1024);
@ -155,6 +154,5 @@ void init_pci(){
} }
} }
} }
klogf(true,"PCI device loaded: %d\n",PCI_NUM);
printf("[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() { void vbe_scroll() {
if (cx > c_width) { if (cx > c_width) {
cx = 0; cx = 0;
@ -198,7 +208,8 @@ void initVBE(multiboot_t *info) {
width = info->framebuffer_width; width = info->framebuffer_width;
height = info->framebuffer_height; height = info->framebuffer_height;
color = 0xc6c6c6; color = 0xc6c6c6;
back_color = 0x1c1c1c; //back_color = 0x1c1c1c;
back_color = 0x000000;
c_width = width / 9; c_width = width / 9;
c_height = height / 16; c_height = height / 16;

View File

@ -16,6 +16,7 @@ int init_vdisk() {
for (int i = 0; i < 26; i++) { for (int i = 0; i < 26; i++) {
vdisk_ctl[i].flag = 0; // 设置为未使用 vdisk_ctl[i].flag = 0; // 设置为未使用
} }
klogf(true,"VDisk interface initialize.\n");
} }
int register_vdisk(vdisk vd) { 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) { void file_loadfile(int clustno, int size, char *buf, int *fat, vfs_t *vfs) {
if (!size) { if (!size) {
return; return;
@ -168,15 +169,7 @@ void file_savefile(int clustno, int size, char *buf, int *fat,
} }
void *img = kmalloc(alloc_size); void *img = kmalloc(alloc_size);
memclean((char *)img, alloc_size); memclean((char *)img, alloc_size);
memcpy(img, buf, 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];
// }
int flag = 0, a, num = 0, sec_start = 0; int flag = 0, a, num = 0, sec_start = 0;
for (int i = 0; i != (alloc_size / get_dm(vfs).ClustnoBytes); i++) { for (int i = 0; i != (alloc_size / get_dm(vfs).ClustnoBytes); i++) {
uint32_t sec = (get_dm(vfs).FileDataAddress + uint32_t sec = (get_dm(vfs).FileDataAddress +

View File

@ -10,6 +10,7 @@
vfs_t vfsstl[26]; vfs_t vfsstl[26];
vfs_t vfsMount_Stl[26]; vfs_t vfsMount_Stl[26];
vfs_t *vfs_now; vfs_t *vfs_now;
bool hasFS;
static vfs_t *drive2fs(uint8_t drive) { static vfs_t *drive2fs(uint8_t drive) {
for (int i = 0; i < 26; i++) { 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) { 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++) { for (int i = 0; i < 26; i++) {
if (vfsMount_Stl[i].flag == 1 && if (vfsMount_Stl[i].flag == 1 &&
(vfsMount_Stl[i].drive == drive || (vfsMount_Stl[i].drive == drive ||
@ -95,6 +95,9 @@ bool vfs_mount_disk(uint8_t disk_number, uint8_t drive) {
seat->drive = drive; seat->drive = drive;
seat->disk_number = disk_number; seat->disk_number = disk_number;
seat->flag = 1; seat->flag = 1;
printf("Disk %c mount success!\n",disk_number);
return true; return true;
} }
@ -400,10 +403,10 @@ void init_vfs() {
// PDEBUG("Set vfsstl[%d] & vfsMount_Stl[%d] OK.", i, i); // PDEBUG("Set vfsstl[%d] & vfsMount_Stl[%d] OK.", i, i);
} }
vfs_now = NULL; vfs_now = NULL;
klogf(true,"Virtual File System initialize.\n");
} }
bool vfs_register_fs(vfs_t vfs) { bool vfs_register_fs(vfs_t vfs) {
printf("Register file system: %s\n", vfs.FSName);
vfs_t *seat; vfs_t *seat;
seat = findSeat(vfsstl); seat = findSeat(vfsstl);
if (!seat) { if (!seat) {
@ -411,5 +414,6 @@ bool vfs_register_fs(vfs_t vfs) {
return false; return false;
} }
*seat = vfs; *seat = vfs;
klogf(true,"Register file system: %s\n",vfs.FSName);
return true; 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 CRASHPOWEROS_COMMON_H
#define OS_NAME "CoolPotOS" #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_MAX 9223372036854775807L
#define LONG_MIN -9223372036854775808L #define LONG_MIN -9223372036854775808L

View File

@ -5,6 +5,8 @@
#define GDT_LENGTH 6 #define GDT_LENGTH 6
#define SA_RPL3 3
typedef struct gdt_entry_t { typedef struct gdt_entry_t {
uint16_t limit_low; // 段基址 | 低16位置 uint16_t limit_low; // 段基址 | 低16位置
uint16_t base_low; // 段基址 | 高16位置 uint16_t base_low; // 段基址 | 高16位置
@ -121,12 +123,38 @@ typedef struct tss_table {
uint16_t iomap_base; uint16_t iomap_base;
} tss_entry; } 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 write_tss(int32_t num, uint16_t ss0, uint32_t esp0);
void set_kernel_stack(uintptr_t stack); void set_kernel_stack(uintptr_t stack);
void set_tss_ss0(uintptr_t ss);
void gdt_install(); void gdt_install();
void idt_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); void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags);
#endif //CRASHPOWEROS_DESCRIPTION_TABLE_H #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 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 draw_rect(int x0, int y0, int x1, int y1, int c);
void initVBE(multiboot_t *multiboot); void initVBE(multiboot_t *multiboot);
void drawPixel(uint32_t x, uint32_t y, uint32_t color);
#endif #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" #include "isr.h"
#define KHEAP_INITIAL_SIZE 0xf00000 #define KHEAP_INITIAL_SIZE 0xf00000
#define KHEAP_START 0xc0000000 #define KHEAP_START 0xa0000000
#define STACK_SIZE 32768 #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 INDEX_FROM_BIT(a) (a / (8*4))
#define OFFSET_FROM_BIT(a) (a % (8*4)) #define OFFSET_FROM_BIT(a) (a % (8*4))
typedef char ALIGN[16]; typedef char ALIGN[16];
#include "multiboot.h" #include "multiboot.h"
#include "common.h"
typedef struct page { typedef struct page {
uint32_t present: 1; uint32_t present: 1;
@ -24,17 +32,17 @@ typedef struct page {
uint32_t dirty: 1; uint32_t dirty: 1;
uint32_t unused: 7; uint32_t unused: 7;
uint32_t frame: 20; uint32_t frame: 20;
} page_t; }__attribute__((packaged)) page_t;
typedef struct page_table { typedef struct page_table {
page_t pages[1024]; page_t pages[1024];
} page_table_t; }__attribute__((packaged)) page_table_t;
typedef struct page_directory { typedef struct page_directory {
page_table_t *tables[1024]; page_table_t *tables[1024];
uint32_t tablesPhysical[1024]; uint32_t tablesPhysical[1024];
uint32_t physicalAddr; uint32_t physicalAddr;
} page_directory_t; }__attribute__((packaged)) page_directory_t;
typedef union header { typedef union header {
struct { struct {
@ -57,7 +65,7 @@ void *memmove(void *dest, const void *src, size_t num);
void switch_page_directory(page_directory_t *dir); 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); 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 #ifndef CRASHPOWEROS_PANIC_H
#define 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 #endif

View File

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

View File

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

View File

@ -45,6 +45,10 @@ void set_kernel_stack(uintptr_t stack) {
tss.esp0 = stack; tss.esp0 = stack;
} }
void set_tss_ss0(uintptr_t ss){
tss.ss0 = ss;
}
void gdt_install() { void gdt_install() {
gdt_ptr.limit = sizeof(gdt_entry_t) * GDT_LENGTH - 1; gdt_ptr.limit = sizeof(gdt_entry_t) * GDT_LENGTH - 1;
gdt_ptr.base = (uint32_t)&gdt_entries; 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); 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) { 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_low = base & 0xFFFF;
idt_entries[num].base_high = (base >> 16) & 0xFFFF; // 拆成低位和高位 idt_entries[num].base_high = (base >> 16) & 0xFFFF; // 拆成低位和高位

View File

@ -18,12 +18,16 @@
#include "../include/vfs.h" #include "../include/vfs.h"
#include "../include/fat.h" #include "../include/fat.h"
#include "../include/iso9660.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))) #define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
extern uint32_t end; extern uint32_t end;
extern int status; extern int status;
extern vdisk vdisk_ctl[10]; extern vdisk vdisk_ctl[10];
extern bool hasFS;
uint32_t placement_address = (uint32_t) & end; uint32_t placement_address = (uint32_t) & end;
void reset_kernel(){ void reset_kernel(){
@ -38,6 +42,8 @@ void shutdown_kernel(){
kill_all_task(); kill_all_task();
clock_sleep(10); clock_sleep(10);
power_off(); power_off();
} }
uint32_t memory_all(){ uint32_t memory_all(){
@ -70,59 +76,72 @@ void kernel_main(multiboot_t *multiboot) {
} }
initVBE(multiboot); initVBE(multiboot);
printf("CPOS_Kernel %s (GRUB Multiboot) on an i386.\n",OS_VERSION);
printf("[kernel]: VBE driver load success!\n"); 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(); gdt_install();
idt_install(); idt_install();
printf("[kernel]: description table config success!\n");
init_timer(1); init_timer(1);
acpi_install(); acpi_install();
printf("[kernel]: ACPI enable success!\n");
init_page(multiboot); init_page(multiboot);
printf("[kernel]: page set success!\n");
init_sched(); init_sched();
printf("[kernel]: task load success!\n");
init_keyboard(); init_keyboard();
printf("[kernel]: Keyboard driver load success!\n");
init_pit(); init_pit();
io_sti(); io_sti();
init_pci(); init_pci();
printf("[kernel]: PCI driver load success!\n");
init_vdisk(); init_vdisk();
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000); ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000);
printf("[kernel]: Disk driver load success!\n");
init_vfs(); init_vfs();
Register_fat_fileSys(); Register_fat_fileSys();
printf("iso\n");
init_iso9660(); init_iso9660();
printf("[kernel]: FileSystem load success!\n");
syscall_install(); syscall_install();
char disk_id = '0';
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
if (vdisk_ctl[i].flag) { if (vdisk_ctl[i].flag) {
vdisk vd = vdisk_ctl[i]; vdisk vd = vdisk_ctl[i];
char id = i + ('A'); 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");
bool pcnet_init = pcnet_find_card();
//vfs_mount_disk('A','A'); klogf(pcnet_init,"Enable network device pcnet.\n");
if(vfs_change_disk('A')) if(pcnet_init){
printf("[FileSystem]: Change disk win!\n");
if(pcnet_find_card()){
//init_pcnet_card(); //init_pcnet_card();
} else printf("[kernel]: Cannot found pcnet.\n"); }
klogf(true,"Kernel load done!\n");
print_cpu_id(); printf("\n\n");
clock_sleep(25); clock_sleep(25);
int pid = kernel_thread(setup_shell, NULL, "CPOS-Shell"); // vfs_change_disk('B');
kernel_thread(check_task,&pid,"CPOS-SHELL-CHECK"); 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 (;;) { for (;;) {
io_hlt(); io_hlt();

View File

@ -1,10 +1,13 @@
#include "../include/memory.h" #include "../include/memory.h"
#include "../include/task.h"
#include "../include/printf.h"
header_t *head = NULL, *tail = NULL; // 内存块链表 header_t *head = NULL, *tail = NULL; // 内存块链表
extern page_directory_t *current_directory; extern page_directory_t *current_directory;
extern uint32_t end; // declared in linker.ld extern uint32_t end; // declared in linker.ld
static uint32_t placement_address = (uint32_t) &end; static uint32_t placement_address = (uint32_t) &end;
void *program_break, *program_break_end; void *program_break, *program_break_end;
extern struct task_struct *current;
uint32_t memory_usage(){ uint32_t memory_usage(){
header_t *curr = head; 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丢掉了 void *addr = alloc(sz); // 直接mallocalign丢掉了
if (phys) { 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); *phys = page->frame * 0x1000 + ((uint32_t) addr & 0x00000FFF);
} }
return (uint32_t) addr; return (uint32_t) addr;
@ -113,7 +116,6 @@ void kfree(void *block) {
header_t *header, *tmp; header_t *header, *tmp;
if (!block) return; if (!block) return;
header = (header_t *) block - 1; header = (header_t *) block - 1;
if ((char *) block + header->s.size == program_break) { if ((char *) block + header->s.size == program_break) {
if (head == tail) head = tail = NULL; if (head == tail) head = tail = NULL;
else { else {

View File

@ -51,7 +51,9 @@ uint32_t first_frame() {
} }
void alloc_frame(page_t *page, int is_kernel, int is_writable) { void alloc_frame(page_t *page, int is_kernel, int is_writable) {
if (page->frame) return; if (page->present) {
return;
}
else { else {
uint32_t idx = first_frame(); uint32_t idx = first_frame();
if (idx == (uint32_t) - 1) { 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); set_frame(idx * 0x1000);
memset(page,0,4);
page->present = 1; // 现在这个页存在了 page->present = 1; // 现在这个页存在了
page->rw = is_writable ? 1 : 0; // 是否可写由is_writable决定 page->rw = is_writable ? 1 : 0; // 是否可写由is_writable决定
page->user = is_kernel ? 0 : 1; // 是否为用户态由is_kernel决定 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){ void page_switch(page_directory_t *dir){
io_cli();
current_directory = dir; current_directory = dir;
logkf("TablePhy: %08x | KERPhy: %08x\n",(&dir->tablesPhysical),kernel_directory->tablesPhysical); asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical));
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical)); // 设置cr3寄存器切换页表
logk("Switch directory win!\n");
io_sti();
} }
void switch_page_directory(page_directory_t *dir) { 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)); 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; address /= 0x1000;
uint32_t table_idx = address / 1024; 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) { else if (make) {
uint32_t tmp; 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); memset(dir->tables[table_idx], 0, 0x1000);
dir->tablesPhysical[table_idx] = tmp | 0x7; 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; } else return 0;
} }
@ -141,11 +147,11 @@ void page_fault(registers_t *regs) {
if (present) { if (present) {
printf("Type: present;\n\taddress: %x \n", faulting_address); printf("Type: present;\n\taddress: %x \n", faulting_address);
} else if (rw) { } 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) { } 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) { } else if (reserved) {
printf("Type: reserved;\n\taddress: %x", faulting_address); printf("Type: reserved;\n\taddress: %x\n", faulting_address);
} else if (id) { } else if (id) {
printf("Type: decode address;\n\taddress: %x\n", faulting_address); 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) { 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)); memset(table, 0, sizeof(page_directory_t));
int i; int i;
@ -220,25 +226,35 @@ void init_page(multiboot_t *mboot) {
while (i < placement_address + 0x30000) { while (i < placement_address + 0x30000) {
// 内核部分对ring3而言可读不可写 | 无偏移页表映射 // 内核部分对ring3而言可读不可写 | 无偏移页表映射
alloc_frame(get_page(i, 1, kernel_directory), 0, 0); alloc_frame(get_page(i, 1, kernel_directory,false), 1, 1);
i += 0x1000; i += 0x1000;
} }
unsigned int j = mboot->framebuffer_addr,size = mboot->framebuffer_height * mboot->framebuffer_width*mboot->framebuffer_bpp; unsigned int j = mboot->framebuffer_addr,size = mboot->framebuffer_height * mboot->framebuffer_width*mboot->framebuffer_bpp;
while (j <= mboot->framebuffer_addr + size){ 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; j += 0x1000;
} }
for (int i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i++) { 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); 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 = (void *) KHEAP_START;
program_break_end = (void *) (KHEAP_START + KHEAP_INITIAL_SIZE); 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/syscall.h"
#include "../include/printf.h" #include "../include/printf.h"
#include "../include/isr.h" #include "../include/isr.h"
#include "../include/description_table.h"
#include "../include/graphics.h"
void syscall_handler(registers_t *regs){ void syscall_handler(registers_t regs){
if (regs->eax >= SYSCALL_NUM) if(regs.eax == 0x01){
return; putchar((regs.edx));
}
void *location = NULL;//syscalls[regs->eax]; return;
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_install(){ 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/graphics.h"
#include "../include/io.h" #include "../include/io.h"
#include "../include/description_table.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 *running_proc_head = NULL;
struct task_struct *wait_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); extern void switch_to(struct context *prev, struct context *next);
int now_pid = 0; int now_pid = 0;
int can_sche = 1;
struct task_struct* get_current(){ struct task_struct *get_current() {
return current; return current;
} }
void print_proc_t(int *i,struct task_struct *base,struct task_struct *cur,int 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 (cur->pid == base->pid) {
if(is_print){ if (is_print) {
switch (cur->state) { switch (cur->state) {
case TASK_RUNNABLE: 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; break;
case TASK_SLEEPING: 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; break;
case TASK_UNINIT: 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; break;
case TASK_ZOMBIE: 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; break;
case TASK_DEATH: 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; break;
} }
} }
(*i)++; (*i)++;
} else{ } else {
if(is_print){ if (is_print) {
switch (cur->state) { switch (cur->state) {
case TASK_RUNNABLE: 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; break;
case TASK_SLEEPING: 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; break;
case TASK_UNINIT: 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; break;
case TASK_ZOMBIE: 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; break;
case TASK_DEATH: 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; break;
} }
} }
(*i)++; (*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; int index = 0;
print_proc_t(&index,current,current->next,0); print_proc_t(&index, current, current->next, 0);
return index; return index;
} }
void print_proc(){ void print_proc() {
int index = 0; int index = 0;
print_proc_t(&index,current,current->next,1); print_proc_t(&index, current, current->next, 1);
printf("====---------------[Processes]----------------====\n"); 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; struct task_struct *t = base;
if(t == NULL){ if (t == NULL) {
argv = NULL; argv = NULL;
return; return;
} }
if(t->pid == pid){ if (t->pid == pid) {
*argv = t; *argv = t;
return; return;
} else{ } else {
if(!first) if (!first)
if(head->pid == t->pid){ if (head->pid == t->pid) {
argv = NULL; argv = NULL;
return; 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; struct task_struct *argv = NULL;
found_task(pid,running_proc_head,running_proc_head,&argv,1); found_task(pid, running_proc_head, running_proc_head, &argv, 1);
if(argv == NULL){ if (argv == NULL) {
printf("Cannot found task Pid:[%d].\n",pid); printf("Cannot found task Pid:[%d].\n", pid);
return NULL; return NULL;
} }
return argv; return argv;
} }
void wait_task(struct task_struct *task){ void wait_task(struct task_struct *task) {
task->state = TASK_SLEEPING; task->state = TASK_SLEEPING;
} }
void start_task(struct task_struct *task){ void start_task(struct task_struct *task) {
task->state = TASK_RUNNABLE; task->state = TASK_RUNNABLE;
} }
void task_kill(int pid){ void task_kill(int pid) {
io_cli();
struct task_struct *argv = found_task_pid(pid); struct task_struct *argv = found_task_pid(pid);
if(argv == NULL){ if (argv == NULL) {
printf("Cannot found task Pid:[%d].\n",pid); printf("Cannot found task Pid:[%d].\n", pid);
return; return;
} }
if(argv->pid == 0){ if (argv->pid == 0) {
printf("[\033kernel\036]: Taskkill cannot terminate kernel processes.\n"); printf("\033ff3030;[kernel]: Taskkill cannot terminate kernel processes.\033c6c6c6;\n");
return; return;
} }
argv->state = TASK_DEATH; argv->state = TASK_DEATH;
printf("Taskkill process PID:%d Name:%s\n", current->pid, current->name); 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(); io_sti();
kfree(argv); kfree(argv);
struct task_struct *head = running_proc_head; struct task_struct *head = running_proc_head;
struct task_struct *last = NULL; struct task_struct *last = NULL;
while (1){ while (1) {
if(head->pid == argv->pid){ if (head->pid == argv->pid) {
last->next = argv->next; last->next = argv->next;
io_sti();
return; return;
} }
last = head; last = head;
head = head->next; head = head->next;
} }
io_cli();
} }
void schedule() { void schedule() {
if (current) { if (current && can_sche) {
if(current->next->state == TASK_SLEEPING){ if (current->next->state == TASK_SLEEPING) {
change_task_to(current->next->next); change_task_to(current->next->next);
return; return;
} }
@ -159,22 +172,122 @@ void change_task_to(struct task_struct *next) {
current = next; current = next;
page_switch(current->pgd_dir); 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)); 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); 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 // 将栈低端结构信息初始化为 0
memset(new_task,0, sizeof(struct task_struct)); memset(new_task, 0, sizeof(struct task_struct));
new_task->state = TASK_RUNNABLE; new_task->state = TASK_RUNNABLE;
new_task->stack = current; new_task->stack = current;
new_task->pid = now_pid++; 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; 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; new_task->next = running_proc_head;
// 找到当前进任务队列,插入到末尾 // 找到当前进任务队列,插入到末尾
struct task_struct *tail = running_proc_head; struct task_struct *tailt = running_proc_head;
assert(tail != NULL, "Must init sched!"); assert(tailt != NULL, "Must init sched!");
while (tail->next != running_proc_head) { while (tailt->next != running_proc_head) {
tail = tail->next; tailt = tailt->next;
} }
tail->next = new_task; tailt->next = new_task;
io_sti();
return new_task->pid; return new_task->pid;
} }
@ -209,18 +322,64 @@ void kthread_exit() {
while (1); while (1);
} }
void kill_all_task(){ void kill_all_task() {
struct task_struct *head = running_proc_head; struct task_struct *head = running_proc_head;
while (1){ while (1) {
head = head->next; head = head->next;
if(head == NULL || head->pid == running_proc_head->pid){ if (head == NULL || head->pid == running_proc_head->pid) {
return; return;
} }
if(head->pid == current->pid) continue; if (head->pid == current->pid) continue;
task_kill(head->pid); 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() { void init_sched() {
// 为当前执行流创建信息结构体 该结构位于当前执行流的栈最低端 // 为当前执行流创建信息结构体 该结构位于当前执行流的栈最低端
current = (struct task_struct *) kmalloc(sizeof(struct task_struct)); current = (struct task_struct *) kmalloc(sizeof(struct task_struct));
@ -230,8 +389,19 @@ void init_sched() {
current->stack = current; // 该成员指向栈低地址 current->stack = current; // 该成员指向栈低地址
current->pgd_dir = kernel_directory; current->pgd_dir = kernel_directory;
current->name = "CPOS-System"; current->name = "CPOS-System";
current->mem_size = 0;
current->next = current; 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; 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) { void init_timer(uint32_t timer) {
printf("REG TIMER INT: %d, function address: %08x.\n",IRQ0, &timer_handle);
register_interrupt_handler(IRQ0, &timer_handle); register_interrupt_handler(IRQ0, &timer_handle);
uint32_t divisor = 1193180 / timer; 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 Queue *key_char_queue;
extern vdisk vdisk_ctl[10]; extern vdisk vdisk_ctl[10];
extern bool hasFS;
char getc() { char getc() {
while (key_char_queue->size == 0x00) { while (key_char_queue->size == 0x00) {
@ -134,6 +135,11 @@ void cmd_mkdir(int argc, char **argv) {
return; return;
} }
if(!hasFS){
printf("Cannot find fs in this disk.\n");
return;
}
vfs_file *file = get_cur_file(argv[1]); vfs_file *file = get_cur_file(argv[1]);
if(file != NULL){ if(file != NULL){
@ -152,6 +158,11 @@ void cmd_del(int argc, char **argv) {
return; return;
} }
if(!hasFS){
printf("Cannot find fs in this disk.\n");
return;
}
vfs_file *file = get_cur_file(argv[1]); vfs_file *file = get_cur_file(argv[1]);
if(file == NULL){ 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"); print("[Shell-CD]: If there are too few parameters, please specify the path.\n");
return; return;
} }
if(!hasFS){
printf("Cannot find fs in this disk.\n");
return;
}
if (vfs_change_path(argv[1]) == 0) printf("Invalid path.\n"); 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"); print("[Shell-TYPE]: If there are too few parameters, please specify the path.\n");
return; return;
} }
if(!hasFS){
printf("Cannot find fs in this disk.\n");
return;
}
char *buffer; char *buffer;
buffer = (char*) kmalloc(vfs_filesize(argv[1])); buffer = (char*) kmalloc(vfs_filesize(argv[1]));
@ -335,7 +355,7 @@ void setup_shell() {
screen_clear(); screen_clear();
printf("Welcome to %s %s (CPOS Kernel x86_64)\n" printf("Welcome to %s %s (CPOS Kernel i386)\n"
"\n" "\n"
" * SourceCode: https://github.com/xiaoyi1212/CoolPotOS\n" " * SourceCode: https://github.com/xiaoyi1212/CoolPotOS\n"
" * Website: https://github.com/plos-clan\n" " * Website: https://github.com/plos-clan\n"
@ -360,7 +380,15 @@ void setup_shell() {
char *buffer[255]; char *buffer[255];
while (1) { 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); printf("\03343cd80;%s@localhost: \0334169E1;%s\\\033c6c6c6;$ ", user1, buffer);
if (gets(com, MAX_COMMAND_LEN) <= 0) continue; if (gets(com, MAX_COMMAND_LEN) <= 0) continue;
argc = cmd_parse(com, argv, ' '); argc = cmd_parse(com, argv, ' ');
@ -414,6 +442,6 @@ void setup_shell() {
print("disk[list|<ID>|cg<ID>]List or view disks.\n"); print("disk[list|<ID>|cg<ID>]List or view disks.\n");
print("cd <path> Change shell top directory.\n"); print("cd <path> Change shell top directory.\n");
print("sb3 <name> Player a wav sound file.\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); 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(){ void screen_clear(){
if(vbe_status){ if(vbe_status){
vbe_clear(); vbe_clear();
@ -333,6 +347,6 @@ void logkf(char *formet,...){
} }
void logk(char *message){ void logk(char *message){
for (size_t i = 0; i < strlen(message); i++) for (size_t i = 0; i < strlen(message); i++);
write_serial(message[i]); //write_serial(message[i]);
} }