-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 53eface
Showing
19 changed files
with
1,013 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
*.o | ||
*.elf | ||
*.tns |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
GCC = nspire-gcc | ||
LD = nspire-ld | ||
GCCFLAGS = -Os -nostdlib -Wall -W -marm -Werror | ||
LDFLAGS = -lnspireio | ||
OBJCOPY := "$(shell which arm-elf-objcopy 2>/dev/null)" | ||
ifeq (${OBJCOPY},"") | ||
OBJCOPY := arm-none-eabi-objcopy | ||
endif | ||
EXE = linuxloader.tns | ||
OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) | ||
DISTDIR = . | ||
vpath %.tns $(DISTDIR) | ||
|
||
all: $(EXE) | ||
|
||
%.o: %.c | ||
$(GCC) $(GCCFLAGS) -c $< | ||
|
||
$(EXE): $(OBJS) | ||
$(LD) $^ -o $(@:.tns=.elf) $(LDFLAGS) | ||
mkdir -p $(DISTDIR) | ||
$(OBJCOPY) -O binary $(@:.tns=.elf) $(DISTDIR)/$@ | ||
|
||
clean: | ||
rm -f *.o *.elf | ||
rm -f $(DISTDIR)/$(EXE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
/* | ||
TI-NSPIRE Linux In-Place Bootloader | ||
Copyright (C) 2012 Daniel Tang | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <os.h> | ||
#include <stdint.h> | ||
|
||
#include "atag_tags.h" | ||
#include "atag.h" | ||
#include "common.h" | ||
#include "macros.h" | ||
|
||
static void* atag_add(void *head, int tagid, ...) { | ||
va_list ap; | ||
va_start(ap, tagid); | ||
char *cmdline = NULL; | ||
|
||
((struct atag*)head)->hdr.tag = tagid; | ||
|
||
#define SET_NEXT_VARARG(type, element) ((struct atag*)head)->u.type.element = va_arg(ap, uint32_t) | ||
#define SET_SIZE(x) ((struct atag*)head)->hdr.size = 2 + (sizeof(((struct atag*)head)->u.x) / sizeof(uint32_t)) | ||
switch (tagid) { | ||
case ATAG_MEM: | ||
SET_SIZE(mem); | ||
SET_NEXT_VARARG(mem, size); | ||
SET_NEXT_VARARG(mem, start); | ||
break; | ||
case ATAG_VIDEOTEXT: | ||
SET_SIZE(videotext); | ||
SET_NEXT_VARARG(videotext, x); | ||
SET_NEXT_VARARG(videotext, y); | ||
SET_NEXT_VARARG(videotext, video_page); | ||
SET_NEXT_VARARG(videotext, video_mode); | ||
SET_NEXT_VARARG(videotext, video_cols); | ||
SET_NEXT_VARARG(videotext, video_ega_bx); | ||
SET_NEXT_VARARG(videotext, video_isvga); | ||
SET_NEXT_VARARG(videotext, video_points); | ||
break; | ||
case ATAG_RAMDISK: | ||
SET_SIZE(ramdisk); | ||
SET_NEXT_VARARG(ramdisk, flags); | ||
SET_NEXT_VARARG(ramdisk, size); | ||
SET_NEXT_VARARG(ramdisk, start); | ||
break; | ||
case ATAG_INITRD2: | ||
SET_SIZE(initrd2); | ||
SET_NEXT_VARARG(initrd2, start); | ||
SET_NEXT_VARARG(initrd2, size); | ||
break; | ||
case ATAG_SERIAL: | ||
SET_SIZE(serialnr); | ||
SET_NEXT_VARARG(serialnr, low); | ||
SET_NEXT_VARARG(serialnr, high); | ||
break; | ||
case ATAG_REVISION: | ||
SET_SIZE(revision); | ||
SET_NEXT_VARARG(revision, rev); | ||
break; | ||
case ATAG_VIDEOLFB: | ||
SET_SIZE(videolfb); | ||
SET_NEXT_VARARG(videolfb, lfb_width); | ||
SET_NEXT_VARARG(videolfb, lfb_height); | ||
SET_NEXT_VARARG(videolfb, lfb_depth); | ||
SET_NEXT_VARARG(videolfb, lfb_linelength); | ||
SET_NEXT_VARARG(videolfb, lfb_base); | ||
SET_NEXT_VARARG(videolfb, lfb_size); | ||
SET_NEXT_VARARG(videolfb, red_size); | ||
SET_NEXT_VARARG(videolfb, red_pos); | ||
SET_NEXT_VARARG(videolfb, green_size); | ||
SET_NEXT_VARARG(videolfb, green_pos); | ||
SET_NEXT_VARARG(videolfb, blue_size); | ||
SET_NEXT_VARARG(videolfb, blue_pos); | ||
SET_NEXT_VARARG(videolfb, rsvd_size); | ||
SET_NEXT_VARARG(videolfb, rsvd_pos); | ||
break; | ||
case ATAG_CORE: | ||
case ATAG_NONE: | ||
((struct atag*)head)->hdr.size = 2; | ||
break; | ||
case ATAG_CMDLINE: | ||
cmdline = va_arg(ap, char*); | ||
((struct atag*)head)->hdr.size = 2 + ((strlen(cmdline) + sizeof(uint32_t)) / sizeof(uint32_t)); | ||
break; | ||
default: | ||
printl("Invalid ATAG id %d", tagid); | ||
return head; | ||
} | ||
size_t tag_size = (((struct atag*)head)->hdr.size * sizeof(uint32_t)); | ||
|
||
if (tagid == ATAG_NONE) ((struct atag*)head)->hdr.size = 0; | ||
if (cmdline) { | ||
strcpy(((struct atag*)head)->u.cmdline.cmdline, cmdline); | ||
} | ||
va_end(ap); | ||
return (char*)head + tag_size; | ||
} | ||
|
||
static void* atag_begin(void *head) { | ||
return atag_add(head, ATAG_CORE); | ||
} | ||
|
||
#define ATAG(...) do { \ | ||
if (current > (char*)settings.atag.start + settings.atag.size) { \ | ||
printl("Internal error. ATAG buffer overrun\n"); \ | ||
return -1; \ | ||
} \ | ||
current = atag_add(current, __VA_ARGS__); \ | ||
} while (0) | ||
|
||
int atag_build() { | ||
char *current; | ||
if (!settings.atag.start) { | ||
printl("Internal error. settings.atag.start = NULL\n"); | ||
return -1; | ||
} | ||
current = atag_begin(settings.atag.start); | ||
/* | ||
Begin building list of ATAGs | ||
*/ | ||
if (settings.phys.size) | ||
ATAG(ATAG_MEM, settings.phys.size, settings.phys.start); | ||
if (strlen(settings.kernel_cmdline)) | ||
ATAG(ATAG_CMDLINE, settings.kernel_cmdline); | ||
if (settings.ramdisk_loaded) | ||
ATAG(ATAG_INITRD2, settings.ramdisk.addr, settings.ramdisk.size); | ||
/* | ||
End list. Stop here | ||
*/ | ||
ATAG(ATAG_NONE); | ||
return 0; | ||
} | ||
|
||
#undef ATAG |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
TI-NSPIRE Linux In-Place Bootloader | ||
Copyright (C) 2012 Daniel Tang | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef ATAG_H | ||
#define ATAG_H | ||
|
||
/* list of possible tags */ | ||
#define ATAG_NONE 0x00000000 | ||
#define ATAG_CORE 0x54410001 | ||
#define ATAG_MEM 0x54410002 | ||
#define ATAG_VIDEOTEXT 0x54410003 | ||
#define ATAG_RAMDISK 0x54410004 | ||
#define ATAG_INITRD2 0x54420005 | ||
#define ATAG_SERIAL 0x54410006 | ||
#define ATAG_REVISION 0x54410007 | ||
#define ATAG_VIDEOLFB 0x54410008 | ||
#define ATAG_CMDLINE 0x54410009 | ||
|
||
int atag_build(); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
Taken from http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html | ||
This file is BSD Licensed. | ||
*/ | ||
#ifndef ATAG_TAGS_H | ||
#define ATAG_TAGS_H | ||
/* structures for each atag */ | ||
struct atag_header { | ||
uint32_t size; /* length of tag in words including this header */ | ||
uint32_t tag; /* tag type */ | ||
}; | ||
|
||
struct atag_core { | ||
uint32_t flags; | ||
uint32_t pagesize; | ||
uint32_t rootdev; | ||
}; | ||
|
||
struct atag_mem { | ||
uint32_t size; | ||
uint32_t start; | ||
}; | ||
|
||
struct atag_videotext { | ||
uint8_t x; | ||
uint8_t y; | ||
uint16_t video_page; | ||
uint8_t video_mode; | ||
uint8_t video_cols; | ||
uint16_t video_ega_bx; | ||
uint8_t video_lines; | ||
uint8_t video_isvga; | ||
uint16_t video_points; | ||
}; | ||
|
||
struct atag_ramdisk { | ||
uint32_t flags; | ||
uint32_t size; | ||
uint32_t start; | ||
}; | ||
|
||
struct atag_initrd2 { | ||
uint32_t start; | ||
uint32_t size; | ||
}; | ||
|
||
struct atag_serialnr { | ||
uint32_t low; | ||
uint32_t high; | ||
}; | ||
|
||
struct atag_revision { | ||
uint32_t rev; | ||
}; | ||
|
||
struct atag_videolfb { | ||
uint16_t lfb_width; | ||
uint16_t lfb_height; | ||
uint16_t lfb_depth; | ||
uint16_t lfb_linelength; | ||
uint32_t lfb_base; | ||
uint32_t lfb_size; | ||
uint8_t red_size; | ||
uint8_t red_pos; | ||
uint8_t green_size; | ||
uint8_t green_pos; | ||
uint8_t blue_size; | ||
uint8_t blue_pos; | ||
uint8_t rsvd_size; | ||
uint8_t rsvd_pos; | ||
}; | ||
|
||
struct atag_cmdline { | ||
char cmdline[1]; | ||
}; | ||
|
||
struct atag { | ||
struct atag_header hdr; | ||
union { | ||
struct atag_core core; | ||
struct atag_mem mem; | ||
struct atag_videotext videotext; | ||
struct atag_ramdisk ramdisk; | ||
struct atag_initrd2 initrd2; | ||
struct atag_serialnr serialnr; | ||
struct atag_revision revision; | ||
struct atag_videolfb videolfb; | ||
struct atag_cmdline cmdline; | ||
} u; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
TI-NSPIRE Linux In-Place Bootloader | ||
Copyright (C) 2012 Daniel Tang | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <os.h> | ||
|
||
#include "kernel.h" | ||
#include "common.h" | ||
#include "load.h" | ||
#include "macros.h" | ||
|
||
/* | ||
Returns number of filled arguments. | ||
Var args are all of type char** | ||
*/ | ||
int cmd_args(char* args, unsigned max_n, ...) { | ||
va_list ap; | ||
va_start(ap, max_n); | ||
|
||
char *ptr = args; | ||
unsigned i; | ||
for (i=0; i<max_n && *args; i++) { | ||
if (*args == ' ') { | ||
*args = '\0'; | ||
char **fill = va_arg(ap,char**); | ||
*fill = ptr; | ||
ptr = args + 1; | ||
} | ||
args++; | ||
} | ||
|
||
va_end(ap); | ||
return i; | ||
} | ||
|
||
/* | ||
Returns 1 if program should gracefully exit | ||
Returns 0 if further commands can be executed | ||
*/ | ||
#define DEFINE_COMMAND(s, f) else if (!strncmp(#s, cmd, sizeof(#s)-1)) f(cmd+sizeof(#s)) | ||
int process_cmd(char * cmd) { | ||
if (*cmd == '\0') return 0; | ||
else if (!strcmp("exit", cmd)) return 1; | ||
/* | ||
Define custom commands below | ||
DEFINE_COMMAND( function_name, function_to_call ); | ||
function_to_call should accept one parameter which is | ||
pointer to arguments | ||
*/ | ||
DEFINE_COMMAND(kernel, load_kernel); | ||
DEFINE_COMMAND(initrd, load_ramdisk); | ||
DEFINE_COMMAND(dump, dump_settings); | ||
DEFINE_COMMAND(boot, kernel_boot); | ||
/* | ||
End command list. Do not add any more after here | ||
*/ | ||
else { printl("Unknown command\n"); } | ||
return 0; | ||
} | ||
#undef DEFINE_COMMAND |
Oops, something went wrong.