int kcinth() { u16 segment, offset; int a,b,c,d, r; segment = running->uss; offset = running->usp; //==> WRITE CODE TO GET get syscall parameters a,b,c,d from ustack a = get_word(segment, offset + 2*PA); b = get_word(segment, offset + 2*PB); c = get_word(segment, offset + 2*PC); d = get_word(segment, offset + 2*PD); switch(a){ case 0 : printf("hello in kernel a: %d cmd: %s\n", a, cmds[a]);r = kgetpid(); break; case 1 : printf("hello in kernel a: %d cmd: %s\n", a, cmds[a]);r = kps(); break; case 2 : printf("hello in kernel a: %d cmd: %s\n", a, cmds[a]);r = kchname(b); break; case 3 : printf("hello in kernel a: %d cmd: %s\n", a, cmds[a]);r = kkfork(); break; case 4 : printf("hello in kernel a: %d cmd: %s\n", a, cmds[a]);r = ktswitch(); break; case 5 : printf("hello in kernel a: %d cmd: %s\n", a, cmds[a]);r = kkwait(b); break; case 6 : printf("hello in kernel a: %d cmd: %s\n", a, cmds[a]);r = kkexit(b); break; case 7 : printf("hello in kernel a: %d cmd: %s\n", a, cmds[a]);r = kexec(b); break; case 99: kkexit(b); break; default: printf("invalid syscall # : %d\n", a); } put_word(r, segment, offset + 2*AX); return r;//this will be overwritten by the pop ax register when restoring back to uMode }
/************** syscall routing table ***********/ int kcinth() { u16 x, y, z, w, r; u16 seg, off; seg = running->uss; off = running->usp; x = get_word(seg, off+13*2); y = get_word(seg, off+14*2); z = get_word(seg, off+15*2); w = get_word(seg, off+16*2); switch(x){ case 0 : r = running->pid; break; case 1 : r = kps(); break; case 2 : r = chname(y); break; case 3 : r = kmode(); break; case 4 : r = tswitch(); break; case 5 : r = kwait(); break; case 6 : r = kexit(); break; case 7 : r = fork(); break; case 8 : r = kexec(y); break; case 9 : r = sout(y); break; case 10: r = sin(y); break; case 99: r = kexit(); break; default: printf("invalid syscall # : %d\n", x); } put_word(r, seg, off+2*8); }
void pv_boot (void) { unsigned long flags = 0; if (multiboot_next_module_header) { /* Termination entry */ multiboot_next_module_header->mod_start = 0; /* Total size */ module_size = multiboot_next_module - module_image; /* It's a multiboot module */ flags |= SIF_MULTIBOOT_MOD; } kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg, flags); }
void main() { kputs("--DEBUG-- Hello world from kernel!\n"); unsigned long i; kernelsp[0]=(unsigned long)kernel_stack[1]; for(i=1;i<MSIM_CPU_NUM;i++) { send(MSIM_MASTER_ID, 0, 0); kernelsp[i]=(unsigned long)kernel_stack[i+1]; send(i, 1, (uint32_t)cpu_stack[i+1]); send(i, 0, (uint32_t)slave_main); } cur_pid=pid_alloc(); write_c0_entryhi(cur_pid); sc_num=SYS_EXEC; sc_args[0]="init"; sc_pid=cur_pid; for(;;) { write_c0_compare(0); switch(sc_num) { case SYS_PUTS: kputs(sc_args[0]); sc_ret=0; break; case SYS_FORK: sc_ret=kfork(); break; case SYS_EXEC: sc_ret=kexec(sc_args[0]); break; case SYS_GETS: sc_ret=kgets(sc_args[0], sc_args[1]); break; } pcb[sc_pid].gpr[ORD_V0]=sc_ret; cur_pid=sc_pid; next_process; sc_num=SYS_NONE; __to_user(); } }
/****************** syscall handler in C ***************************/ int kcinth() { int a,b,c,d, r; //WRITE CODE TO GET get syscall parameters a,b,c,d from ustack a = get_word(running->uss, running->usp + 26); b = get_word(running->uss, running->usp + 28); c = get_word(running->uss, running->usp + 30); d = get_word(running->uss, running->usp + 32); switch(a){ case 0 : r = kgetpid(); break; case 1 : r = kps(); break; case 2 : r = kchname(b); break; case 3 : r = kmode(); break; case 4 : r = tswitch(); break; case 5 : r = kkwait(b); break; case 6 : r = kkexit(b); break; case 7 : r = fork(); break; case 8 : r = kexec(b); break; case 30: r = kpipe(b); break; case 31: r = read_pipe(b,c,d); break; case 32: r = write_pipe(b,c,d);break; case 33: r = close_pipe(b); break; case 34: r = pfd(); break; case 90: r = getc(); break; case 91: r = putc(b); break; case 99: kkexit(b); break; default: printf("invalid syscall # : %d\n", a); } //WRITE CODE to let r be the return value to Umode put_word(r, running->uss, running->usp + 16); return r; }
static void kexec_from_uart(int uartdev) { #ifdef _XINU_PLATFORM_ARM_RPI_ irqmask im; device *uart; ulong size; void *kernel; uchar *p; ulong n; im = disable(); uart = (device*)&devtab[uartdev]; /* Tell raspbootcom to send the new kernel. */ kputc('\x03', uart); kputc('\x03', uart); kputc('\x03', uart); /* Receive size of the new kernel. */ for (;;) { size = (ulong)kgetc(uart); size |= (ulong)kgetc(uart) << 8; size |= (ulong)kgetc(uart) << 16; size |= (ulong)kgetc(uart) << 24; if (size <= 99999999 && size != 0) { break; } /* Tell raspbootcom to re-send the size. */ kputc('S', uart); kputc('E', uart); } /* Tell raspbootcom the size was successfully received. */ kputc('O', uart); kputc('K', uart); /* Allocate buffer for new kernel. */ kernel = memget(size); if (kernel == (void*)SYSERR) { return; } /* Load new kernel over the UART, placing it into the buffer. */ p = kernel; n = size; while (n--) { *p++ = kgetc(uart); } /* Execute the new kernel. */ kexec(kernel, size); /* The following code should never actually be reached. */ memfree(kernel, size); restore(im); #else /* _XINU_PLATFORM_ARM_RPI_ */ fprintf(stderr, "ERROR: kexec from UART not supported on this platform.\n"); #endif /* !_XINU_PLATFORM_ARM_RPI_ */ }
static void kexec_from_network(int netdev, char *boot) { #if defined(WITH_DHCPC) && NETHER != 0 struct dhcpData data; int result; const struct netaddr *gatewayptr; struct netif *nif; void *kernel; uint size; char str_ip[20]; char str_mask[20]; char str_gateway[20]; const char *netdevname = devtab[netdev].name; /* Bring network interface (if any) down. */ netDown(netdev); /* Run DHCP client on the device for at most 10 seconds. */ printf("Running DHCP on %s\n", netdevname); result = dhcpClient(netdev, 10, &data); if (OK != result) { fprintf(stderr, "ERROR: DHCP failed.\n"); return; } /* Ensure the DHCP server provided the boot filename and TFTP server IP * address. */ if (('\0' == data.bootfile[0] || 0 == data.next_server.type) && boot == NULL) { fprintf(stderr, "ERROR: DHCP server did not provide boot file " "and TFTP server address.\n"); return; } /* Bring up the network interface. */ netaddrsprintf(str_ip, &data.ip); netaddrsprintf(str_mask, &data.mask); if (0 != data.gateway.len) { netaddrsprintf(str_gateway, &data.gateway); printf("Bringing up %s as %s with mask %s (gateway %s)\n", netdevname, str_ip, str_mask, str_gateway); gatewayptr = &data.gateway; } else { printf("Bringing up %s as %s with mask %s (no gateway)\n", netdevname, str_ip, str_mask); gatewayptr = NULL; } result = netUp(netdev, &data.ip, &data.mask, gatewayptr); if (OK != result) { fprintf(stderr, "ERROR: failed to bring up %s.\n", netdevname); return; } nif = netLookup(netdev); /* Download new kernel using TFTP. */ netaddrsprintf(str_ip, &data.next_server); if (boot == NULL) { printf("Downloading bootfile \"%s\" from TFTP server %s\n", data.bootfile, str_ip); kernel = (void*)tftpGetIntoBuffer(data.bootfile, &nif->ip, &data.next_server, &size); }else { printf("Downloading bootfile \"%s\" from TFTP server %s\n", boot, str_ip); kernel = (void*)tftpGetIntoBuffer(boot, &nif->ip, &data.next_server, &size); } if (SYSERR == (int)kernel) { fprintf(stderr, "ERROR: TFTP failed.\n"); return; } /* Execute the new kernel. */ printf("Executing new kernel (size=%u)\n", size); sleep(100); /* Wait just a fraction of a second for printf()s to finish (no guarantees though). */ kexec(kernel, size); fprintf(stderr, "ERROR: kexec() returned!\n"); #else /* WITH_DHCPC && NETHER != 0 */ fprintf(stderr, "ERROR: Network boot is not supported in this configuration.\n" " Please make sure you have enabled one or more network\n" " devices, along with the DHCP and TFTP clients.\n"); #endif /* !(WITH_DHCPC && NETHER != 0) */ }