加入进程终止功能
This commit is contained in:
parent
07df67ad6e
commit
f4519da582
146
driver/acpi.c
146
driver/acpi.c
@ -1,146 +0,0 @@
|
||||
#include "../include/acpi.h"
|
||||
#include "../include/graphics.h"
|
||||
#include "../include/memory.h"
|
||||
#include "../include/io.h"
|
||||
#include "../include/timer.h"
|
||||
|
||||
struct FADT *fadt;
|
||||
struct DSDT_vals dsdt;
|
||||
void *dsdt_ptr;
|
||||
|
||||
void *findRSDP() {
|
||||
printf("ACPI: searching RSDP");
|
||||
uint8_t * mem = (uint8_t * )
|
||||
0x000E0000;
|
||||
while ((unsigned int) mem != 0x000FFFFF) {
|
||||
if (memcmp(mem, "RSD PTR ", 8) == 0) {
|
||||
uint8_t * bptr = (uint8_t * )
|
||||
mem;
|
||||
uint8_t check = 0;
|
||||
for (unsigned int i = 0; i < sizeof(struct RSDPDescriptor); i++) {
|
||||
check += *bptr;
|
||||
bptr++;
|
||||
}
|
||||
if (((struct RSDPDescriptor *) mem)->Revision >= 1) {
|
||||
check = 0;
|
||||
uint8_t * bptr20 = (uint8_t * )
|
||||
mem;
|
||||
for (unsigned int j = 0; j < sizeof(struct RSDPDescriptor20); j++) {
|
||||
check += *bptr20;
|
||||
bptr20++;
|
||||
}
|
||||
}
|
||||
if (!check) {
|
||||
printf("Done, RSDP found on 0x%08x", mem);
|
||||
return mem;
|
||||
} else {
|
||||
printf("error: ACPI RSDP checksum is invalid.");
|
||||
}
|
||||
}
|
||||
mem++;
|
||||
}
|
||||
printf("RSDP not found.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_check_hdr(uint8_t *table, const char *sig, int n) {
|
||||
if (memcmp(table, sig, n) != 0)
|
||||
return 1;
|
||||
uint8_t checksum = 0;
|
||||
if (checksum == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void parse_dsdt() {
|
||||
if (fadt == 0) {
|
||||
printf("ACPI: FADT not found!");
|
||||
}
|
||||
if (acpi_check_hdr((uint8_t * )(int)fadt->Dsdt, "DSDT", 4)!=0){
|
||||
printf("ACPI: Invalid DSDT signature!");
|
||||
}
|
||||
dsdt_ptr = (void *) fadt->Dsdt;
|
||||
dsdt.length = ((struct ACPISDTHeader *) dsdt_ptr)->Length - sizeof(struct ACPISDTHeader);
|
||||
int i;
|
||||
for (i = 0; i <= dsdt.length; i++) {
|
||||
if (memcmp(dsdt_ptr + sizeof(struct ACPISDTHeader) + i, "_S5_", 4) == 0) {
|
||||
dsdt.S5_object = dsdt_ptr + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == dsdt.length) {
|
||||
printf("ACPI: No S5 object in DSDT.");
|
||||
}
|
||||
}
|
||||
|
||||
void parse_acpi(void *mem) {
|
||||
struct RSDPDescriptor *rsdp = mem;
|
||||
struct RSDT *rsdt = (struct RSDT *) (rsdp->RsdtAddress);
|
||||
int i = 0;
|
||||
if (acpi_check_hdr((uint8_t * )(int)rsdt, "RSDT", 4)!=0)
|
||||
{
|
||||
printf("ACPI: Invalid RSDT signature.");
|
||||
}
|
||||
while (acpi_check_hdr((uint8_t * )(&rsdt->PointerToOtherSDT)[i], "FACP", 4) != 0 && i <= 64)
|
||||
i++;
|
||||
if (i < 64) {
|
||||
fadt = (struct FADT *) (&rsdt->PointerToOtherSDT)[i];
|
||||
} else {
|
||||
printf("ACPI: FADT not found!");
|
||||
}
|
||||
const char *pm_profile_strings[9] = {"unspecified", "desktop", "notebook", "mobile", "workstation",
|
||||
"enterprice server", "SOHO server", "appliance PC", "perfomance server"};
|
||||
printf("This PC's power management profile is %s",
|
||||
(fadt->PreferredPowerManagementProfile < 8) ? pm_profile_strings[fadt->PreferredPowerManagementProfile]
|
||||
: "unknown, field is in reserved value");
|
||||
//Then parse the DSDT and enable ACPI.
|
||||
parse_dsdt();
|
||||
acpi_enable();
|
||||
}
|
||||
|
||||
void parse_acpi20(void *mem) {
|
||||
struct RSDPDescriptor20 *rsdp = (struct RSDPDescriptor20 *) mem;
|
||||
struct XSDT *xsdt = (struct XSDT *) (int) (rsdp->XsdtAddress);
|
||||
int i = 0;
|
||||
while (acpi_check_hdr((uint8_t * )(int)(&xsdt->PointerToOtherSDT)[i], "FACP", 4)!=0 && i <= 64)
|
||||
i++;
|
||||
if (i < 64) {
|
||||
fadt = (struct FADT *) (int) (&xsdt->PointerToOtherSDT)[i];
|
||||
} else {
|
||||
printf("ACPI: FADT not found!");
|
||||
}
|
||||
parse_dsdt();
|
||||
acpi_enable();
|
||||
}
|
||||
|
||||
void acpi_enable() {
|
||||
printf("ACPI: Trying to enable ACPI...");
|
||||
if ((inw(fadt->PM1aControlBlock) >> 1 & 1) == 0) {
|
||||
printf("ACPI already enabled");
|
||||
return;
|
||||
}
|
||||
outb(fadt->SMI_CommandPort, fadt->AcpiEnable);
|
||||
int i;
|
||||
for (i = 0; i < 300; i++) {
|
||||
if ((inw(fadt->PM1aControlBlock) & 1) == 0)
|
||||
break;
|
||||
clock_sleep(4);
|
||||
}
|
||||
if ((inw(fadt->PM1aControlBlock) & 1) != 0) {
|
||||
printf("Failed to enable ACPI.");
|
||||
}
|
||||
printf("ACPI: ACPI enabled!");
|
||||
}
|
||||
|
||||
void init_acpi() {
|
||||
struct RSDPDescriptor *rsdp = findRSDP();
|
||||
if (rsdp == NULL) {
|
||||
printf("\nNo ACPI on this computer.");
|
||||
}
|
||||
if (rsdp->Revision >= 1) {
|
||||
parse_acpi20((void *) rsdp);
|
||||
return;
|
||||
}
|
||||
parse_acpi((void *) rsdp);
|
||||
}
|
||||
|
132
include/acpi.h
132
include/acpi.h
@ -1,132 +0,0 @@
|
||||
#ifndef CRASHPOWEROS_ACPI_H
|
||||
#define CRASHPOWEROS_ACPI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct RSDPDescriptor RSDPDescriptor;
|
||||
typedef struct GenericAddressStructure GenericAddressStructure;
|
||||
|
||||
struct RSDPDescriptor {
|
||||
char Signature[8];
|
||||
uint8_t Checksum;
|
||||
char OEMID[6];
|
||||
uint8_t Revision;
|
||||
uint32_t RsdtAddress;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct RSDPDescriptor20 {
|
||||
struct RSDPDescriptor firstPart;
|
||||
|
||||
uint32_t Length;
|
||||
uint64_t XsdtAddress;
|
||||
uint8_t ExtendedChecksum;
|
||||
uint8_t reserved[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ACPISDTHeader {
|
||||
char Signature[4];
|
||||
uint32_t Length;
|
||||
uint8_t Revision;
|
||||
uint8_t Checksum;
|
||||
char OEMID[6];
|
||||
char OEMTableID[8];
|
||||
uint32_t OEMRevision;
|
||||
uint32_t CreatorID;
|
||||
uint32_t CreatorRevision;
|
||||
};
|
||||
|
||||
struct RSDT {
|
||||
struct ACPISDTHeader h;
|
||||
uint32_t PointerToOtherSDT;
|
||||
};
|
||||
|
||||
struct XSDT {
|
||||
struct ACPISDTHeader h;
|
||||
uint64_t PointerToOtherSDT;
|
||||
};
|
||||
|
||||
struct GenericAddressStructure {
|
||||
uint8_t AddressSpace;
|
||||
uint8_t BitWidth;
|
||||
uint8_t BitOffset;
|
||||
uint8_t AccessSize;
|
||||
uint64_t Address;
|
||||
};
|
||||
|
||||
struct FADT {
|
||||
struct ACPISDTHeader h;
|
||||
uint32_t FirmwareCtrl;
|
||||
uint32_t Dsdt;
|
||||
|
||||
uint8_t Reserved;
|
||||
|
||||
uint8_t PreferredPowerManagementProfile;
|
||||
uint16_t SCI_Interrupt;
|
||||
uint32_t SMI_CommandPort;
|
||||
uint8_t AcpiEnable;
|
||||
uint8_t AcpiDisable;
|
||||
uint8_t S4BIOS_REQ;
|
||||
uint8_t PSTATE_Control;
|
||||
uint32_t PM1aEventBlock;
|
||||
uint32_t PM1bEventBlock;
|
||||
uint32_t PM1aControlBlock;
|
||||
uint32_t PM1bControlBlock;
|
||||
uint32_t PM2ControlBlock;
|
||||
uint32_t PMTimerBlock;
|
||||
uint32_t GPE0Block;
|
||||
uint32_t GPE1Block;
|
||||
uint8_t PM1EventLength;
|
||||
uint8_t PM1ControlLength;
|
||||
uint8_t PM2ControlLength;
|
||||
uint8_t PMTimerLength;
|
||||
uint8_t GPE0Length;
|
||||
uint8_t GPE1Length;
|
||||
uint8_t GPE1Base;
|
||||
uint8_t CStateControl;
|
||||
uint16_t WorstC2Latency;
|
||||
uint16_t WorstC3Latency;
|
||||
uint16_t FlushSize;
|
||||
uint16_t FlushStride;
|
||||
uint8_t DutyOffset;
|
||||
uint8_t DutyWidth;
|
||||
uint8_t DayAlarm;
|
||||
uint8_t MonthAlarm;
|
||||
uint8_t Century;
|
||||
|
||||
uint16_t BootArchitectureFlags;
|
||||
|
||||
uint8_t Reserved2;
|
||||
uint32_t Flags;
|
||||
|
||||
GenericAddressStructure ResetReg;
|
||||
|
||||
uint8_t ResetValue;
|
||||
uint8_t Reserved3[3];
|
||||
|
||||
uint64_t X_FirmwareControl;
|
||||
uint64_t X_Dsdt;
|
||||
|
||||
GenericAddressStructure X_PM1aEventBlock;
|
||||
GenericAddressStructure X_PM1bEventBlock;
|
||||
GenericAddressStructure X_PM1aControlBlock;
|
||||
GenericAddressStructure X_PM1bControlBlock;
|
||||
GenericAddressStructure X_PM2ControlBlock;
|
||||
GenericAddressStructure X_PMTimerBlock;
|
||||
GenericAddressStructure X_GPE0Block;
|
||||
GenericAddressStructure X_GPE1Block;
|
||||
};
|
||||
|
||||
struct DSDT_vals {
|
||||
int length;
|
||||
void *S5_object;
|
||||
};
|
||||
|
||||
void *findRSDP();
|
||||
int acpi_check_hdr(uint8_t *table, const char *sig, int n);
|
||||
void parse_dsdt();
|
||||
void parse_acpi(void *mem);
|
||||
void parse_acpi20(void *mem);
|
||||
void acpi_enable();
|
||||
void init_acpi();
|
||||
|
||||
#endif //CRASHPOWEROS_ACPI_H
|
@ -2,7 +2,10 @@
|
||||
#define CRASHPOWEROS_COMMON_H
|
||||
|
||||
#define OS_NAME "CrashPowerDOS"
|
||||
#define OS_VERSION "v0.2.2"
|
||||
#define OS_VERSION "v0.2.3"
|
||||
|
||||
#define LONG_MAX 9223372036854775807L
|
||||
#define LONG_MIN -9223372036854775808L
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@ -27,5 +30,6 @@ char *uint32_to_str_oct(uint32_t num, int flag, int width);
|
||||
char *insert_str(char *buf, const char *str);
|
||||
int vsprintf(char *buf, const char *fmt, va_list args);
|
||||
int sprintf(char *buf, const char *fmt, ...);
|
||||
long int strtol(const char *str,char **endptr,int base);
|
||||
|
||||
#endif //CRASHPOWEROS_COMMON_H
|
||||
|
@ -10,7 +10,7 @@ void setup_shell();
|
||||
|
||||
//内置命令
|
||||
void cmd_echo(int argc,char **argv);
|
||||
void cmd_proc();
|
||||
void cmd_proc(int argc, char **argv);
|
||||
void cmd_date();
|
||||
void cmd_reset();
|
||||
void cmd_del(int argc, char **argv);
|
||||
|
@ -44,4 +44,6 @@ void schedule();
|
||||
|
||||
void change_task_to(struct task_struct *next);
|
||||
|
||||
void task_kill(int pid);
|
||||
|
||||
#endif //CRASHPOWEROS_TASK_H
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "../include/keyboard.h"
|
||||
#include "../include/shell.h"
|
||||
#include "../include/date.h"
|
||||
#include "../include/acpi.h"
|
||||
|
||||
extern uint32_t end;
|
||||
extern int status;
|
||||
@ -37,7 +36,6 @@ void kernel_main(multiboot_t *multiboot) {
|
||||
printf("[\035kernel\036]: PCB load success!\n");
|
||||
init_keyboard();
|
||||
printf("[\035kernel\036]: Keyboard driver load success!\n");
|
||||
//init_acpi();printf("[\035kernel\036]: ACPI enabled!\n");
|
||||
|
||||
print_cpu_id();
|
||||
io_sti();
|
||||
|
@ -62,19 +62,74 @@ void print_proc(){
|
||||
printf("Name Pid Status [All Proc: %d]\n\n",index);
|
||||
}
|
||||
|
||||
static void found_task(int pid,struct task_struct *base,struct task_struct *argv){
|
||||
struct task_struct *t = base;
|
||||
if(t == NULL){
|
||||
argv = NULL;
|
||||
return;
|
||||
}
|
||||
if(t->pid == pid){
|
||||
*argv = *t;
|
||||
return;
|
||||
} else{
|
||||
found_task(pid,t->next,argv);
|
||||
}
|
||||
}
|
||||
|
||||
void task_kill(int pid){
|
||||
struct task_struct *argv;
|
||||
found_task(pid,running_proc_head,argv);
|
||||
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");
|
||||
return;
|
||||
}
|
||||
argv->state = TASK_DEATH;
|
||||
switch (argv->state) {
|
||||
case TASK_RUNNABLE:
|
||||
printf("%s %d %s\n",argv->name,argv->pid,"Running");
|
||||
break;
|
||||
case TASK_SLEEPING:
|
||||
printf("%s %d %s\n",argv->name,argv->pid,"Sleeping");
|
||||
break;
|
||||
case TASK_UNINIT:
|
||||
printf("%s %d %s\n",argv->name,argv->pid,"Init");
|
||||
break;
|
||||
case TASK_ZOMBIE:
|
||||
printf("%s %d %s\n",argv->name,argv->pid,"Zombie");
|
||||
break;
|
||||
case TASK_DEATH:
|
||||
printf("%s %d %s\n",argv->name,argv->pid,"Death");
|
||||
break;
|
||||
}
|
||||
printf("Task [%s] exit code: -130.\n",argv->name);
|
||||
|
||||
struct task_struct *head = running_proc_head;
|
||||
struct task_struct *last = NULL;
|
||||
while (1){
|
||||
if(head->pid == argv->pid){
|
||||
last->next = argv->next;
|
||||
return;
|
||||
}
|
||||
last = head;
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
|
||||
void schedule() {
|
||||
if (current) {
|
||||
volatile task_state state = current->next->state;
|
||||
if(state == TASK_RUNNABLE || state == TASK_SLEEPING){
|
||||
change_task_to(current->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void change_task_to(struct task_struct *next) {
|
||||
if (current != next) {
|
||||
struct task_struct *prev = current;
|
||||
current = next;
|
||||
|
||||
//switch_page_directory(current->pgd_dir);
|
||||
switch_to(&(prev->context), &(current->context));
|
||||
}
|
||||
|
@ -67,8 +67,25 @@ void cmd_echo(int argc, char **argv) {
|
||||
vga_putchar('\n');
|
||||
}
|
||||
|
||||
void cmd_proc(){
|
||||
void cmd_proc(int argc, char **argv){
|
||||
if (argc <= 1) {
|
||||
printf("\033[Shell-PROC]: If there are too few parameters.\036\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcmp("list",argv[1])){
|
||||
print_proc();
|
||||
} else if(!strcmp("kill",argv[1])){
|
||||
if (argc <= 2) {
|
||||
printf("\033[Shell-PROC-kill]: If there are too few parameters.\036\n");
|
||||
return;
|
||||
}
|
||||
int pid = strtol(argv[2],NULL,10);
|
||||
task_kill(pid);
|
||||
} else{
|
||||
printf("\033[Shell-[PROC]]: Unknown parameter\036\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_date(){
|
||||
@ -195,7 +212,7 @@ void setup_shell(){
|
||||
else if (!strcmp("clear", argv[0]))
|
||||
vga_clear();
|
||||
else if (!strcmp("proc", argv[0]))
|
||||
cmd_proc();
|
||||
cmd_proc(argc, argv);
|
||||
else if (!strcmp("sysinfo", argv[0]))
|
||||
cmd_date();
|
||||
else if (!strcmp("ls", argv[0]))
|
||||
@ -221,7 +238,7 @@ void setup_shell(){
|
||||
vga_writestring("mkdir <name> \032Make a directory.\036\n");
|
||||
vga_writestring("del rm <name> \032Delete a file.\036\n");
|
||||
vga_writestring("sysinfo \032Print system info.\036\n");
|
||||
vga_writestring("proc \032Lists all running processes.\036\n");
|
||||
vga_writestring("proc [kill<pid>|list] \032Lists all running processes.\036\n");
|
||||
vga_writestring("reset \032Reset OS.\036\n");
|
||||
} else printf("\033[Shell]: Unknown command '%s'.\036\n", argv[0]);
|
||||
}
|
||||
|
@ -5,6 +5,73 @@
|
||||
|
||||
static char num_str_buf[BUF_SIZE];
|
||||
|
||||
long int strtol(const char *str,char **endptr,int base){
|
||||
const char *s;
|
||||
unsigned long acc;
|
||||
char c;
|
||||
unsigned long cutoff;
|
||||
int neg, any, cutlim;
|
||||
s = str;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace((unsigned char)c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X') &&
|
||||
((s[1] >= '0' && s[1] <= '9') ||
|
||||
(s[1] >= 'A' && s[1] <= 'F') ||
|
||||
(s[1] >= 'a' && s[1] <= 'f'))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
acc = any = 0;
|
||||
if (base < 2 || base > 36)
|
||||
goto noconv;
|
||||
|
||||
cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX
|
||||
: LONG_MAX;
|
||||
cutlim = cutoff % base;
|
||||
cutoff /= base;
|
||||
for ( ; ; c = *s++) {
|
||||
if (c >= '0' && c <= '9')
|
||||
c -= '0';
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
c -= 'A' - 10;
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
c -= 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = neg ? LONG_MIN : LONG_MAX;
|
||||
} else if (!any) {
|
||||
noconv:
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *)(any ? s - 1 : str);
|
||||
return (acc);
|
||||
}
|
||||
|
||||
size_t strnlen(const char *s, size_t maxlen) {
|
||||
const char *es = s;
|
||||
while (*es && maxlen) {
|
||||
|
Loading…
Reference in New Issue
Block a user