/** * @brief Writes a message to the kernel's output device and panics the kernel. * * @param fmt Formatted message to be written onto kernel's output device. */ PUBLIC void kpanic(const char *fmt, ...) { int i; /* Loop index. */ va_list args; /* Variable arguments list. */ char buffer[KBUFFER_SIZE + 1]; /* Temporary buffer. */ kstrncpy(buffer, "PANIC: ", 7); /* Convert to raw string. */ va_start(args, fmt); i = kvsprintf(buffer + 7, fmt, args) + 7; buffer[i++] = '\n'; va_end(args); /* Save on kernel log and write on kout. */ cdev_write(kout, buffer, i); klog_write(buffer, i); /* * Disable interrupts, so we cannot * be bothered. */ disable_interrupts(); while(1); halt(); }
/** * @brief Initializes the process management system. */ PUBLIC void pm_init(void) { int i; /* Loop index. */ struct process *p; /* Working process. */ /* Initialize the process table. */ for (p = FIRST_PROC; p <= LAST_PROC; p++) p->flags = 0, p->state = PROC_DEAD; /* Handcraft init process. */ IDLE->cr3 = (dword_t)idle_pgdir; IDLE->intlvl = 1; IDLE->flags = 0; IDLE->received = 0; IDLE->kstack = idle_kstack; IDLE->restorer = NULL; for (i = 0; i < NR_SIGNALS; i++) IDLE->handlers[i] = SIG_DFL; IDLE->irqlvl = INT_LVL_5; IDLE->pgdir = idle_pgdir; for (i = 0; i < NR_PREGIONS; i++) IDLE->pregs[i].reg = NULL; IDLE->size = 0; for (i = 0; i < OPEN_MAX; i++) IDLE->ofiles[i] = NULL; IDLE->close = 0; IDLE->umask = S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH; IDLE->tty = NULL_DEV; IDLE->status = 0; IDLE->nchildren = 0; IDLE->uid = SUPERUSER; IDLE->euid = SUPERUSER; IDLE->suid = SUPERUSER; IDLE->gid = SUPERGROUP; IDLE->egid = SUPERGROUP; IDLE->sgid = SUPERGROUP; IDLE->pid = next_pid++; IDLE->pgrp = IDLE; IDLE->father = NULL; kstrncpy(IDLE->name, "idle", NAME_MAX); IDLE->utime = 0; IDLE->ktime = 0; IDLE->cutime = 0; IDLE->cktime = 0; IDLE->state = PROC_RUNNING; IDLE->counter = PROC_QUANTUM; IDLE->priority = PRIO_USER; IDLE->nice = NZERO; IDLE->alarm = 0; IDLE->next = NULL; IDLE->chain = NULL; nprocs++; clock_init(CLOCK_FREQ); enable_interrupts(); }
/* supported formats: %%, %d, %u, %x, %p, %s, %c * TODO: * - return number of bytes copied into 'str' */ int kvsprintf(char *str, const char *fmt, va_list ap) { char *ptr, *stmp; unsigned utmp; int itmp; char ctmp; for (; *fmt; fmt = ptr + 2) { ptr = kstrchr(fmt, '%'); if (ptr == NULL) { kstrcpy(str, fmt); return 1; } str += kstrncpy(str, fmt, (int)ptr - (int)fmt); switch (*(ptr + 1)) { case 'd': /* signed int */ itmp = va_arg(ap, int); str = sitoa(str, itmp); break; case 'u': /* unsigned int */ utmp = va_arg(ap, unsigned); str = uitoa(str, utmp); break; case 'p': /* pointer */ *str++ = '0'; *str++ = 'x'; case 'x': /* hex */ utmp = va_arg(ap, unsigned); str = htoa(str, utmp); break; case 's': /* string */ stmp = va_arg(ap, char *); str += kstrcpy(str, stmp); break; case '%': *str++ = '%'; break; case 'c': ctmp = va_arg(ap, int); *str++ = ctmp; break; default: /* unsupported format */ break; } } return 1; }
/* * Adds an entry to a directory. */ PUBLIC int dir_add(struct inode *dinode, struct inode *inode, const char *name) { struct buffer *buf; /* Block buffer. */ struct d_dirent *d; /* Disk directory entry. */ d = dirent_search(dinode, name, &buf, 1); /* Failed to create directory entry. */ if (d == NULL) return (-1); kstrncpy(d->d_name, name, NAME_MAX); d->d_ino = inode->num; buf->flags |= BUFFER_DIRTY; brelse(buf); return (0); }