diff --git a/kboot.conf b/kboot.conf new file mode 100644 index 0000000..bf218b5 --- /dev/null +++ b/kboot.conf @@ -0,0 +1,61 @@ +#KBOOTCONFIG +; #KBOOTCONFIG (and nothing else) has to stay in FIRST line of the file + +# General XeLL options +; netconfig - only if the ip= is valid and isnt the same as eventually in the previously parsed kboot.conf, the netconfig gets set +; if netconfig values aren't set/set invalid/commented, XeLL will use: Either supplied DHCP address or if no DHCP available, static IP (192.168.1.99/255.255.255.0) +ip=192.168.1.98 +netmask=255.255.255.0 +gateway=192.168.1.1 + +; set custom tftp server IP +; incase no tftp_server= is set/set invalid/commented, XeLL will use: Supplied address via DHCP, if no DHCP available it will use 192.168.1.98 +tftp_server=192.168.1.99 + +; XeLL's videomode - valid modes: +; 0: VIDEO_MODE_VGA_640x480 +; 1: VIDEO_MODE_VGA_1024x768 +; 2: VIDEO_MODE_PAL60 +; 3: VIDEO_MODE_YUV_480P +; 4: VIDEO_MODE_PAL50 +; 5: VIDEO_MODE_VGA_1280x768 +; 6: VIDEO_MODE_VGA_1360x768 +; 7: VIDEO_MODE_VGA_1280x720 +; 8: VIDEO_MODE_VGA_1440x900 +; 9: VIDEO_MODE_VGA_1280x1024 +; 10: VIDEO_MODE_HDMI_720P +; 11: VIDEO_MODE_YUV_720P +; 12: VIDEO_MODE_NTSC +; If no value is set/set invalid/commented, XeLL will continue using the autodetected value +videomode=10 + +; speed up cpu - valid modes: +; 1: XENON_SPEED_FULL +; 2: XENON_SPEED_3_2 +; 3: XENON_SPEED_1_2 +; 4: XENON_SPEED_1_3 +; If no value is set/set invalid/commented, XeLL won't change CPU Speed +speedup=1 + + +# Linux/ELF BootMenu +# Supplying boot-entries is optional - you can delete those from the config to just set "General XeLL options" + +; label of the default bootentry - +; If no value is set/set invalid/commented, XeLL defaults to first bootentry +default=zlx_browser + +; timeout of the bootmenu in seconds - timeout=0 skips user input completely! +timeout=10 + +; Kernel / Bootentries +; ! first parameter: kernel path ! + +zlx_browser_tftp="/xenon/zlx_browser" +nullDC_usb="uda:/nulldc-360.elf" +linux_usb_noinitrd="uda:/casper/vmlinuz boot=casper console=tty0 console=ttyS0,115200n8 video=xenonfb panic=60 maxcpus=3" +linux_usb="uda:/casper/vmlinuz boot=casper initrd=uda:/casper/initrd.gz console=tty0 console=ttyS0,115200n8 video=xenonfb panic=60 maxcpus=3" +linux_tftp_nosubdir="xenon initrd=initrd.gz root=/dev/nfs nfsroot=192.168.1.99:/mnt/sdc/nfs/xbox_v2 rw console=tty0 console=ttyS0,115200n8 ip=dhcp video=xenonfb panic=60 maxcpus=3 noplymouth nosplash" +linux_tftp_subdir="/xbox/xenon initrd=/casper/initrd.gz console=tty0 console=ttyS0,115200n8 video=xenonfb panic=60 maxcpus=3" +linux_dvd="dvd:/casper/vmlinuz boot=casper initrd=dvd:/casper/initrd.gz console=tty0 console=ttyS0,115200n8 video=xenonfb panic=60 maxcpus=3" +linux_hdd="sda:/vmlinux root=/dev/nfs initrd=sda:/xbox/initrd.gz console=tty0 console=ttyS0,115200n8 video=xenonfb panic=60 maxcpus=3" diff --git a/source/lv2/kboot/kbootconf.c b/source/lv2/kboot/kbootconf.c new file mode 100755 index 0000000..e3992fb --- /dev/null +++ b/source/lv2/kboot/kbootconf.c @@ -0,0 +1,485 @@ +/* kbootcfg.c - kboot.cfg parsing + +Copyright (C) 2010-2011 Hector Martin "marcan" + +This code is licensed to you under the terms of the GNU GPL, version 2; +see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +/* See http://www.kernel.org/pub/linux/kernel/people/geoff/cell/ps3-linux-docs/ps3-linux-docs-08.06.09/mini-boot-conf.txt */ + +/* Menu functions written by Georg "ge0rg" Lukas for XeLL (Menu-branch) + kbootconf-parsing and menu functions modified by tuxuser */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tftp/tftp.h" +#include "kbootconf.h" + +int boot_entry; +char conf_buf[MAX_KBOOTCONF_SIZE]; +struct kbootconf conf; + +ip_addr_t oldipaddr, oldnetmask, oldgateway; +char *kboot_tftp; + +enum ir_remote_codes IR; +static struct controller_data_s ctrl; +static struct controller_data_s old_ctrl; + +/* main.c */ +extern int try_load_elf(char *filename); +extern char *boot_server_name(); +/* network.h */ +extern struct netif netif; + +#define LOAD_FILE(x) {if(!strncmp(x,"uda:/",4)||!strncmp(x,"dvd:/",4)||!strncmp(x,"sda:/",4))try_load_elf(x); else boot_tftp(boot_server_name(),x);} + +char *strip(char *buf) +{ + while (*buf == ' ' || *buf == '\t') + buf++; + char *end = buf + strlen(buf) - 1; + while (*end == ' ' || *end == '\t') + *end-- = 0; + + return buf; +} + +void split(char *buf, char **left, char **right, char delim) +{ + char *p = strchr(buf, delim); + + if (p) { + *p = 0; + *left = strip(buf); + *right = strip(p+1); + } else { + *left = strip(buf); + *right = NULL; + } +} + +void kboot_set_config(void) +{ + + int setnetconfig = 0; + static int oldvideomode = -1; + ip_addr_t ipaddr, netmask, gateway, tftpserver; + + if(conf.tftp_server != NULL) + if (ipaddr_aton(conf.tftp_server,&tftpserver)) + kboot_tftp = conf.tftp_server; + + /* Only reinit network if IPs dont match which got set by kboot on previous try*/ + if(conf.ipaddress != NULL) + if (ipaddr_aton(conf.ipaddress,&ipaddr) && ip_addr_cmp(&oldipaddr,&ipaddr) == 0) + { + printf(" * taking network down to set config values\n"); + setnetconfig = 1; + netif_set_down(&netif); + + netif_set_ipaddr(&netif,&ipaddr); + ip_addr_set(&oldipaddr,&ipaddr); + } + + if(conf.netmask != NULL) + if (ipaddr_aton(conf.netmask,&netmask) && setnetconfig){ + netif_set_netmask(&netif,&netmask); + ip_addr_set(&oldnetmask,&netmask); + } + + if(conf.gateway != NULL) + if (ipaddr_aton(conf.gateway,&gateway) && setnetconfig){ + netif_set_gw(&netif,&gateway); + ip_addr_set(&oldgateway,&gateway); + } + + if (setnetconfig){ + printf(" * bringing network back up...\n"); + netif_set_up(&netif); + network_print_config(); + } + + if(conf.videomode > VIDEO_MODE_AUTO && conf.videomode <= VIDEO_MODE_NTSC && oldvideomode != conf.videomode){ + oldvideomode = conf.videomode; + xenos_init(conf.videomode); + printf(" * Xenos re-initalized\n"); + } + + if(conf.speedup >= XENON_SPEED_FULL && conf.speedup <= XENON_SPEED_1_3){ //speedmode: drivers/xenon_soc/xenon_power.h + printf("Speeding up CPU\n"); + xenon_make_it_faster(conf.speedup); + } + +} + +int kbootconf_parse(void) +{ + char *lp = conf_buf; + char *dflt = NULL; + char *dinitrd = NULL; + char *droot = NULL; + char *dvideo = NULL; + char tmpbuf[MAX_CMDLINE_SIZE]; + int lineno = 1; + int i; + + memset(&conf, 0, sizeof(conf)); + + conf.timeout = -1; + conf.videomode = -1; + conf.speedup = 0; + + while(*lp) { + char *newline = strchr(lp, '\n'); + char *next; + if (newline) { + *newline = 0; + next = newline+1; + } else { + next = lp+strlen(lp); + } + + lp = strip(lp); + if (!*lp) + goto nextline; + + char *left, *right; + + split(lp, &left, &right, '='); + if (!right) { + if(strncmp(left,"#",1) && strncmp(left,";",1)) + PRINT_WARN("kboot.conf: parse error (line %d)\n", lineno); + goto nextline; + } + + while(*right == '"' || *right == '\'') + right++; + char *rend = right + strlen(right) - 1; + while(*rend == '"' || *rend == '\'') + *rend-- = 0; + + if (!strcmp(left, "timeout")) { + conf.timeout = atoi(right); + } else if (!strcmp(left, "default")) { + dflt = right; + } else if (!strcmp(left, "message")) { + conf.msgfile = right; + } else if (!strcmp(left, "initrd")) { + dinitrd = right; + } else if (!strcmp(left, "root")) { + droot = right; + } else if (!strcmp(left, "videomode")) { + conf.videomode = atoi(right); + } else if (!strcmp(left, "speedup")) { + conf.speedup = atoi(right); + } else if (!strcmp(left, "tftp_server")) { + conf.tftp_server = right; + } else if (!strcmp(left, "ip")) { + conf.ipaddress = right; + } else if (!strcmp(left, "netmask")) { + conf.netmask = right; + } else if (!strcmp(left, "gateway")) { + conf.gateway = right; + } else if (!strncmp(left, "#", 1)||!strncmp(left, ";", 1)) { + goto nextline; + } else { + if (strlen(right) > MAX_CMDLINE_SIZE) { + PRINT_WARN("kboot.conf: maximum length exceeded (line %d)\n", lineno); + goto nextline; + } + conf.kernels[conf.num_kernels].label = left; + conf.kernels[conf.num_kernels].kernel = right; + + char *p = strchr(right, ' '); + if (!p) { + // kernel, no arguments + conf.num_kernels++; + goto nextline; + } + *p++ = 0; + char *buf = p; + char *root = NULL; + char *initrd = NULL; + tmpbuf[0] = 0; + /* split commandline arguments and extract the useful bits */ + while (*p) { + char *spc = strchr(p, ' '); + if (spc) + *spc++ = 0; + else + spc = p+strlen(p); + if (*p == 0) { + p = spc; + continue; + } + + char *arg, *val; + split(p, &arg, &val, '='); + if (!val) { + strlcat(tmpbuf, arg, sizeof(tmpbuf)); + strlcat(tmpbuf, " ", sizeof(tmpbuf)); + } else if (!strcmp(arg, "root")) { + root = val; + } else if (!strcmp(arg, "initrd")) { + initrd = val; + } else { + strlcat(tmpbuf, arg, sizeof(tmpbuf)); + strlcat(tmpbuf, "=", sizeof(tmpbuf)); + strlcat(tmpbuf, val, sizeof(tmpbuf)); + strlcat(tmpbuf, " ", sizeof(tmpbuf)); + } + + p = spc; + } + + int len = strlen(tmpbuf); + if (len && tmpbuf[len-1] == ' ') + tmpbuf[--len] = 0; + len++; + + // UGLY: tack on initrd and root onto tmpbuf, then copy it entirely + // on top of the original buffer (avoids having to deal with malloc) + conf.kernels[conf.num_kernels].parameters = buf; + if (initrd) { + strlcpy(tmpbuf+len, initrd, sizeof(tmpbuf)-len); + conf.kernels[conf.num_kernels].initrd = buf + len; + len += strlen(initrd)+1; + } + if (root) { + strlcpy(tmpbuf+len, root, sizeof(tmpbuf)-len); + conf.kernels[conf.num_kernels].root = buf + len; + len += strlen(root)+1; + } + memcpy(buf, tmpbuf, len); + conf.num_kernels++; + } + +nextline: + lp = next; + lineno++; + } + + conf.default_idx = 0; + for (i=0; i %i", + defaultchoice); + } + else + { + printf(" \r[%02d] > %i", + timeout - delta,defaultchoice); + } + redraw = 0; + } + + if (xenon_smc_poll() == 0) { + int ch = xenon_smc_get_ir(); + + if (ch >= min && ch <= max) + return ch; + else if (ch == IR_UP && (defaultchoice < max-1)) + defaultchoice++; + else if(ch == IR_DOWN && (defaultchoice > min)) + defaultchoice--; + else if(ch == IR_OK) + return defaultchoice; + else if(ch == IR_BTN_B) + return -1; + redraw = 1; + } + + if (kbhit()) { + char ch = getch(); + + if (ch == 0xD) + return defaultchoice; + else if (ch == 0x41 && (defaultchoice < max-1)) // UP + defaultchoice++; + else if(ch == 0x42 && (defaultchoice > min)) // DOWN + defaultchoice--; + else if(ch == 0x63) // C - (c)ancel + return -1; + + redraw = 1; + } + + if (get_controller_data(&ctrl, 0)) { + if ((ctrl.a > old_ctrl.a) || (ctrl.start > old_ctrl.start)) + return defaultchoice; + else if ((ctrl.b > old_ctrl.b) || (ctrl.select > old_ctrl.select)) + return -1; + else if ((ctrl.up > old_ctrl.up) && (defaultchoice < max-1)) + defaultchoice++; + else if ((ctrl.down > old_ctrl.down) && (defaultchoice > min)) + defaultchoice--; + old_ctrl=ctrl; + redraw = 1; + } + + network_poll(); + usb_do_poll(); + + if(old_default != defaultchoice) + timeout_disabled = 1; + } +printf("\nTimeout.\n"); +return defaultchoice; +} + +void try_kbootconf(void * addr, unsigned len){ + + if (len > MAX_KBOOTCONF_SIZE) + { + PRINT_ERR("file is bigger than %u bytes\n",len); + PRINT_ERR("Aborting\n"); + return; + } + + memcpy(conf_buf,addr,len); + conf_buf[len] = 0; //ensure null-termination + + kbootconf_parse(); + kboot_set_config(); + + if (conf.num_kernels == 0){ + PRINT_WARN("No kernels found in kboot.conf !\n"); + return; + } + + int i; + printf("\nXeLL Main Menu. Please choose from:\n\n"); + for(i=0;i %s - %s\n",i,conf.kernels[i].label, conf.kernels[i].kernel); + } + boot_entry = user_prompt(conf.default_idx, conf.num_kernels,conf.timeout); + + if (boot_entry < 0) + { + printf("\rAborted by user!\n"); + return; + } + printf("\nYou chose: %i\n",boot_entry); + + if (conf.kernels[boot_entry].parameters) + kernel_build_cmdline(conf.kernels[boot_entry].parameters,conf.kernels[boot_entry].root); + + kernel_reset_initrd(); + + if (conf.kernels[boot_entry].initrd) + { + printf("Loading initrd ...\n"); + LOAD_FILE(conf.kernels[boot_entry].initrd); + } + + printf("Loading kernel ...\n"); + LOAD_FILE(conf.kernels[boot_entry].kernel); + + memset(conf_buf,0,MAX_KBOOTCONF_SIZE); + conf.num_kernels = 0; + conf.timeout = 0; + conf.default_idx = 0; + conf.speedup = 0; +} diff --git a/source/lv2/kboot/kbootconf.h b/source/lv2/kboot/kbootconf.h new file mode 100755 index 0000000..99adce4 --- /dev/null +++ b/source/lv2/kboot/kbootconf.h @@ -0,0 +1,42 @@ +/* main.c - kboot.conf parsing + +Copyright (C) 2010-2011 Hector Martin "marcan" + +This code is licensed to you under the terms of the GNU GPL, version 2; +see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef KBOOTCONF_H +#define KBOOTCONF_H + +#define MAX_CMDLINE_SIZE 255 +#define MAX_KBOOTCONF_SIZE 16384 +#define MAX_KERNELS 64 + +struct kbootkernel { + char *label; + char *kernel; + char *initrd; + char *root; + char *video; + char *parameters; +}; + +struct kbootconf { + int timeout; + int videomode; + int speedup; + char *msgfile; + char *tftp_server; + char *ipaddress; + char *netmask; + char *gateway; + int default_idx; + int num_kernels; + struct kbootkernel kernels[MAX_KERNELS]; +}; + +int kbootconf_parse(void); +void try_kbootconf(void * addr, unsigned len); + +#endif