(2006-08-06) rescue-bootcd

This commit is contained in:
2006-08-06 00:00:00 +02:00
parent 2f796b816a
commit decb062d20
21091 changed files with 7076462 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
__divdi3.o: __divdi3.c ./code16.h /usr/include/stdint.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h /usr/include/bits/wchar.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h

View File

@@ -0,0 +1,4 @@
__udivmoddi4.o: __udivmoddi4.c ./code16.h /usr/include/stdint.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h /usr/include/bits/wchar.h \
/usr/include/bits/wordsize.h

View File

@@ -0,0 +1,5 @@
argv.o: argv.c ./code16.h /usr/include/inttypes.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/gnu/stubs.h /usr/include/stdint.h \
/usr/include/bits/wchar.h /usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h ./stdio.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h ./stdlib.h

View File

@@ -0,0 +1 @@
atou.o: atou.c ./code16.h mystuff.h

View File

@@ -0,0 +1 @@
bootsect_bin.o: ../bootsect_bin.c ./code16.h

View File

@@ -0,0 +1,7 @@
cache.o: ../libfat/cache.c ./code16.h ./stdlib.h ../libfat/libfatint.h \
../libfat/libfat.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/inttypes.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/gnu/stubs.h /usr/include/stdint.h \
/usr/include/bits/wchar.h /usr/include/bits/wordsize.h ../libfat/fat.h \
../libfat/ulint.h

View File

@@ -0,0 +1,2 @@
conio.o: conio.c ./code16.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h mystuff.h

View File

@@ -0,0 +1,7 @@
fatchain.o: ../libfat/fatchain.c ./code16.h ../libfat/libfatint.h \
../libfat/libfat.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/inttypes.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/gnu/stubs.h /usr/include/stdint.h \
/usr/include/bits/wchar.h /usr/include/bits/wordsize.h ../libfat/fat.h \
../libfat/ulint.h

View File

@@ -0,0 +1,5 @@
free.o: free.c ./code16.h ./stdlib.h malloc.h /usr/include/stdint.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h /usr/include/bits/wchar.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h

View File

@@ -0,0 +1 @@
ldlinux_bin.o: ../ldlinux_bin.c ./code16.h

View File

@@ -0,0 +1,5 @@
malloc.o: malloc.c ./code16.h ./stdlib.h malloc.h /usr/include/stdint.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h /usr/include/bits/wchar.h \
/usr/include/bits/wordsize.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h

View File

@@ -0,0 +1 @@
mbr_bin.o: ../mbr_bin.c ./code16.h

View File

@@ -0,0 +1,7 @@
open.o: ../libfat/open.c ./code16.h ./stdlib.h ../libfat/libfatint.h \
../libfat/libfat.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/inttypes.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/gnu/stubs.h /usr/include/stdint.h \
/usr/include/bits/wchar.h /usr/include/bits/wordsize.h ../libfat/fat.h \
../libfat/ulint.h

View File

@@ -0,0 +1,3 @@
printf.o: printf.c ./code16.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h ./stdio.h \
./stdlib.h mystuff.h

View File

@@ -0,0 +1,7 @@
searchdir.o: ../libfat/searchdir.c ./code16.h ./string.h \
../libfat/libfatint.h ../libfat/libfat.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h \
/usr/include/inttypes.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/gnu/stubs.h /usr/include/stdint.h \
/usr/include/bits/wchar.h /usr/include/bits/wordsize.h ../libfat/fat.h \
../libfat/ulint.h

View File

@@ -0,0 +1 @@
skipatou.o: skipatou.c ./code16.h mystuff.h

View File

@@ -0,0 +1,8 @@
syslinux.o: syslinux.c ./code16.h ./errno.h ./stdio.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h ./stdlib.h \
./string.h mystuff.h ../syslinux.h /usr/include/inttypes.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h /usr/include/stdint.h \
/usr/include/bits/wchar.h /usr/include/bits/wordsize.h \
../libfat/libfat.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h

View File

@@ -0,0 +1,6 @@
syslxmod.o: ../syslxmod.c ./code16.h ./stdio.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h ./stdlib.h \
/usr/include/inttypes.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/gnu/stubs.h /usr/include/stdint.h \
/usr/include/bits/wchar.h /usr/include/bits/wordsize.h ./string.h \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stddef.h ../syslinux.h

View File

@@ -0,0 +1,60 @@
CC = gcc -m32 -mregparm=3 -DREGPARM=3
LD = ld -m elf_i386
OBJCOPY = objcopy
OPTFLAGS = -g -Os -march=i386 -falign-functions=0 -falign-jumps=0 -falign-loops=0 -fomit-frame-pointer
INCLUDES = -include code16.h -I. -I.. -I../libfat
CFLAGS = -W -Wall -ffreestanding -msoft-float $(OPTFLAGS) $(INCLUDES)
LDFLAGS = -T com16.ld
AR = ar
RANLIB = ranlib
LIBGCC := $(shell $(CC) --print-libgcc)
SRCS = syslinux.c \
../syslxmod.c ../bootsect_bin.c ../ldlinux_bin.c ../mbr_bin.c \
$(wildcard ../libfat/*.c)
OBJS = crt0.o $(patsubst %.c,%.o,$(notdir $(SRCS)))
LIBOBJS = conio.o memcpy.o memset.o skipatou.o atou.o malloc.o free.o \
argv.o printf.o __divdi3.o __udivmoddi4.o
.SUFFIXES: .c .o .i .s .S .elf .com
VPATH = .:..:../libfat
TARGETS = syslinux.com
all: $(TARGETS)
tidy:
-rm -f *.o *.i *.s *.a .*.d *.elf
clean: tidy
spotless: clean
-rm -f *~ $(TARGETS)
installer:
syslinux.elf: $(OBJS) libcom.a
$(LD) $(LDFLAGS) -o $@ $^
libcom.a: $(LIBOBJS)
-rm -f $@
$(AR) cq $@ $^
$(RANLIB) $@
syslinux.com: syslinux.elf
$(OBJCOPY) -O binary $< $@
%.o: %.c
$(CC) -Wp,-MT,$@,-MD,.$@.d $(CFLAGS) -c -o $@ $<
%.i: %.c
$(CC) $(CFLAGS) -E -o $@ $<
%.s: %.c
$(CC) $(CFLAGS) -S -o $@ $<
%.s: %.S
$(CC) $(CFLAGS) -D__ASSEMBLY__ -S -o $@ $<
-include .*.d

View File

@@ -0,0 +1,29 @@
/*
* arch/i386/libgcc/__divdi3.c
*/
#include <stdint.h>
#include <stddef.h>
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;
if ( num < 0 ) {
num = -num;
minus = 1;
}
if ( den < 0 ) {
den = -den;
minus ^= 1;
}
v = __udivmoddi4(num, den, NULL);
if ( minus )
v = -v;
return v;
}

Binary file not shown.

View File

@@ -0,0 +1,31 @@
#include <stdint.h>
uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p)
{
uint64_t quot = 0, qbit = 1;
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;
}
while ( qbit ) {
if ( den <= num ) {
num -= den;
quot += qbit;
}
den >>= 1;
qbit >>= 1;
}
if ( rem_p )
*rem_p = num;
return quot;
}

Binary file not shown.

View File

@@ -0,0 +1,94 @@
#ident "$Id: argv.c,v 1.3 2004/12/19 00:25:14 hpa Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 2004 H. Peter Anvin - All Rights Reserved
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall
* be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* ----------------------------------------------------------------------- */
/*
* argv.c
*
* Parse a single C string into argc and argv (argc is return value.)
* memptr points to available memory.
*/
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#define ALIGN_UP(p,t) ((t *)(((uintptr_t)(p) + (sizeof(t)-1)) & ~(sizeof(t)-1)))
extern char _end[]; /* Symbol created by linker */
void *__mem_end = &_end; /* 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;
/* 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;
}
/* 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;
}
}
*arg++ = NULL; /* Null pointer at the end */
__mem_end = arg; /* End of memory we used */
return argc;
}

Binary file not shown.

View File

@@ -0,0 +1,10 @@
#include "mystuff.h"
unsigned int atou(const char *s)
{
unsigned int i = 0;
while (isdigit(*s))
i = i*10 + (*s++ - '0');
return i;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
/* Must be included first of all */
__asm__ (".code16gcc");

View File

@@ -0,0 +1,127 @@
/*
* Linker script for COM16 binaries
*/
/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
"elf32-i386")
OUTPUT_ARCH(i386)
EXTERN(_start)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0x100;
PROVIDE (__executable_start = .);
.init :
{
KEEP (*(.init))
} =0x90909090
.text :
{
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
} =0x90909090
.fini :
{
KEEP (*(.fini))
} =0x90909090
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(4);
PROVIDE (__preinit_array_start = .);
.preinit_array : { *(.preinit_array) }
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { *(.init_array) }
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { *(.fini_array) }
PROVIDE (__fini_array_end = .);
PROVIDE (__ctors_start = .);
.ctors :
{
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
PROVIDE (__ctors_end = .);
PROVIDE (__dtors_start = .);
.dtors :
{
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
PROVIDE (__dtors_end = .);
/* Adjust the address for the data segment. Avoid mixing code and
data within same 128-byte chunk. */
. = ALIGN(128);
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
_end = .;
PROVIDE (end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/DISCARD/ : { *(.note.GNU-stack) }
}

View File

@@ -0,0 +1,43 @@
#ident "$Id: conio.c,v 1.3 2004/12/17 17:47:16 hpa Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 2001-2004 H. Peter Anvin - All Rights Reserved
*
* 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, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* conio.c
*
* Output to the screen
*/
#include <stdarg.h>
#include "mystuff.h"
int putchar(int 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;
while ( *s ) {
putchar(*s);
count++;
s++;
}
return count;
}

Binary file not shown.

View File

@@ -0,0 +1,53 @@
.code16
#ifndef REGPARM
# error "This file assumes -mregparm=3 -DREGPARM=3"
#endif
.section ".init","ax"
.globl _start
.type _start,@function
_start:
# Align the stack and make sure the high half is zero
andl $0xfff8,%esp
# Clear the .bss
cld
xorl %eax,%eax
movw $__bss_start,%di
movw $_end+3,%cx
subw %di,%cx
shrw $2,%cx
rep ; stosl
# Compute argc and argv (assumes REGPARM)
xorl %edx,%edx
movzbw 0x80,%bx
movb %dl,0x81(%bx) # Zero-terminate string
movb $0x81,%dl
pushl %eax # Make space for argv
movl %esp,%eax
calll __parse_argv
pushl %eax # argc
# Initialize malloc
calll __init_memory_arena
# Now call main... (NOTE: gcc forces main to be regparm 0)
popl %eax # argc
popl %edx # argv
calll main
# Here %eax is the exit code, fall through into exit
.size _start,.-_start
.globl exit
.type exit,@function
exit:
# Exit code already in %eax
movb $0x4c,%ah # Terminate program
int $0x21
1: hlt
jmp 1b
.size exit,.-exit

Binary file not shown.

View File

@@ -0,0 +1,7 @@
#ifndef ERRNO_H
#define ERRNO_H
int errno;
void perror(const char *);
#endif /* ERRNO_H */

Binary file not shown.

View File

@@ -0,0 +1,78 @@
/*
* free.c
*
* Very simple linked-list based malloc()/free().
*/
#include <stdlib.h>
#include "malloc.h"
static struct free_arena_header *
__free_block(struct free_arena_header *ah)
{
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;
#ifdef DEBUG_MALLOC
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;
#ifdef DEBUG_MALLOC
nah->a.type = ARENA_TYPE_DEAD;
#endif
}
/* Return the block that contains the called block */
return ah;
}
void free(void *ptr)
{
struct free_arena_header *ah;
if ( !ptr )
return;
ah = (struct free_arena_header *)
((struct arena_header *)ptr - 1);
#ifdef DEBUG_MALLOC
assert( ah->a.type == ARENA_TYPE_USED );
#endif
__free_block(ah);
/* Here we could insert code to return memory to the system. */
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,114 @@
/*
* malloc.c
*
* Very simple linked-list based malloc()/free().
*/
#include <stdlib.h>
#include "malloc.h"
struct free_arena_header __malloc_head =
{
{
ARENA_TYPE_HEAD,
0,
&__malloc_head,
&__malloc_head,
},
&__malloc_head,
&__malloc_head
};
/* This is extern so it can be overridden by the user application */
const size_t __stack_size = 4096;
static inline size_t sp(void)
{
uint32_t sp;
asm volatile("movl %%esp,%0" : "=rm" (sp));
return sp;
}
extern void *__mem_end;
void __init_memory_arena(void)
{
struct free_arena_header *fp;
size_t start, total_space;
start = (size_t)ARENA_ALIGN_UP(__mem_end);
total_space = sp() - start;
fp = (struct free_arena_header *)start;
fp->a.type = ARENA_TYPE_FREE;
fp->a.size = total_space - __stack_size;
/* 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);
}
void *malloc(size_t size)
{
struct free_arena_header *fp;
if ( size == 0 )
return NULL;
/* 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);
}
}
/* Nothing found... need to request a block from the kernel */
return NULL; /* No kernel to get stuff from */
}

View File

@@ -0,0 +1,54 @@
/*
* malloc.h
*
* Internals for the memory allocator
*/
#include <stdint.h>
#include <stddef.h>
/*
* This is the minimum chunk size we will ask the kernel for; this should
* be a multiple of the page size on all architectures.
*/
#define MALLOC_CHUNK_SIZE 65536
#define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1)
/*
* This structure should be a power of two. This becomes the
* alignment unit.
*/
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;
};
#ifdef DEBUG_MALLOC
#define ARENA_TYPE_USED 0x64e69c70
#define ARENA_TYPE_FREE 0x012d610a
#define ARENA_TYPE_HEAD 0x971676b5
#define ARENA_TYPE_DEAD 0xeeeeeeee
#else
#define ARENA_TYPE_USED 0
#define ARENA_TYPE_FREE 1
#define ARENA_TYPE_HEAD 2
#endif
#define ARENA_SIZE_MASK (sizeof(struct arena_header)-1)
#define ARENA_ALIGN_UP(p) ((char *)(((uintptr_t)(p) + ARENA_SIZE_MASK) & ~ARENA_SIZE_MASK))
#define ARENA_ALIGN_DOWN(p) ((char *)((uintptr_t)(p) & ~ARENA_SIZE_MASK))
/*
* This structure should be no more than twice the size of the
* previous structure.
*/
struct free_arena_header {
struct arena_header a;
struct free_arena_header *next_free, *prev_free;
};
extern struct free_arena_header __malloc_head;

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,24 @@
# $Id: memcpy.S,v 1.2 2004/12/17 10:03:47 hpa Exp $
#
# memcpy.S
#
# Simple 16-bit memcpy() implementation
#
.text
.code16gcc
.globl memcpy
.type memcpy, @function
memcpy:
cld
pushw %di
pushw %si
movw %ax,%di
movw %dx,%si
# The third argument is already in cx
rep ; movsb
popw %si
popw %di
ret
.size memcpy,.-memcpy

Binary file not shown.

View File

@@ -0,0 +1,22 @@
# $Id: memset.S,v 1.2 2004/12/17 10:03:47 hpa Exp $
#
# memset.S
#
# Minimal 16-bit memset() implementation
#
.text
.code16gcc
.globl memset
.type memset, @function
memset:
cld
pushw %di
movw %ax,%di
movb %dl,%al
# The third argument is already in %cx
rep ; stosb
popw %di
retl
.size memset,.-memset

Binary file not shown.

View File

@@ -0,0 +1,15 @@
#ifndef MYSTUFF_H
#define MYSTUFF_H
#define NULL ((void *)0)
unsigned int skip_atou(const char **s);
unsigned int atou(const char *s);
static inline int
isdigit(int ch)
{
return (ch >= '0') && (ch <= '9');
}
#endif /* MYSTUFF_H */

Binary file not shown.

View File

@@ -0,0 +1,8 @@
#include <stdio.h>
#include <errno.h>
void perror(const char *msg)
{
printf("%s: error %s\n", msg, errno);
}

View File

@@ -0,0 +1,298 @@
/*
* Oh, it's a waste of space, but oh-so-yummy for debugging. It's just
* initialization code anyway, so it doesn't take up space when we're
* actually running. This version of printf() does not include 64-bit
* support. "Live with it."
*
* Most of this code was shamelessly snarfed from the Linux kernel, then
* modified. It's therefore GPL.
*
* printf() isn't actually needed to build syslinux.com, but during
* debugging it's handy.
*/
#include <stdarg.h>
#include <stdio.h>
#include "mystuff.h"
static int strnlen(const char *s, int maxlen)
{
const char *es = s;
while ( *es && maxlen ) {
es++; maxlen--;
}
return (es-s);
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
#define do_div(n,base) ({ \
int __res; \
__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)
{
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--;
}
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))
while (size-- > 0)
*str++ = c;
while (i < precision--)
*str++ = '0';
while (i-- > 0)
*str++ = tmp[i];
while (size-- > 0)
*str++ = ' ';
return str;
}
/* Forward decl. needed for IP address printing stuff... */
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 flags; /* flags to number() */
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;
}
/* 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;
}
int sprintf(char * buf, const char *fmt, ...)
{
va_list args;
int 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;
va_start(args, fmt);
printed = vsprintf(printf_buf, fmt, args);
va_end(args);
puts(printf_buf);
return printed;
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,10 @@
#include "mystuff.h"
unsigned int skip_atou(const char **s)
{
int i=0;
while (isdigit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}

Binary file not shown.

View File

@@ -0,0 +1,22 @@
#ifndef STDIO_H
#define STDIO_H
#include <stdarg.h>
#include <stdlib.h>
typedef unsigned int off_t;
int putchar(int);
int puts(const char *);
int sprintf(char * buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args);
int printf(const char *fmt, ...);
#define stdin 0
#define stdout 1
#define stderr 2
#define fprintf(x, y, ...) printf(y, ## __VA_ARGS__)
#endif /* STDIO_H */

View File

@@ -0,0 +1,12 @@
#ifndef STDLIB_H
#define STDLIB_H
typedef int ssize_t;
typedef unsigned int size_t;
void __attribute__((noreturn)) exit(int);
void *malloc(size_t);
void free(void *);
#endif

View File

@@ -0,0 +1,23 @@
/*
* string.h
*/
#ifndef _STRING_H
#define _STRING_H
/* Standard routines */
#define memcpy(a,b,c) __builtin_memcpy(a,b,c)
#define memset(a,b,c) __builtin_memset(a,b,c)
#define strcpy(a,b) __builtin_strcpy(a,b)
#define strlen(a) __builtin_strlen(a)
/* 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;
}
#endif /* _STRING_H */

View File

@@ -0,0 +1,594 @@
#ident "$Id: syslinux.c,v 1.13 2004/12/28 22:51:44 hpa Exp $"
/* ----------------------------------------------------------------------- *
*
* Copyright 1998-2004 H. Peter Anvin - All Rights Reserved
*
* 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, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
/*
* syslinux.c - Linux installer program for SYSLINUX
*
* Hacked up for DOS.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mystuff.h"
#include "syslinux.h"
#include "libfat.h"
const char *program = "syslinux"; /* Name of program */
uint16_t dos_version;
#ifdef DEBUG
# define dprintf printf
#else
# define dprintf(...) ((void)0)
#endif
void __attribute__((noreturn)) usage(void)
{
puts("Usage: syslinux [-sfma] <drive>: [bootsecfile]\n");
exit(1);
}
void unlock_device(int);
void __attribute__((noreturn)) die(const char *msg)
{
unlock_device(0);
puts("syslinux: ");
puts(msg);
putchar('\n');
exit(1);
}
/*
* read/write wrapper functions
*/
int creat(const char *filename, int mode)
{
uint16_t rv;
uint8_t err;
dprintf("creat(\"%s\", 0x%x)\n", filename, mode);
rv = 0x3C00;
asm volatile("int $0x21 ; setc %0"
: "=abcdm" (err), "+a" (rv)
: "c" (mode), "d" (filename));
if ( err ) {
dprintf("rv = %d\n", rv);
die("cannot open ldlinux.sys");
}
return rv;
}
void close(int fd)
{
uint16_t rv = 0x3E00;
dprintf("close(%d)\n", 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... */
}
ssize_t write_file(int fd, const void *buf, size_t count)
{
uint16_t rv;
ssize_t done = 0;
uint8_t err;
dprintf("write_file(%d,%p,%u)\n", fd, buf, count);
while ( count ) {
rv = 0x4000;
asm volatile("int $0x21 ; setc %0"
: "=abcdm" (err), "+a" (rv)
: "b" (fd), "c" (count), "d" (buf));
if ( err || rv == 0 )
die("file write error");
done += rv;
count -= rv;
}
return done;
}
struct diskio {
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;
dprintf("write_device(%d,%p,%u,%u)\n", drive, buf, nsecs, sector);
dio.startsector = sector;
dio.sectors = nsecs;
dio.bufoffs = (uintptr_t)buf;
asm("movw %%ds,%0" : "=m" (dio.bufseg));
asm volatile("int $0x26 ; setc %0 ; popfw"
: "=abcdm" (err)
: "a" (drive-1), "b" (&dio), "c" (-1), "d" (buf));
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;
dprintf("read_device(%d,%p,%u,%u)\n", drive, buf, nsecs, sector);
dio.startsector = sector;
dio.sectors = nsecs;
dio.bufoffs = (uintptr_t)buf;
asm("movw %%ds,%0" : "=m" (dio.bufseg));
asm volatile("int $0x25 ; setc %0 ; popfw"
: "=abcdm" (err)
: "a" (drive-1), "b" (&dio), "c" (-1), "d" (buf));
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));
uint32_t get_partition_offset(int drive)
{
uint8_t err;
uint16_t rv;
struct deviceparams dp;
dp.specfunc = 1; /* Get current information */
rv = 0x440d;
asm volatile("int $0x21 ; setc %0"
: "=abcdm" (err), "+a" (rv)
: "b" (drive), "c" (0x0860), "d" (&dp));
if ( !err )
return dp.hiddensecs;
rv = 0x440d;
asm volatile("int $0x21 ; setc %0"
: "=abcdm" (err), "+a" (rv)
: "b" (drive), "c" (0x4860), "d" (&dp));
if ( !err )
return dp.hiddensecs;
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));
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
};
void write_mbr(int drive, const void *buf)
{
uint16_t rv;
uint8_t err;
dprintf("write_mbr(%d,%p)\n", drive, buf);
mbr.bufferoffset = (uintptr_t)buf;
asm("movw %%ds,%0" : "=m" (mbr.bufferseg));
rv = 0x440d;
asm volatile("int $0x21 ; setc %0"
: "=abcdm" (err), "+a" (rv)
: "c" (0x0841), "d" (&mbr), "b" (drive));
if ( !err )
return;
rv = 0x440d;
asm volatile("int $0x21 ; setc %0"
: "=abcdm" (err), "+a" (rv)
: "c" (0x4841), "d" (&mbr), "b" (drive));
if ( err )
die("mbr write error");
}
void read_mbr(int drive, const void *buf)
{
uint16_t rv;
uint8_t err;
dprintf("read_mbr(%d,%p)\n", drive, buf);
mbr.bufferoffset = (uintptr_t)buf;
asm("movw %%ds,%0" : "=m" (mbr.bufferseg));
rv = 0x440d;
asm volatile("int $0x21 ; setc %0"
: "=abcdm" (err), "+a" (rv)
: "c" (0x0861), "d" (&mbr), "b" (drive));
if ( !err )
return;
rv = 0x440d;
asm volatile("int $0x21 ; setc %0"
: "=abcdm" (err), "+a" (rv)
: "c" (0x4861), "d" (&mbr), "b" (drive));
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;
dprintf("set_attributes(\"%s\", 0x%02x)\n", file, attributes);
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)
{
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);
}
/* The locking interface relies on static variables. A massive hack :( */
static uint16_t lock_level;
static inline void set_lock_device(uint8_t device)
{
lock_level = device;
}
void lock_device(int level)
{
uint16_t rv;
uint8_t err;
uint16_t lock_call;
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;
#else
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");
}
lock_level = new_level;
}
return;
}
void unlock_device(int level)
{
uint16_t rv;
uint8_t err;
uint16_t unlock_call;
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;
#else
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;
}
}
/*
* 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));
static void adjust_mbr(int device, int writembr, int set_active)
{
static unsigned char sectbuf[512];
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++;
}
if ( found < 1 ) {
die("partition not found");
} else if ( found > 1 ) {
die("multiple aliased partitions found");
}
}
write_mbr(device, sectbuf);
}
int main(int argc, char *argv[])
{
static unsigned char sectbuf[512];
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, sectors[65]; /* 65 is maximum possible */
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 */
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 */
syslinux_make_stupid();
break;
case 'f': /* Force install */
force = 1;
break;
case 'm': /* Write MBR */
writembr = 1;
break;
case 'a': /* Set partition active */
set_active = 1;
break;
default:
usage();
}
opt++;
}
} else {
if ( bootsecfile )
usage();
else if ( device )
bootsecfile = *argp;
else
device = *argp;
}
}
if ( !device )
usage();
/*
* 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();
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);
}
ldlinux_name[0] = dev_fd | 0x40;
set_attributes(ldlinux_name, 0);
fd = creat(ldlinux_name, 0x07); /* SYSTEM HIDDEN READONLY */
write_file(fd, syslinux_ldlinux, syslinux_ldlinux_len);
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.
*/
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 < 65 ) {
*secp++ = s;
nsectors++;
s = libfat_nextsector(fs, s);
}
libfat_close(fs);
/*
* Patch ldlinux.sys and the boot sector
*/
syslinux_patch(sectors, nsectors);
/*
* Write the now-patched first sector of ldlinux.sys
*/
lock_device(3);
write_device(dev_fd, syslinux_ldlinux, 1, sectors[0]);
/*
* 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, 512);
close(fd);
} else {
write_device(dev_fd, sectbuf, 1, 0);
unlock_device(0);
}
/* Done! */
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.