diff options
Diffstat (limited to 'dos')
-rw-r--r-- | dos/__divdi3.c | 30 | ||||
-rw-r--r-- | dos/__udivmoddi4.c | 42 | ||||
-rw-r--r-- | dos/argv.c | 80 | ||||
-rw-r--r-- | dos/atou.c | 8 | ||||
-rw-r--r-- | dos/conio.c | 22 | ||||
-rw-r--r-- | dos/free.c | 93 | ||||
-rw-r--r-- | dos/malloc.c | 153 | ||||
-rw-r--r-- | dos/malloc.h | 10 | ||||
-rw-r--r-- | dos/mystuff.h | 5 | ||||
-rw-r--r-- | dos/perror.c | 2 | ||||
-rw-r--r-- | dos/printf.c | 481 | ||||
-rw-r--r-- | dos/skipatou.c | 8 | ||||
-rw-r--r-- | dos/stdint.h | 56 | ||||
-rw-r--r-- | dos/stdio.h | 2 | ||||
-rw-r--r-- | dos/stdlib.h | 2 | ||||
-rw-r--r-- | dos/string.h | 8 | ||||
-rw-r--r-- | dos/syslinux.c | 985 |
17 files changed, 990 insertions, 997 deletions
diff --git a/dos/__divdi3.c b/dos/__divdi3.c index 3641396f..97c77950 100644 --- a/dos/__divdi3.c +++ b/dos/__divdi3.c @@ -5,25 +5,25 @@ #include <stdint.h> #include <stddef.h> -extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); +extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem); int64_t __divdi3(int64_t num, int64_t den) { - int minus = 0; - int64_t v; + int minus = 0; + int64_t v; - if ( num < 0 ) { - num = -num; - minus = 1; - } - if ( den < 0 ) { - den = -den; - minus ^= 1; - } + if (num < 0) { + num = -num; + minus = 1; + } + if (den < 0) { + den = -den; + minus ^= 1; + } - v = __udivmoddi4(num, den, NULL); - if ( minus ) - v = -v; + v = __udivmoddi4(num, den, NULL); + if (minus) + v = -v; - return v; + return v; } diff --git a/dos/__udivmoddi4.c b/dos/__udivmoddi4.c index 8e7661f5..ca476b70 100644 --- a/dos/__udivmoddi4.c +++ b/dos/__udivmoddi4.c @@ -1,31 +1,31 @@ #include <stdint.h> -uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p) +uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem_p) { - uint64_t quot = 0, qbit = 1; + uint64_t quot = 0, qbit = 1; - if ( den == 0 ) { - asm volatile("int $0"); - return 0; /* If trap returns... */ - } + if (den == 0) { + asm volatile ("int $0"); + return 0; /* If trap returns... */ + } - /* Left-justify denominator and count shift */ - while ( (int64_t)den >= 0 ) { - den <<= 1; - qbit <<= 1; - } + /* Left-justify denominator and count shift */ + while ((int64_t) den >= 0) { + den <<= 1; + qbit <<= 1; + } - while ( qbit ) { - if ( den <= num ) { - num -= den; - quot += qbit; + while (qbit) { + if (den <= num) { + num -= den; + quot += qbit; + } + den >>= 1; + qbit >>= 1; } - den >>= 1; - qbit >>= 1; - } - if ( rem_p ) - *rem_p = num; + if (rem_p) + *rem_p = num; - return quot; + return quot; } @@ -39,54 +39,54 @@ #define ALIGN_UP(p,t) ((t *)(((uintptr_t)(p) + (sizeof(t)-1)) & ~(sizeof(t)-1))) extern char __heap_start[]; -void *__mem_end = &__heap_start; /* Global variable for use by malloc() */ +void *__mem_end = &__heap_start; /* Global variable for use by malloc() */ int __parse_argv(char ***argv, const char *str) { - char *mem = __mem_end; - const char *p = str; - char *q = mem; - char *r; - char **arg; - int wasspace = 0; - int argc = 1; + char *mem = __mem_end; + const char *p = str; + char *q = mem; + char *r; + char **arg; + int wasspace = 0; + int argc = 1; - /* First copy the string, turning whitespace runs into nulls */ - for ( p = str ; ; p++ ) { - if ( *p <= ' ' ) { - if ( !wasspace ) { - wasspace = 1; - *q++ = '\0'; - } - } else { - if ( wasspace ) { - argc++; - wasspace = 0; - } - *q++ = *p; - } + /* First copy the string, turning whitespace runs into nulls */ + for (p = str;; p++) { + if (*p <= ' ') { + if (!wasspace) { + wasspace = 1; + *q++ = '\0'; + } + } else { + if (wasspace) { + argc++; + wasspace = 0; + } + *q++ = *p; + } - /* This test is AFTER we have processed the null byte; - we treat it as a whitespace character so it terminates - the last argument */ - if ( ! *p ) - break; - } + /* This test is AFTER we have processed the null byte; + we treat it as a whitespace character so it terminates + the last argument */ + if (!*p) + break; + } - /* Now create argv */ - arg = ALIGN_UP(q,char *); - *argv = arg; - *arg++ = mem; /* argv[0] */ + /* Now create argv */ + arg = ALIGN_UP(q, char *); + *argv = arg; + *arg++ = mem; /* argv[0] */ - q--; /* Point q to final null */ - for ( r = mem ; r < q ; r++ ) { - if ( *r == '\0' ) { - *arg++ = r+1; + q--; /* Point q to final null */ + for (r = mem; r < q; r++) { + if (*r == '\0') { + *arg++ = r + 1; + } } - } - *arg++ = NULL; /* Null pointer at the end */ - __mem_end = arg; /* End of memory we used */ + *arg++ = NULL; /* Null pointer at the end */ + __mem_end = arg; /* End of memory we used */ - return argc; + return argc; } @@ -2,8 +2,8 @@ unsigned int atou(const char *s) { - unsigned int i = 0; - while (isdigit(*s)) - i = i*10 + (*s++ - '0'); - return i; + unsigned int i = 0; + while (isdigit(*s)) + i = i * 10 + (*s++ - '0'); + return i; } diff --git a/dos/conio.c b/dos/conio.c index bf54805a..1400e42c 100644 --- a/dos/conio.c +++ b/dos/conio.c @@ -21,22 +21,22 @@ int putchar(int ch) { - if ( ch == '\n' ) - putchar('\r'); - asm("movb $0x02,%%ah ; int $0x21" : : "d" (ch)); - return ch; + if (ch == '\n') + putchar('\r'); +asm("movb $0x02,%%ah ; int $0x21": :"d"(ch)); + return ch; } /* Note: doesn't put '\n' like the stdc version does */ int puts(const char *s) { - int count = 0; + int count = 0; - while ( *s ) { - putchar(*s); - count++; - s++; - } + while (*s) { + putchar(*s); + count++; + s++; + } - return count; + return count; } @@ -7,72 +7,71 @@ #include <stdlib.h> #include "malloc.h" -static struct free_arena_header * -__free_block(struct free_arena_header *ah) +static struct free_arena_header *__free_block(struct free_arena_header *ah) { - struct free_arena_header *pah, *nah; + struct free_arena_header *pah, *nah; - pah = ah->a.prev; - nah = ah->a.next; - if ( pah->a.type == ARENA_TYPE_FREE && - (char *)pah+pah->a.size == (char *)ah ) { - /* Coalesce into the previous block */ - pah->a.size += ah->a.size; - pah->a.next = nah; - nah->a.prev = pah; + pah = ah->a.prev; + nah = ah->a.next; + if (pah->a.type == ARENA_TYPE_FREE && + (char *)pah + pah->a.size == (char *)ah) { + /* Coalesce into the previous block */ + pah->a.size += ah->a.size; + pah->a.next = nah; + nah->a.prev = pah; #ifdef DEBUG_MALLOC - ah->a.type = ARENA_TYPE_DEAD; + ah->a.type = ARENA_TYPE_DEAD; #endif - ah = pah; - pah = ah->a.prev; - } else { - /* Need to add this block to the free chain */ - ah->a.type = ARENA_TYPE_FREE; - - ah->next_free = __malloc_head.next_free; - ah->prev_free = &__malloc_head; - __malloc_head.next_free = ah; - ah->next_free->prev_free = ah; - } - - /* In either of the previous cases, we might be able to merge - with the subsequent block... */ - if ( nah->a.type == ARENA_TYPE_FREE && - (char *)ah+ah->a.size == (char *)nah ) { - ah->a.size += nah->a.size; - - /* Remove the old block from the chains */ - nah->next_free->prev_free = nah->prev_free; - nah->prev_free->next_free = nah->next_free; - ah->a.next = nah->a.next; - nah->a.next->a.prev = ah; + ah = pah; + pah = ah->a.prev; + } else { + /* Need to add this block to the free chain */ + ah->a.type = ARENA_TYPE_FREE; + + ah->next_free = __malloc_head.next_free; + ah->prev_free = &__malloc_head; + __malloc_head.next_free = ah; + ah->next_free->prev_free = ah; + } + + /* In either of the previous cases, we might be able to merge + with the subsequent block... */ + if (nah->a.type == ARENA_TYPE_FREE && + (char *)ah + ah->a.size == (char *)nah) { + ah->a.size += nah->a.size; + + /* Remove the old block from the chains */ + nah->next_free->prev_free = nah->prev_free; + nah->prev_free->next_free = nah->next_free; + ah->a.next = nah->a.next; + nah->a.next->a.prev = ah; #ifdef DEBUG_MALLOC - nah->a.type = ARENA_TYPE_DEAD; + nah->a.type = ARENA_TYPE_DEAD; #endif - } + } - /* Return the block that contains the called block */ - return ah; + /* Return the block that contains the called block */ + return ah; } void free(void *ptr) { - struct free_arena_header *ah; + struct free_arena_header *ah; - if ( !ptr ) - return; + if (!ptr) + return; - ah = (struct free_arena_header *) - ((struct arena_header *)ptr - 1); + ah = (struct free_arena_header *) + ((struct arena_header *)ptr - 1); #ifdef DEBUG_MALLOC - assert( ah->a.type == ARENA_TYPE_USED ); + assert(ah->a.type == ARENA_TYPE_USED); #endif - __free_block(ah); + __free_block(ah); - /* Here we could insert code to return memory to the system. */ + /* Here we could insert code to return memory to the system. */ } diff --git a/dos/malloc.c b/dos/malloc.c index 2d74459c..55c78c4c 100644 --- a/dos/malloc.c +++ b/dos/malloc.c @@ -8,105 +8,104 @@ #include <string.h> #include "malloc.h" -struct free_arena_header __malloc_head = -{ - { - ARENA_TYPE_HEAD, - 0, - &__malloc_head, +struct free_arena_header __malloc_head = { + { + ARENA_TYPE_HEAD, + 0, + &__malloc_head, + &__malloc_head, + }, &__malloc_head, - }, - &__malloc_head, - &__malloc_head + &__malloc_head }; extern void *__mem_end; /* In argv.c */ void __init_memory_arena(void) { - extern char __heap_end[]; - struct free_arena_header *fp; - - fp = (struct free_arena_header *)__mem_end; - fp->a.type = ARENA_TYPE_FREE; - fp->a.size = __heap_end - (char *)__mem_end; - - /* Insert into chains */ - fp->a.next = fp->a.prev = &__malloc_head; - fp->next_free = fp->prev_free = &__malloc_head; - __malloc_head.a.next = __malloc_head.a.prev = fp; - __malloc_head.next_free = __malloc_head.prev_free = fp; + extern char __heap_end[]; + struct free_arena_header *fp; + + fp = (struct free_arena_header *)__mem_end; + fp->a.type = ARENA_TYPE_FREE; + fp->a.size = __heap_end - (char *)__mem_end; + + /* Insert into chains */ + fp->a.next = fp->a.prev = &__malloc_head; + fp->next_free = fp->prev_free = &__malloc_head; + __malloc_head.a.next = __malloc_head.a.prev = fp; + __malloc_head.next_free = __malloc_head.prev_free = fp; } static void *__malloc_from_block(struct free_arena_header *fp, size_t size) { - size_t fsize; - struct free_arena_header *nfp, *na; - - fsize = fp->a.size; - - /* We need the 2* to account for the larger requirements of a free block */ - if ( fsize >= size+2*sizeof(struct arena_header) ) { - /* Bigger block than required -- split block */ - nfp = (struct free_arena_header *)((char *)fp + size); - na = fp->a.next; - - nfp->a.type = ARENA_TYPE_FREE; - nfp->a.size = fsize-size; - fp->a.type = ARENA_TYPE_USED; - fp->a.size = size; - - /* Insert into all-block chain */ - nfp->a.prev = fp; - nfp->a.next = na; - na->a.prev = nfp; - fp->a.next = nfp; - - /* Replace current block on free chain */ - nfp->next_free = fp->next_free; - nfp->prev_free = fp->prev_free; - fp->next_free->prev_free = nfp; - fp->prev_free->next_free = nfp; - } else { - /* Allocate the whole block */ - fp->a.type = ARENA_TYPE_USED; - - /* Remove from free chain */ - fp->next_free->prev_free = fp->prev_free; - fp->prev_free->next_free = fp->next_free; - } - - return (void *)(&fp->a + 1); + size_t fsize; + struct free_arena_header *nfp, *na; + + fsize = fp->a.size; + + /* We need the 2* to account for the larger requirements of a free block */ + if (fsize >= size + 2 * sizeof(struct arena_header)) { + /* Bigger block than required -- split block */ + nfp = (struct free_arena_header *)((char *)fp + size); + na = fp->a.next; + + nfp->a.type = ARENA_TYPE_FREE; + nfp->a.size = fsize - size; + fp->a.type = ARENA_TYPE_USED; + fp->a.size = size; + + /* Insert into all-block chain */ + nfp->a.prev = fp; + nfp->a.next = na; + na->a.prev = nfp; + fp->a.next = nfp; + + /* Replace current block on free chain */ + nfp->next_free = fp->next_free; + nfp->prev_free = fp->prev_free; + fp->next_free->prev_free = nfp; + fp->prev_free->next_free = nfp; + } else { + /* Allocate the whole block */ + fp->a.type = ARENA_TYPE_USED; + + /* Remove from free chain */ + fp->next_free->prev_free = fp->prev_free; + fp->prev_free->next_free = fp->next_free; + } + + return (void *)(&fp->a + 1); } void *malloc(size_t size) { - struct free_arena_header *fp; + struct free_arena_header *fp; - if ( size == 0 ) - return NULL; + if (size == 0) + return NULL; - /* Add the obligatory arena header, and round up */ - size = (size+2*sizeof(struct arena_header)-1) & ~ARENA_SIZE_MASK; + /* Add the obligatory arena header, and round up */ + size = (size + 2 * sizeof(struct arena_header) - 1) & ~ARENA_SIZE_MASK; - for ( fp = __malloc_head.next_free ; fp->a.type != ARENA_TYPE_HEAD ; - fp = fp->next_free ) { - if ( fp->a.size >= size ) { - /* Found fit -- allocate out of this block */ - return __malloc_from_block(fp, size); + for (fp = __malloc_head.next_free; fp->a.type != ARENA_TYPE_HEAD; + fp = fp->next_free) { + if (fp->a.size >= size) { + /* Found fit -- allocate out of this block */ + return __malloc_from_block(fp, size); + } } - } - /* Nothing found... need to request a block from the kernel */ - return NULL; /* No kernel to get stuff from */ + /* Nothing found... need to request a block from the kernel */ + return NULL; /* No kernel to get stuff from */ } void *calloc(size_t nmemb, size_t size) { - void *p; - size *= nmemb; - p = malloc(size); - if (p) - memset(p, 0, size); - return p; + void *p; + size *= nmemb; + p = malloc(size); + if (p) + memset(p, 0, size); + return p; } diff --git a/dos/malloc.h b/dos/malloc.h index 70d0e635..67bf217c 100644 --- a/dos/malloc.h +++ b/dos/malloc.h @@ -21,9 +21,9 @@ struct free_arena_header; struct arena_header { - size_t type; - size_t size; /* Also gives the location of the next entry */ - struct free_arena_header *next, *prev; + size_t type; + size_t size; /* Also gives the location of the next entry */ + struct free_arena_header *next, *prev; }; #ifdef DEBUG_MALLOC @@ -47,8 +47,8 @@ struct arena_header { * previous structure. */ struct free_arena_header { - struct arena_header a; - struct free_arena_header *next_free, *prev_free; + struct arena_header a; + struct free_arena_header *next_free, *prev_free; }; extern struct free_arena_header __malloc_head; diff --git a/dos/mystuff.h b/dos/mystuff.h index 83f072f5..fbf4e75b 100644 --- a/dos/mystuff.h +++ b/dos/mystuff.h @@ -6,10 +6,9 @@ unsigned int skip_atou(const char **s); unsigned int atou(const char *s); -static inline int -isdigit(int ch) +static inline int isdigit(int ch) { - return (ch >= '0') && (ch <= '9'); + return (ch >= '0') && (ch <= '9'); } #endif /* MYSTUFF_H */ diff --git a/dos/perror.c b/dos/perror.c index e6e82874..99ab2f81 100644 --- a/dos/perror.c +++ b/dos/perror.c @@ -3,5 +3,5 @@ void perror(const char *msg) { - printf("%s: error %s\n", msg, errno); + printf("%s: error %s\n", msg, errno); } diff --git a/dos/printf.c b/dos/printf.c index 99b389f6..4bef2662 100644 --- a/dos/printf.c +++ b/dos/printf.c @@ -17,12 +17,13 @@ static int strnlen(const char *s, int maxlen) { - const char *es = s; - while ( *es && maxlen ) { - es++; maxlen--; - } + const char *es = s; + while (*es && maxlen) { + es++; + maxlen--; + } - return (es-s); + return (es - s); } #define ZEROPAD 1 /* pad with zero */ @@ -39,259 +40,269 @@ __res = ((unsigned long) n) % (unsigned) base; \ n = ((unsigned long) n) / (unsigned) base; \ __res; }) -static char * number(char * str, long num, int base, int size, int precision - ,int type) +static char *number(char *str, long num, int base, int size, int precision, + int type) { - char c,sign,tmp[66]; - const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; - int i; - - if (type & LARGE) - digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - if (type & LEFT) - type &= ~ZEROPAD; - if (base < 2 || base > 36) - return 0; - c = (type & ZEROPAD) ? '0' : ' '; - sign = 0; - if (type & SIGN) { - if (num < 0) { - sign = '-'; - num = -num; - size--; - } else if (type & PLUS) { - sign = '+'; - size--; - } else if (type & SPACE) { - sign = ' '; - size--; + char c, sign, tmp[66]; + const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; } - } - if (type & SPECIAL) { - if (base == 16) - size -= 2; - else if (base == 8) - size--; - } - i = 0; - if (num == 0) - tmp[i++]='0'; - else while (num != 0) - tmp[i++] = digits[do_div(num,base)]; - if (i > precision) - precision = i; - size -= precision; - if (!(type&(ZEROPAD+LEFT))) - while(size-->0) - *str++ = ' '; - if (sign) - *str++ = sign; - if (type & SPECIAL) { - if (base==8) - *str++ = '0'; - else if (base==16) { - *str++ = '0'; - *str++ = digits[33]; + i = 0; + if (num == 0) + tmp[i++] = '0'; + else + while (num != 0) + tmp[i++] = digits[do_div(num, base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type & (ZEROPAD + LEFT))) + while (size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base == 8) + *str++ = '0'; + else if (base == 16) { + *str++ = '0'; + *str++ = digits[33]; + } } - } - if (!(type & LEFT)) + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; while (size-- > 0) - *str++ = c; - while (i < precision--) - *str++ = '0'; - while (i-- > 0) - *str++ = tmp[i]; - while (size-- > 0) - *str++ = ' '; - return str; + *str++ = ' '; + return str; } /* Forward decl. needed for IP address printing stuff... */ -int sprintf(char * buf, const char *fmt, ...); +int sprintf(char *buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args) { - int len; - unsigned long num; - int i, base; - char * str; - const char *s; + int len; + unsigned long num; + int i, base; + char *str; + const char *s; - int flags; /* flags to number() */ + int flags; /* flags to number() */ - int field_width; /* width of output field */ - int precision; /* min. # of digits for integers; max + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max number of chars for from string */ - int qualifier; /* 'h', 'l', or 'L' for integer fields */ - - for (str=buf ; *fmt ; ++fmt) { - if (*fmt != '%') { - *str++ = *fmt; - continue; + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str = buf; *fmt; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; +repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': + flags |= LEFT; + goto repeat; + case '+': + flags |= PLUS; + goto repeat; + case ' ': + flags |= SPACE; + goto repeat; + case '#': + flags |= SPECIAL; + goto repeat; + case '0': + flags |= ZEROPAD; + goto repeat; + } + + /* get field width */ + field_width = -1; + if (isdigit(*fmt)) + field_width = skip_atou(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (isdigit(*fmt)) + precision = skip_atou(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char)va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + len = strnlen(s, precision); + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2 * sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long)va_arg(args, void *), 16, + field_width, precision, flags); + continue; + + case 'n': + if (qualifier == 'l') { + long *ip = va_arg(args, long *); + *ip = (str - buf); + } else { + int *ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + case '%': + *str++ = '%'; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + if (qualifier == 'l') + num = va_arg(args, unsigned long); + else if (qualifier == 'h') { + num = (unsigned short)va_arg(args, int); + if (flags & SIGN) + num = (short)num; + } else if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + str = number(str, num, base, field_width, precision, flags); } - - /* process flags */ - flags = 0; - repeat: - ++fmt; /* this also skips first '%' */ - switch (*fmt) { - case '-': flags |= LEFT; goto repeat; - case '+': flags |= PLUS; goto repeat; - case ' ': flags |= SPACE; goto repeat; - case '#': flags |= SPECIAL; goto repeat; - case '0': flags |= ZEROPAD; goto repeat; - } - - /* get field width */ - field_width = -1; - if (isdigit(*fmt)) - field_width = skip_atou(&fmt); - else if (*fmt == '*') { - ++fmt; - /* it's the next argument */ - field_width = va_arg(args, int); - if (field_width < 0) { - field_width = -field_width; - flags |= LEFT; - } - } - - /* get the precision */ - precision = -1; - if (*fmt == '.') { - ++fmt; - if (isdigit(*fmt)) - precision = skip_atou(&fmt); - else if (*fmt == '*') { - ++fmt; - /* it's the next argument */ - precision = va_arg(args, int); - } - if (precision < 0) - precision = 0; - } - - /* get the conversion qualifier */ - qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { - qualifier = *fmt; - ++fmt; - } - - /* default base */ - base = 10; - - switch (*fmt) { - case 'c': - if (!(flags & LEFT)) - while (--field_width > 0) - *str++ = ' '; - *str++ = (unsigned char) va_arg(args, int); - while (--field_width > 0) - *str++ = ' '; - continue; - - case 's': - s = va_arg(args, char *); - len = strnlen(s, precision); - - if (!(flags & LEFT)) - while (len < field_width--) - *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = ' '; - continue; - - case 'p': - if (field_width == -1) { - field_width = 2*sizeof(void *); - flags |= ZEROPAD; - } - str = number(str, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); - continue; - - - case 'n': - if (qualifier == 'l') { - long * ip = va_arg(args, long *); - *ip = (str - buf); - } else { - int * ip = va_arg(args, int *); - *ip = (str - buf); - } - continue; - - case '%': - *str++ = '%'; - continue; - - /* integer number formats - set up the flags and "break" */ - case 'o': - base = 8; - break; - - case 'X': - flags |= LARGE; - case 'x': - base = 16; - break; - - case 'd': - case 'i': - flags |= SIGN; - case 'u': - break; - - default: - *str++ = '%'; - if (*fmt) - *str++ = *fmt; - else - --fmt; - continue; - } - if (qualifier == 'l') - num = va_arg(args, unsigned long); - else if (qualifier == 'h') { - num = (unsigned short) va_arg(args, int); - if (flags & SIGN) - num = (short) num; - } else if (flags & SIGN) - num = va_arg(args, int); - else - num = va_arg(args, unsigned int); - str = number(str, num, base, field_width, precision, flags); - } - *str = '\0'; - return str-buf; + *str = '\0'; + return str - buf; } -int sprintf(char * buf, const char *fmt, ...) +int sprintf(char *buf, const char *fmt, ...) { - va_list args; - int i; + va_list args; + int i; - va_start(args, fmt); - i=vsprintf(buf,fmt,args); - va_end(args); - return i; + va_start(args, fmt); + i = vsprintf(buf, fmt, args); + va_end(args); + return i; } int printf(const char *fmt, ...) { - char printf_buf[1024]; - va_list args; - int printed; + char printf_buf[1024]; + va_list args; + int printed; - va_start(args, fmt); - printed = vsprintf(printf_buf, fmt, args); - va_end(args); + va_start(args, fmt); + printed = vsprintf(printf_buf, fmt, args); + va_end(args); - puts(printf_buf); + puts(printf_buf); - return printed; + return printed; } diff --git a/dos/skipatou.c b/dos/skipatou.c index f71c5342..655ab565 100644 --- a/dos/skipatou.c +++ b/dos/skipatou.c @@ -2,9 +2,9 @@ unsigned int skip_atou(const char **s) { - int i=0; + int i = 0; - while (isdigit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; + while (isdigit(**s)) + i = i * 10 + *((*s)++) - '0'; + return i; } diff --git a/dos/stdint.h b/dos/stdint.h index 9a5553b9..a8391bf9 100644 --- a/dos/stdint.h +++ b/dos/stdint.h @@ -7,49 +7,49 @@ /* Exact types */ -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef signed long long int64_t; +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef signed long long int64_t; -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; /* Small types */ -typedef signed char int_least8_t; -typedef signed short int_least16_t; -typedef signed int int_least32_t; -typedef signed long long int_least64_t; +typedef signed char int_least8_t; +typedef signed short int_least16_t; +typedef signed int int_least32_t; +typedef signed long long int_least64_t; -typedef unsigned char uint_least8_t; -typedef unsigned short uint_least16_t; -typedef unsigned int uint_least32_t; -typedef unsigned long long uint_least64_t; +typedef unsigned char uint_least8_t; +typedef unsigned short uint_least16_t; +typedef unsigned int uint_least32_t; +typedef unsigned long long uint_least64_t; /* Fast types */ -typedef signed char int_fast8_t; -typedef signed short int_fast16_t; -typedef signed int int_fast32_t; -typedef signed long long int_fast64_t; +typedef signed char int_fast8_t; +typedef signed short int_fast16_t; +typedef signed int int_fast32_t; +typedef signed long long int_fast64_t; -typedef unsigned char uint_fast8_t; -typedef unsigned short uint_fast16_t; -typedef unsigned int uint_fast32_t; -typedef unsigned long long uint_fast64_t; +typedef unsigned char uint_fast8_t; +typedef unsigned short uint_fast16_t; +typedef unsigned int uint_fast32_t; +typedef unsigned long long uint_fast64_t; /* Pointer types */ -typedef int32_t intptr_t; -typedef uint32_t uintptr_t; +typedef int32_t intptr_t; +typedef uint32_t uintptr_t; /* Maximal types */ -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; /* * To be strictly correct... diff --git a/dos/stdio.h b/dos/stdio.h index 97988c24..2c256669 100644 --- a/dos/stdio.h +++ b/dos/stdio.h @@ -8,7 +8,7 @@ typedef unsigned int off_t; int putchar(int); int puts(const char *); -int sprintf(char * buf, const char *fmt, ...); +int sprintf(char *buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args); int printf(const char *fmt, ...); diff --git a/dos/stdlib.h b/dos/stdlib.h index 08045177..71af6907 100644 --- a/dos/stdlib.h +++ b/dos/stdlib.h @@ -4,7 +4,7 @@ typedef int ssize_t; typedef unsigned int size_t; -void __attribute__((noreturn)) exit(int); +void __attribute__ ((noreturn)) exit(int); void *malloc(size_t); void *calloc(size_t, size_t); diff --git a/dos/string.h b/dos/string.h index 44f77dac..8f8c8967 100644 --- a/dos/string.h +++ b/dos/string.h @@ -14,10 +14,10 @@ /* This only returns true or false */ static inline int memcmp(const void *__m1, const void *__m2, unsigned int __n) { - _Bool rv; - asm volatile("cld ; repe ; cmpsb ; setne %0" - : "=abd" (rv), "+D" (__m1), "+S" (__m2), "+c" (__n)); - return rv; + _Bool rv; + asm volatile ("cld ; repe ; cmpsb ; setne %0":"=abd" (rv), "+D"(__m1), + "+S"(__m2), "+c"(__n)); + return rv; } #endif /* _STRING_H */ diff --git a/dos/syslinux.c b/dos/syslinux.c index 6bbdada8..212cfced 100644 --- a/dos/syslinux.c +++ b/dos/syslinux.c @@ -25,7 +25,7 @@ #include "syslinux.h" #include "libfat.h" -const char *program = "syslinux"; /* Name of program */ +const char *program = "syslinux"; /* Name of program */ uint16_t dos_version; #ifdef DEBUG @@ -34,28 +34,28 @@ uint16_t dos_version; # define dprintf(...) ((void)0) #endif -void __attribute__((noreturn)) usage(void) +void __attribute__ ((noreturn)) usage(void) { - puts("Usage: syslinux [-sfmar][-d directory] <drive>: [bootsecfile]\n"); - exit(1); + puts("Usage: syslinux [-sfmar][-d directory] <drive>: [bootsecfile]\n"); + exit(1); } void unlock_device(int); -void __attribute__((noreturn)) die(const char *msg) +void __attribute__ ((noreturn)) die(const char *msg) { - unlock_device(0); - puts("syslinux: "); - puts(msg); - putchar('\n'); - exit(1); + unlock_device(0); + puts("syslinux: "); + puts(msg); + putchar('\n'); + exit(1); } void warning(const char *msg) { - puts("syslinux: warning: "); - puts(msg); - putchar('\n'); + puts("syslinux: warning: "); + puts(msg); + putchar('\n'); } /* @@ -63,55 +63,52 @@ void warning(const char *msg) */ int creat(const char *filename, int mode) { - uint16_t rv; - uint8_t err; + uint16_t rv; + uint8_t err; - dprintf("creat(\"%s\", 0x%x)\n", filename, mode); + dprintf("creat(\"%s\", 0x%x)\n", filename, mode); - rv = 0x3C00; - asm volatile("int $0x21 ; setc %0" - : "=bcdm" (err), "+a" (rv) - : "c" (mode), "d" (filename)); - if ( err ) { - dprintf("rv = %d\n", rv); - die("cannot open ldlinux.sys"); - } + rv = 0x3C00; + asm volatile ("int $0x21 ; setc %0":"=bcdm" (err), "+a"(rv) + :"c"(mode), "d"(filename)); + if (err) { + dprintf("rv = %d\n", rv); + die("cannot open ldlinux.sys"); + } - return rv; + return rv; } void close(int fd) { - uint16_t rv = 0x3E00; + uint16_t rv = 0x3E00; - dprintf("close(%d)\n", fd); + dprintf("close(%d)\n", fd); - asm volatile("int $0x21" - : "+a" (rv) - : "b" (fd)); + asm volatile ("int $0x21":"+a" (rv) + :"b"(fd)); - /* The only error MS-DOS returns for close is EBADF, - and we really don't care... */ + /* The only error MS-DOS returns for close is EBADF, + and we really don't care... */ } int rename(const char *oldname, const char *newname) { - uint16_t rv = 0x5600; /* Also support 43FFh? */ - uint8_t err; + uint16_t rv = 0x5600; /* Also support 43FFh? */ + uint8_t err; - dprintf("rename(\"%s\", \"%s\")\n", oldname, newname); + dprintf("rename(\"%s\", \"%s\")\n", oldname, newname); - asm volatile("int $0x21 ; setc %0" - : "=bcdm" (err), "+a" (rv) - : "d" (oldname), "D" (newname)); + asm volatile ("int $0x21 ; setc %0":"=bcdm" (err), "+a"(rv) + :"d"(oldname), "D"(newname)); - if ( err ) { - dprintf("rv = %d\n", rv); - warning("cannot move ldlinux.sys"); - return rv; - } + if (err) { + dprintf("rv = %d\n", rv); + warning("cannot move ldlinux.sys"); + return rv; + } - return 0; + return 0; } extern const char __payload_sseg[]; @@ -119,257 +116,247 @@ uint16_t ldlinux_seg; ssize_t write_ldlinux(int fd) { - uint32_t offset = 0; - uint16_t rv; - uint8_t err; - - while (offset < syslinux_ldlinux_len) { - uint32_t chunk = syslinux_ldlinux_len - offset; - if (chunk > 32768) - chunk = 32768; - asm volatile("pushw %%ds ; " - "movw %6,%%ds ; " - "int $0x21 ; " - "popw %%ds ; " - "setc %0" - : "=bcdm" (err), "=a" (rv) - : "a" (0x4000), "b" (fd), "c" (chunk), "d" (offset & 15), - "SD" ((uint16_t)(ldlinux_seg + (offset >> 4)))); - if ( err || rv == 0 ) - die("file write error"); - offset += rv; - } - - return offset; + uint32_t offset = 0; + uint16_t rv; + uint8_t err; + + while (offset < syslinux_ldlinux_len) { + uint32_t chunk = syslinux_ldlinux_len - offset; + if (chunk > 32768) + chunk = 32768; + asm volatile ("pushw %%ds ; " + "movw %6,%%ds ; " + "int $0x21 ; " + "popw %%ds ; " "setc %0":"=bcdm" (err), "=a"(rv) + :"a"(0x4000), "b"(fd), "c"(chunk), "d"(offset & 15), + "SD"((uint16_t) (ldlinux_seg + (offset >> 4)))); + if (err || rv == 0) + die("file write error"); + offset += rv; + } + + return offset; } ssize_t write_file(int fd, const void *buf, size_t count) { - uint16_t rv; - ssize_t done = 0; - uint8_t err; + uint16_t rv; + ssize_t done = 0; + uint8_t err; - dprintf("write_file(%d,%p,%u)\n", fd, buf, count); + dprintf("write_file(%d,%p,%u)\n", fd, buf, count); - while ( count ) { - asm volatile("int $0x21 ; setc %0" - : "=bcdm" (err), "=a" (rv) - : "a" (0x4000), "b" (fd), "c" (count), "d" (buf)); - if ( err || rv == 0 ) - die("file write error"); + while (count) { + asm volatile ("int $0x21 ; setc %0":"=bcdm" (err), "=a"(rv) + :"a"(0x4000), "b"(fd), "c"(count), "d"(buf)); + if (err || rv == 0) + die("file write error"); - done += rv; - count -= rv; - } + done += rv; + count -= rv; + } - return done; + return done; } -static inline __attribute__((const)) uint16_t data_segment(void) +static inline __attribute__ ((const)) +uint16_t data_segment(void) { - uint16_t ds; + uint16_t ds; - asm("movw %%ds,%0" : "=rm" (ds)); - return ds; +asm("movw %%ds,%0":"=rm"(ds)); + return ds; } struct diskio { - uint32_t startsector; - uint16_t sectors; - uint16_t bufoffs, bufseg; -} __attribute__((packed)); + uint32_t startsector; + uint16_t sectors; + uint16_t bufoffs, bufseg; +} __attribute__ ((packed)); void write_device(int drive, const void *buf, size_t nsecs, unsigned int sector) { - uint8_t err; - struct diskio dio; + uint8_t err; + struct diskio dio; - dprintf("write_device(%d,%p,%u,%u)\n", drive, buf, nsecs, sector); + dprintf("write_device(%d,%p,%u,%u)\n", drive, buf, nsecs, sector); - dio.startsector = sector; - dio.sectors = nsecs; - dio.bufoffs = (uintptr_t)buf; - dio.bufseg = data_segment(); + dio.startsector = sector; + dio.sectors = nsecs; + dio.bufoffs = (uintptr_t) buf; + dio.bufseg = data_segment(); - asm volatile("int $0x26 ; setc %0 ; popfw" - : "=abcdm" (err) - : "a" (drive-1), "b" (&dio), "c" (-1), "d" (buf), "m" (dio)); + asm volatile ("int $0x26 ; setc %0 ; popfw":"=abcdm" (err) + :"a"(drive - 1), "b"(&dio), "c"(-1), "d"(buf), "m"(dio)); - if ( err ) - die("sector write error"); + if (err) + die("sector write error"); } void read_device(int drive, const void *buf, size_t nsecs, unsigned int sector) { - uint8_t err; - struct diskio dio; + uint8_t err; + struct diskio dio; - dprintf("read_device(%d,%p,%u,%u)\n", drive, buf, nsecs, sector); + dprintf("read_device(%d,%p,%u,%u)\n", drive, buf, nsecs, sector); - dio.startsector = sector; - dio.sectors = nsecs; - dio.bufoffs = (uintptr_t)buf; - dio.bufseg = data_segment(); + dio.startsector = sector; + dio.sectors = nsecs; + dio.bufoffs = (uintptr_t) buf; + dio.bufseg = data_segment(); - asm volatile("int $0x25 ; setc %0 ; popfw" - : "=abcdm" (err) - : "a" (drive-1), "b" (&dio), "c" (-1), "d" (buf), "m" (dio)); + asm volatile ("int $0x25 ; setc %0 ; popfw":"=abcdm" (err) + :"a"(drive - 1), "b"(&dio), "c"(-1), "d"(buf), "m"(dio)); - if ( err ) - die("sector read error"); + if (err) + die("sector read error"); } /* Both traditional DOS and FAT32 DOS return this structure, but FAT32 return a lot more data, so make sure we have plenty of space */ struct deviceparams { - uint8_t specfunc; - uint8_t devtype; - uint16_t devattr; - uint16_t cylinders; - uint8_t mediatype; - uint16_t bytespersec; - uint8_t secperclust; - uint16_t ressectors; - uint8_t fats; - uint16_t rootdirents; - uint16_t sectors; - uint8_t media; - uint16_t fatsecs; - uint16_t secpertrack; - uint16_t heads; - uint32_t hiddensecs; - uint32_t hugesectors; - uint8_t lotsofpadding[224]; -} __attribute__((packed)); + uint8_t specfunc; + uint8_t devtype; + uint16_t devattr; + uint16_t cylinders; + uint8_t mediatype; + uint16_t bytespersec; + uint8_t secperclust; + uint16_t ressectors; + uint8_t fats; + uint16_t rootdirents; + uint16_t sectors; + uint8_t media; + uint16_t fatsecs; + uint16_t secpertrack; + uint16_t heads; + uint32_t hiddensecs; + uint32_t hugesectors; + uint8_t lotsofpadding[224]; +} __attribute__ ((packed)); uint32_t get_partition_offset(int drive) { - uint8_t err; - uint16_t rv; - struct deviceparams dp; + uint8_t err; + uint16_t rv; + struct deviceparams dp; - dp.specfunc = 1; /* Get current information */ + dp.specfunc = 1; /* Get current information */ - rv = 0x440d; - asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv), "=m" (dp) - : "b" (drive), "c" (0x0860), "d" (&dp)); + rv = 0x440d; + asm volatile ("int $0x21 ; setc %0":"=abcdm" (err), "+a"(rv), "=m"(dp) + :"b"(drive), "c"(0x0860), "d"(&dp)); - if ( !err ) - return dp.hiddensecs; + if (!err) + return dp.hiddensecs; - rv = 0x440d; - asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv), "=m" (dp) - : "b" (drive), "c" (0x4860), "d" (&dp)); + rv = 0x440d; + asm volatile ("int $0x21 ; setc %0":"=abcdm" (err), "+a"(rv), "=m"(dp) + :"b"(drive), "c"(0x4860), "d"(&dp)); - if ( !err ) - return dp.hiddensecs; + if (!err) + return dp.hiddensecs; - die("could not find partition start offset"); + die("could not find partition start offset"); } struct rwblock { - uint8_t special; - uint16_t head; - uint16_t cylinder; - uint16_t firstsector; - uint16_t sectors; - uint16_t bufferoffset; - uint16_t bufferseg; -} __attribute__((packed)); + uint8_t special; + uint16_t head; + uint16_t cylinder; + uint16_t firstsector; + uint16_t sectors; + uint16_t bufferoffset; + uint16_t bufferseg; +} __attribute__ ((packed)); static struct rwblock mbr = { - .special = 0, - .head = 0, - .cylinder = 0, - .firstsector = 0, /* MS-DOS, unlike the BIOS, zero-base sectors */ - .sectors = 1, - .bufferoffset = 0, - .bufferseg = 0 + .special = 0, + .head = 0, + .cylinder = 0, + .firstsector = 0, /* MS-DOS, unlike the BIOS, zero-base sectors */ + .sectors = 1, + .bufferoffset = 0, + .bufferseg = 0 }; void write_mbr(int drive, const void *buf) { - uint16_t rv; - uint8_t err; + uint16_t rv; + uint8_t err; - dprintf("write_mbr(%d,%p)\n", drive, buf); + dprintf("write_mbr(%d,%p)\n", drive, buf); - mbr.bufferoffset = (uintptr_t)buf; - mbr.bufferseg = data_segment(); + mbr.bufferoffset = (uintptr_t) buf; + mbr.bufferseg = data_segment(); - rv = 0x440d; - asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv) - : "c" (0x0841), "d" (&mbr), "b" (drive), "m" (mbr)); + rv = 0x440d; + asm volatile ("int $0x21 ; setc %0":"=abcdm" (err), "+a"(rv) + :"c"(0x0841), "d"(&mbr), "b"(drive), "m"(mbr)); - if ( !err ) - return; + if (!err) + return; - rv = 0x440d; - asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv) - : "c" (0x4841), "d" (&mbr), "b" (drive), "m" (mbr)); + rv = 0x440d; + asm volatile ("int $0x21 ; setc %0":"=abcdm" (err), "+a"(rv) + :"c"(0x4841), "d"(&mbr), "b"(drive), "m"(mbr)); - if ( err ) - die("mbr write error"); + if (err) + die("mbr write error"); } void read_mbr(int drive, const void *buf) { - uint16_t rv; - uint8_t err; + uint16_t rv; + uint8_t err; - dprintf("read_mbr(%d,%p)\n", drive, buf); + dprintf("read_mbr(%d,%p)\n", drive, buf); - mbr.bufferoffset = (uintptr_t)buf; - mbr.bufferseg = data_segment(); + mbr.bufferoffset = (uintptr_t) buf; + mbr.bufferseg = data_segment(); - rv = 0x440d; - asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv) - : "c" (0x0861), "d" (&mbr), "b" (drive), "m" (mbr)); + rv = 0x440d; + asm volatile ("int $0x21 ; setc %0":"=abcdm" (err), "+a"(rv) + :"c"(0x0861), "d"(&mbr), "b"(drive), "m"(mbr)); - if ( !err ) - return; + if (!err) + return; - rv = 0x440d; - asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv) - : "c" (0x4861), "d" (&mbr), "b" (drive), "m" (mbr)); + rv = 0x440d; + asm volatile ("int $0x21 ; setc %0":"=abcdm" (err), "+a"(rv) + :"c"(0x4861), "d"(&mbr), "b"(drive), "m"(mbr)); - if ( err ) - die("mbr read error"); + if (err) + die("mbr read error"); } /* This call can legitimately fail, and we don't care, so ignore error return */ void set_attributes(const char *file, int attributes) { - uint16_t rv = 0x4301; + uint16_t rv = 0x4301; - dprintf("set_attributes(\"%s\", 0x%02x)\n", file, attributes); + dprintf("set_attributes(\"%s\", 0x%02x)\n", file, attributes); - asm volatile("int $0x21" - : "+a" (rv) - : "c" (attributes), "d" (file)); + asm volatile ("int $0x21":"+a" (rv) + :"c"(attributes), "d"(file)); } /* * Version of the read_device function suitable for libfat */ -int libfat_xpread(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sector) +int libfat_xpread(intptr_t pp, void *buf, size_t secsize, + libfat_sector_t sector) { - read_device(pp, buf, 1, sector); - return secsize; + read_device(pp, buf, 1, sector); + return secsize; } static inline void get_dos_version(void) { - uint16_t ver = 0x3001; - asm("int $0x21 ; xchgb %%ah,%%al" : "+a" (ver) : : "ebx", "ecx"); - dos_version = ver; - dprintf("DOS version %d.%d\n", (dos_version >> 8), dos_version & 0xff); + uint16_t ver = 0x3001; +asm("int $0x21 ; xchgb %%ah,%%al": "+a"(ver): :"ebx", "ecx"); + dos_version = ver; + dprintf("DOS version %d.%d\n", (dos_version >> 8), dos_version & 0xff); } /* The locking interface relies on static variables. A massive hack :( */ @@ -377,349 +364,347 @@ static uint16_t lock_level; static inline void set_lock_device(uint8_t device) { - lock_level = device; + lock_level = device; } void lock_device(int level) { - uint16_t rv; - uint8_t err; - uint16_t lock_call; + uint16_t rv; + uint8_t err; + uint16_t lock_call; - if ( dos_version < 0x0700 ) - return; /* Win9x/NT only */ + if (dos_version < 0x0700) + return; /* Win9x/NT only */ #if 0 - /* DOS 7.10 = Win95 OSR2 = first version with FAT32 */ - lock_call = (dos_version >= 0x0710) ? 0x484A : 0x084A; + /* DOS 7.10 = Win95 OSR2 = first version with FAT32 */ + lock_call = (dos_version >= 0x0710) ? 0x484A : 0x084A; #else - lock_call = 0x084A; /* MSDN says this is OK for all filesystems */ + lock_call = 0x084A; /* MSDN says this is OK for all filesystems */ #endif - while ( (lock_level >> 8) < level ) { - uint16_t new_level = lock_level + 0x0100; - dprintf("Trying lock %04x...\n", new_level); - rv = 0x444d; - asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv) - : "b" (new_level), "c" (lock_call), "d"(0x0001)); - if ( err ) { - /* rv == 0x0001 means this call is not supported, if so we - assume locking isn't needed (e.g. Win9x in DOS-only mode) */ - if ( rv == 0x0001 ) - return; - else - die("could not lock device"); - } + while ((lock_level >> 8) < level) { + uint16_t new_level = lock_level + 0x0100; + dprintf("Trying lock %04x...\n", new_level); + rv = 0x444d; + asm volatile ("int $0x21 ; setc %0":"=abcdm" (err), "+a"(rv) + :"b"(new_level), "c"(lock_call), "d"(0x0001)); + if (err) { + /* rv == 0x0001 means this call is not supported, if so we + assume locking isn't needed (e.g. Win9x in DOS-only mode) */ + if (rv == 0x0001) + return; + else + die("could not lock device"); + } - lock_level = new_level; - } - return; + lock_level = new_level; + } + return; } void unlock_device(int level) { - uint16_t rv; - uint8_t err; - uint16_t unlock_call; + uint16_t rv; + uint8_t err; + uint16_t unlock_call; - if ( dos_version < 0x0700 ) - return; /* Win9x/NT only */ + if (dos_version < 0x0700) + return; /* Win9x/NT only */ #if 0 - /* DOS 7.10 = Win95 OSR2 = first version with FAT32 */ - unlock_call = (dos_version >= 0x0710) ? 0x486A : 0x086A; + /* DOS 7.10 = Win95 OSR2 = first version with FAT32 */ + unlock_call = (dos_version >= 0x0710) ? 0x486A : 0x086A; #else - unlock_call = 0x086A; /* MSDN says this is OK for all filesystems */ + unlock_call = 0x086A; /* MSDN says this is OK for all filesystems */ #endif - while ( (lock_level >> 8) > level ) { - uint16_t new_level = lock_level - 0x0100; - rv = 0x440d; - asm volatile("int $0x21 ; setc %0" - : "=abcdm" (err), "+a" (rv) - : "b" (new_level), "c" (unlock_call)); - lock_level = new_level; - } + while ((lock_level >> 8) > level) { + uint16_t new_level = lock_level - 0x0100; + rv = 0x440d; + asm volatile ("int $0x21 ; setc %0":"=abcdm" (err), "+a"(rv) + :"b"(new_level), "c"(unlock_call)); + lock_level = new_level; + } } - /* * This function does any desired MBR manipulation; called with the device lock held. */ struct mbr_entry { - uint8_t active; /* Active flag */ - uint8_t bhead; /* Begin head */ - uint8_t bsector; /* Begin sector */ - uint8_t bcylinder; /* Begin cylinder */ - uint8_t filesystem; /* Filesystem value */ - uint8_t ehead; /* End head */ - uint8_t esector; /* End sector */ - uint8_t ecylinder; /* End cylinder */ - uint32_t startlba; /* Start sector LBA */ - uint32_t sectors; /* Length in sectors */ -} __attribute__((packed)); + uint8_t active; /* Active flag */ + uint8_t bhead; /* Begin head */ + uint8_t bsector; /* Begin sector */ + uint8_t bcylinder; /* Begin cylinder */ + uint8_t filesystem; /* Filesystem value */ + uint8_t ehead; /* End head */ + uint8_t esector; /* End sector */ + uint8_t ecylinder; /* End cylinder */ + uint32_t startlba; /* Start sector LBA */ + uint32_t sectors; /* Length in sectors */ +} __attribute__ ((packed)); static void adjust_mbr(int device, int writembr, int set_active) { - static unsigned char sectbuf[SECTOR_SIZE]; - int i; - - if ( !writembr && !set_active ) - return; /* Nothing to do */ - - read_mbr(device, sectbuf); - - if ( writembr ) { - memcpy(sectbuf, syslinux_mbr, syslinux_mbr_len); - *(uint16_t *)(sectbuf+510) = 0xaa55; - } - - if ( set_active ) { - uint32_t offset = get_partition_offset(device); - struct mbr_entry *me = (struct mbr_entry *)(sectbuf+446); - int found = 0; - - for ( i = 0 ; i < 4 ; i++ ) { - if ( me->startlba == offset ) { - me->active = 0x80; - found++; - } else { - me->active = 0; - } - me++; + static unsigned char sectbuf[SECTOR_SIZE]; + int i; + + if (!writembr && !set_active) + return; /* Nothing to do */ + + read_mbr(device, sectbuf); + + if (writembr) { + memcpy(sectbuf, syslinux_mbr, syslinux_mbr_len); + *(uint16_t *) (sectbuf + 510) = 0xaa55; } - if ( found < 1 ) { - die("partition not found"); - } else if ( found > 1 ) { - die("multiple aliased partitions found"); + if (set_active) { + uint32_t offset = get_partition_offset(device); + struct mbr_entry *me = (struct mbr_entry *)(sectbuf + 446); + int found = 0; + + for (i = 0; i < 4; i++) { + if (me->startlba == offset) { + me->active = 0x80; + found++; + } else { + me->active = 0; + } + me++; + } + + if (found < 1) { + die("partition not found"); + } else if (found > 1) { + die("multiple aliased partitions found"); + } } - } - write_mbr(device, sectbuf); + write_mbr(device, sectbuf); } int main(int argc, char *argv[]) { - static unsigned char sectbuf[SECTOR_SIZE]; - int dev_fd, fd; - static char ldlinux_name[] = "@:\\ldlinux.sys"; - char **argp, *opt; - int force = 0; /* -f (force) option */ - struct libfat_filesystem *fs; - libfat_sector_t s, *secp; - libfat_sector_t *sectors; - int ldlinux_sectors; - int32_t ldlinux_cluster; - int nsectors; - const char *device = NULL, *bootsecfile = NULL; - const char *errmsg; - int i; - int writembr = 0; /* -m (write MBR) option */ - int set_active = 0; /* -a (set partition active) option */ - const char *subdir = NULL; - int stupid = 0; - int raid_mode = 0; - int patch_sectors; - - ldlinux_seg = (size_t)__payload_sseg + data_segment(); - - dprintf("argv = %p\n", argv); - for ( i = 0 ; i <= argc ; i++ ) - dprintf("argv[%d] = %p = \"%s\"\n", i, argv[i], argv[i]); - - (void)argc; /* Unused */ - - get_dos_version(); - - for ( argp = argv+1 ; *argp ; argp++ ) { - if ( **argp == '-' ) { - opt = *argp + 1; - if ( !*opt ) + static unsigned char sectbuf[SECTOR_SIZE]; + int dev_fd, fd; + static char ldlinux_name[] = "@:\\ldlinux.sys"; + char **argp, *opt; + int force = 0; /* -f (force) option */ + struct libfat_filesystem *fs; + libfat_sector_t s, *secp; + libfat_sector_t *sectors; + int ldlinux_sectors; + int32_t ldlinux_cluster; + int nsectors; + const char *device = NULL, *bootsecfile = NULL; + const char *errmsg; + int i; + int writembr = 0; /* -m (write MBR) option */ + int set_active = 0; /* -a (set partition active) option */ + const char *subdir = NULL; + int stupid = 0; + int raid_mode = 0; + int patch_sectors; + + ldlinux_seg = (size_t) __payload_sseg + data_segment(); + + dprintf("argv = %p\n", argv); + for (i = 0; i <= argc; i++) + dprintf("argv[%d] = %p = \"%s\"\n", i, argv[i], argv[i]); + + (void)argc; /* Unused */ + + get_dos_version(); + + for (argp = argv + 1; *argp; argp++) { + if (**argp == '-') { + opt = *argp + 1; + if (!*opt) + usage(); + + while (*opt) { + switch (*opt) { + case 's': /* Use "safe, slow and stupid" code */ + stupid = 1; + break; + case 'r': /* RAID mode */ + raid_mode = 1; + break; + case 'f': /* Force install */ + force = 1; + break; + case 'm': /* Write MBR */ + writembr = 1; + break; + case 'a': /* Set partition active */ + set_active = 1; + break; + case 'd': + if (argp[1]) + subdir = *++argp; + break; + default: + usage(); + } + opt++; + } + } else { + if (bootsecfile) + usage(); + else if (device) + bootsecfile = *argp; + else + device = *argp; + } + } + + if (!device) usage(); - while ( *opt ) { - switch ( *opt ) { - case 's': /* Use "safe, slow and stupid" code */ - stupid = 1; - break; - case 'r': /* RAID mode */ - raid_mode = 1; - break; - case 'f': /* Force install */ - force = 1; - break; - case 'm': /* Write MBR */ - writembr = 1; - break; - case 'a': /* Set partition active */ - set_active = 1; - break; - case 'd': - if ( argp[1] ) - subdir = *++argp; - break; - default: - usage(); - } - opt++; - } - } else { - if ( bootsecfile ) + /* + * Figure out which drive we're talking to + */ + dev_fd = (device[0] & ~0x20) - 0x40; + if (dev_fd < 1 || dev_fd > 26 || device[1] != ':' || device[2]) usage(); - else if ( device ) - bootsecfile = *argp; - else - device = *argp; + + set_lock_device(dev_fd); + + lock_device(2); /* Make sure we can lock the device */ + read_device(dev_fd, sectbuf, 1, 0); + unlock_device(1); + + /* + * Check to see that what we got was indeed an MS-DOS boot sector/superblock + */ + if ((errmsg = syslinux_check_bootsect(sectbuf))) { + unlock_device(0); + puts(errmsg); + putchar('\n'); + exit(1); } - } - if ( !device ) - usage(); + ldlinux_name[0] = dev_fd | 0x40; + + set_attributes(ldlinux_name, 0); + fd = creat(ldlinux_name, 0x07); /* SYSTEM HIDDEN READONLY */ + write_ldlinux(fd); + close(fd); - /* - * Figure out which drive we're talking to - */ - dev_fd = (device[0] & ~0x20) - 0x40; - if ( dev_fd < 1 || dev_fd > 26 || device[1] != ':' || device[2] ) - usage(); + /* + * Now, use libfat to create a block map. This probably + * should be changed to use ioctl(...,FIBMAP,...) since + * this is supposed to be a simple, privileged version + * of the installer. + */ + ldlinux_sectors = (syslinux_ldlinux_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT; + sectors = calloc(ldlinux_sectors, sizeof *sectors); + lock_device(2); + fs = libfat_open(libfat_xpread, dev_fd); + ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", NULL); + secp = sectors; + nsectors = 0; + s = libfat_clustertosector(fs, ldlinux_cluster); + while (s && nsectors < ldlinux_sectors) { + *secp++ = s; + nsectors++; + s = libfat_nextsector(fs, s); + } + libfat_close(fs); + + /* + * If requested, move ldlinux.sys + */ + if (subdir) { + char new_ldlinux_name[160]; + char *cp = new_ldlinux_name + 3; + const char *sd; + int slash = 1; + + new_ldlinux_name[0] = dev_fd | 0x40; + new_ldlinux_name[1] = ':'; + new_ldlinux_name[2] = '\\'; + + for (sd = subdir; *sd; sd++) { + char c = *sd; + + if (c == '/' || c == '\\') { + if (slash) + continue; + c = '\\'; + slash = 1; + } else { + slash = 0; + } + + *cp++ = c; + } - set_lock_device(dev_fd); + /* Skip if subdirectory == root */ + if (cp > new_ldlinux_name + 3) { + if (!slash) + *cp++ = '\\'; - lock_device(2); /* Make sure we can lock the device */ - read_device(dev_fd, sectbuf, 1, 0); - unlock_device(1); + memcpy(cp, "ldlinux.sys", 12); - /* - * Check to see that what we got was indeed an MS-DOS boot sector/superblock - */ - if( (errmsg = syslinux_check_bootsect(sectbuf)) ) { - unlock_device(0); - puts(errmsg); - putchar('\n'); - exit(1); - } - - ldlinux_name[0] = dev_fd | 0x40; - - set_attributes(ldlinux_name, 0); - fd = creat(ldlinux_name, 0x07); /* SYSTEM HIDDEN READONLY */ - write_ldlinux(fd); - close(fd); - - /* - * Now, use libfat to create a block map. This probably - * should be changed to use ioctl(...,FIBMAP,...) since - * this is supposed to be a simple, privileged version - * of the installer. - */ - ldlinux_sectors = (syslinux_ldlinux_len+SECTOR_SIZE-1) >> SECTOR_SHIFT; - sectors = calloc(ldlinux_sectors, sizeof *sectors); - lock_device(2); - fs = libfat_open(libfat_xpread, dev_fd); - ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", NULL); - secp = sectors; - nsectors = 0; - s = libfat_clustertosector(fs, ldlinux_cluster); - while ( s && nsectors < ldlinux_sectors ) { - *secp++ = s; - nsectors++; - s = libfat_nextsector(fs, s); - } - libfat_close(fs); - - /* - * If requested, move ldlinux.sys - */ - if (subdir) { - char new_ldlinux_name[160]; - char *cp = new_ldlinux_name+3; - const char *sd; - int slash = 1; - - new_ldlinux_name[0] = dev_fd | 0x40; - new_ldlinux_name[1] = ':'; - new_ldlinux_name[2] = '\\'; - - for (sd = subdir; *sd; sd++) { - char c = *sd; - - if (c == '/' || c == '\\') { - if (slash) - continue; - c = '\\'; - slash = 1; - } else { - slash = 0; - } - - *cp++ = c; + set_attributes(ldlinux_name, 0); + if (rename(ldlinux_name, new_ldlinux_name)) + set_attributes(ldlinux_name, 0x07); + else + set_attributes(new_ldlinux_name, 0x07); + } } - /* Skip if subdirectory == root */ - if (cp > new_ldlinux_name+3) { - if (!slash) - *cp++ = '\\'; + /* + * Patch ldlinux.sys and the boot sector + */ + i = syslinux_patch(sectors, nsectors, stupid, raid_mode); + patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT; + + /* + * Overwrite the now-patched ldlinux.sys + */ + lock_device(3); + for (i = 0; i < patch_sectors; i++) { + uint16_t si, di, cx; + si = 0; + di = (size_t) sectbuf; + cx = SECTOR_SIZE >> 2; + asm volatile ("movw %3,%%fs ; fs ; rep ; movsl":"+S" (si), "+D"(di), + "+c"(cx) + :"abd"((uint16_t) + (ldlinux_seg + (i << (SECTOR_SHIFT - 4))))); + write_device(dev_fd, sectbuf, 1, sectors[i]); + } - memcpy(cp, "ldlinux.sys", 12); + /* + * Muck with the MBR, if desired, while we hold the lock + */ + adjust_mbr(dev_fd, writembr, set_active); - set_attributes(ldlinux_name, 0); - if (rename(ldlinux_name, new_ldlinux_name)) - set_attributes(ldlinux_name, 0x07); - else - set_attributes(new_ldlinux_name, 0x07); + /* + * To finish up, write the boot sector + */ + + /* Read the superblock again since it might have changed while mounted */ + read_device(dev_fd, sectbuf, 1, 0); + + /* Copy the syslinux code into the boot sector */ + syslinux_make_bootsect(sectbuf); + + /* Write new boot sector */ + if (bootsecfile) { + unlock_device(0); + fd = creat(bootsecfile, 0x20); /* ARCHIVE */ + write_file(fd, sectbuf, SECTOR_SIZE); + close(fd); + } else { + write_device(dev_fd, sectbuf, 1, 0); + unlock_device(0); } - } - - /* - * Patch ldlinux.sys and the boot sector - */ - i = syslinux_patch(sectors, nsectors, stupid, raid_mode); - patch_sectors = (i+SECTOR_SIZE-1) >> SECTOR_SHIFT; - - /* - * Overwrite the now-patched ldlinux.sys - */ - lock_device(3); - for (i = 0; i < patch_sectors; i++) { - uint16_t si, di, cx; - si = 0; - di = (size_t)sectbuf; - cx = SECTOR_SIZE >> 2; - asm volatile("movw %3,%%fs ; fs ; rep ; movsl" - : "+S" (si), "+D" (di), "+c" (cx) - : "abd" ((uint16_t)(ldlinux_seg + (i << (SECTOR_SHIFT-4))))); - write_device(dev_fd, sectbuf, 1, sectors[i]); - } - - /* - * Muck with the MBR, if desired, while we hold the lock - */ - adjust_mbr(dev_fd, writembr, set_active); - - /* - * To finish up, write the boot sector - */ - - /* Read the superblock again since it might have changed while mounted */ - read_device(dev_fd, sectbuf, 1, 0); - - /* Copy the syslinux code into the boot sector */ - syslinux_make_bootsect(sectbuf); - - /* Write new boot sector */ - if ( bootsecfile ) { - unlock_device(0); - fd = creat(bootsecfile, 0x20); /* ARCHIVE */ - write_file(fd, sectbuf, SECTOR_SIZE); - close(fd); - } else { - write_device(dev_fd, sectbuf, 1, 0); - unlock_device(0); - } - /* Done! */ + /* Done! */ - return 0; + return 0; } |