return 0;
}
-void die(int code)
-{
- puts("die with code 0x");
- putxval(code, 4);
- puts(".\n");
- while (1) { }
-}
-
-int main(void)
+void boot_from_sdc(const char *filename)
{
static unsigned char *loadbuf = NULL;
char *entry_point;
void (*f)(void);
extern int buffer_start; /* ¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Ð¥Ã¥Õ¥¡ */
- INTR_DISABLE; /* ³ä¹þ¤ß̵¸ú¤Ë¤¹¤ë */
-
- init();
-
FATFS fatfs;
WORD br, i;
BYTE buff[64];
int rc;
- lcd_draw_string(2, 10, "Booting...", 0);
- led_write(Led1, LedOff);
- led_write(Led2, LedOff);
- led_write(LedG, LedOn);
- led_write(LedR, LedOff);
-
/*
* SD¥«¡¼¥É¤ò¥Þ¥¦¥ó¥È¡£
*/
rc = pf_mount(&fatfs);
if (rc) {
- lcd_draw_string(2, 10, "SD mount failed.", 0);
- led_write(LedG, LedOff);
- led_write(LedR, LedOn);
- die(rc);
+ return;
}
/*
* ¥Õ¥¡¥¤¥ë¤ò³«¤¯¡£
*/
- puts("\n\nOpen kozos boot image.\n");
- rc = pf_open("kozos");
+ rc = pf_open(filename);
if (rc) {
- lcd_draw_string(2, 10, "No boot image.", 0);
- led_write(LedG, LedOff);
- led_write(LedR, LedOn);
- die(rc);
+ return;
}
+ lcd_draw_string(2, 10, "Booting from SDC.", 0);
+
/*
* SD¥«¡¼¥É¾å¤ÎOS¥¤¥á¡¼¥¸¤ò¥á¥â¥ê¾å¤ËÆɤ߹þ¤ß¡£
*/
- puts("Reading...\n");
loadbuf = (char *)(&buffer_start);
for (;;) {
rc = pf_read(buff, sizeof(buff), &br);
loadbuf++;
}
lcd_draw_progressbar(5, 20, 121 - 5, 25, 0, 100, fatfs.fptr * 100 / fatfs.fsize, 0);
+ led_toggle(Led1);
+ led_toggle(Led2);
}
if (rc) {
- puts("error.\n");
lcd_draw_string(2, 10, "File read error.", 0);
- led_write(LedG, LedOff);
- led_write(LedR, LedOn);
- die(rc);
+ return;
}
- led_write(Led1, LedOff);
- led_write(Led2, LedOff);
/*
* ¥á¥â¥ê¾å¤ËŸ³«(¥í¡¼¥É)
*/
- puts("Extracting...\n");
loadbuf = (char *)(&buffer_start);
entry_point = elf_load(loadbuf);
/*
* ¼Â¹Ô¡£
*/
- puts("Running...\n");
if (!entry_point) {
- puts("error.\n");
lcd_draw_string(2, 10, "Run error.", 0);
- led_write(LedG, LedOff);
- led_write(LedR, LedOn);
} else {
lcd_clear();
led_write(Led1, LedOff);
f = (void (*)(void))entry_point;
f();
}
+}
+
+static void wait()
+{
+ volatile long i;
+ for (i = 0; i < 300000; i++)
+ ;
+}
+
+/* ¥á¥â¥ê¤Î16¿Ê¥À¥ó¥×½ÐÎÏ */
+static int dump(char *buf, long size)
+{
+ long i;
+
+ if (size < 0) {
+ puts("no data.\n");
+ return -1;
+ }
+ for (i = 0; i < size; i++) {
+ putxval(buf[i], 2);
+ if ((i & 0xf) == 15) {
+ puts("\n");
+ } else {
+ if ((i & 0xf) == 7) puts(" ");
+ puts(" ");
+ }
+ }
+ puts("\n");
+
+ return 0;
+}
+
+void boot_from_ser(void)
+{
+ static char buf[16];
+ static long size = -1;
+ static unsigned char *loadbuf = NULL;
+ char *entry_point;
+ void (*f)(void);
+ extern int buffer_start; /* ¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Ð¥Ã¥Õ¥¡ */
+
+ lcd_draw_string(2, 10, "Waiting a boot image.", 0);
+
+ while (1) {
+ puts("kzload> "); /* ¥×¥í¥ó¥×¥Èɽ¼¨ */
+ gets(buf); /* ¥·¥ê¥¢¥ë¤«¤é¤Î¥³¥Þ¥ó¥É¼õ¿® */
+
+ if (!strcmp(buf, "load")) { /* XMODEM¤Ç¤Î¥Õ¥¡¥¤¥ë¤Î¥À¥¦¥ó¥í¡¼¥É */
+ lcd_draw_string(2, 10, "Receiving a boot image.", 0);
+ loadbuf = (char *)(&buffer_start);
+ size = xmodem_recv(loadbuf);
+ wait(); /* žÁ÷¥¢¥×¥ê¤¬½ªÎ»¤·Ã¼Ëö¥¢¥×¥ê¤ËÀ©¸æ¤¬Ìá¤ë¤Þ¤ÇÂÔ¤Á¹ç¤ï¤»¤ë */
+ if (size < 0) {
+ puts("\nXMODEM receive error!\n");
+ lcd_draw_string(2, 10, "Receive error occurred.", 0);
+ } else {
+ puts("\nXMODEM receive succeeded.\n");
+ lcd_draw_string(2, 10, "Receive succeeded. ", 0);
+ }
+ } else if (!strcmp(buf, "dump")) { /* ¥á¥â¥ê¤Î16¿Ê¥À¥ó¥×½ÐÎÏ */
+ puts("size: ");
+ putxval(size, 0);
+ puts("\n");
+ dump(loadbuf, size);
+ } else if (!strcmp(buf, "run")) { /* ELF·Á¼°¥Õ¥¡¥¤¥ë¤Î¼Â¹Ô */
+ entry_point = elf_load(loadbuf); /* ¥á¥â¥ê¾å¤ËŸ³«(¥í¡¼¥É) */
+ if (!entry_point) {
+ puts("run error!\n");
+ } else {
+ puts("starting from entry point: ");
+ putxval((unsigned long)entry_point, 0);
+ puts("\n");
+ f = (void (*)(void))entry_point;
+ f(); /* ¤³¤³¤Ç¡¤¥í¡¼¥É¤·¤¿¥×¥í¥°¥é¥à¤Ë½èÍý¤òÅϤ¹ */
+ /* ¤³¤³¤Ë¤ÏÊ֤äƤ³¤Ê¤¤ */
+ }
+ }
+ }
+}
+
+int main(void)
+{
+ INTR_DISABLE; /* ³ä¹þ¤ß̵¸ú¤Ë¤¹¤ë */
+
+ init();
+
+ boot_from_sdc("kozos");
+ boot_from_ser();
for (;;) { }