# HG changeset patch # User Pascal Bellard # Date 1517054170 -3600 # Node ID d74b8b5a78d0c817e918bbc46712f56afd963df0 # Parent 12473799110f3156f223d473aeb186021fc9d815 ipxe: update bootloader diff -r 12473799110f -r d74b8b5a78d0 ipxe/receipt --- a/ipxe/receipt Thu Jan 25 03:48:04 2018 +0200 +++ b/ipxe/receipt Sat Jan 27 12:56:10 2018 +0100 @@ -25,13 +25,27 @@ sed -i -e 's|//\(#define.*IMAGE_PNG\)|\1|' \ -e 's|//\(#define.*CONSOLE_CMD\)|\1|' \ -e 's|//\(#define.*REBOOT_CMD\)|\1|' config/general.h - cp $stuff/lkrnprefix.S arch/i386/prefix + sed -i 's|//\(#define.*CPUID_SETTINGS\)|\1|' config/settings.h pxelinux="$(ls $WOK/syslinux/source/*/core/pxelinux.0)" make bin/undionly.kkkpxe EMBED=$stuff/ipxelinux.ipxe,$pxelinux && mv bin/undionly.kkkpxe bin/ipxelinux.0 + make bin-i386-efi/snponly.efi EMBED=$stuff/ipxelinux.ipxe,$pxelinux && + mv bin-i386-efi/snponly.efi bin-i386-efi/ipxelinux.efi make bin/undionly.pxe bin/undionly.kpxe bin/undionly.kkpxe \ bin/undionly.kkkpxe bin/ipxe.pxe bin/ipxe.kpxe bin/ipxe.kkpxe \ - bin/ipxe.kkkpxe bin/ipxe.nbi bin/ipxe.lkrn EMBED=$stuff/ipxe.cmd + bin/ipxe.kkkpxe bin/ipxe.nbi bin/ipxe.lkrn bin-i386-efi/ipxe.efi \ + bin-i386-efi/snponly.efi EMBED=$stuff/ipxe.cmd + cp $stuff/bootloader.S . + cc -o bootloader.o -Wa,-a=bootloader.lst -c bootloader.S + objcopy -O binary bootloader.o bootloader.bin + size=$(stat -c %s bin/ipxe.lkrn) + while read ofs val ; do + printf '\\\\x%02X\\\\x%02X' $(($val & 255)) $(($val / 256)) | \ + xargs echo -en|dd bs=1 conv=notrunc of=bootloader.bin seek=$ofs + done 2> /dev/null <= 0x202 + popw %es # %es contain INITSEG + movw %es, %di +#else + # cmdline offset at 0x22 + movw $stacktop, %di # stacktop is an arbitrary value >= + # length of bootsect + length of + # setup + room for stack; + # 12 is disk parm size. + popw %es # %es contain INITSEG +#endif + pushw %es + popw %ss # %es = %ss = INITSEG + movw %di, %sp # put stack at INITSEG:stacktop-... +#ifdef EXE_SUPPORT + cwd # force %dx = 0 (floppy only) +#endif + +# Many BIOS's default disk parameter tables will not recognize +# multi-sector reads beyond the maximum sector number specified +# in the default diskette parameter tables - this may mean 7 +# sectors in some cases. +# +# Since single sector reads are slow and out of the question, +# we must take care of this by creating new parameter tables +# (for the first disk) in RAM. We can set the maximum sector +# count to 36 - the most we will encounter on an ED 2.88. +# +# High doesn't hurt. Low does. Let's use the max: 63 + + rep # don't worry about cld + stosw # already done above + popw %bx # offset = 0 + popw %ds # %ds = 0 + popw %fs # %fs = 0 + + movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0) + incw %ax + + ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address + pushw %es + pushw %di + movb $6, %cl # copy 12 bytes + rep # don't worry about cld + movsw # already done above + pushw %ss + popw %ds # now %ds = %es = %ss = INITSEG + popl %fs:0x78(%bx) # update parameter table address + movb $63, 0x4-12(%di) # patch sector count, %di = stacktop + cli + + xchg %ax, %di # sector count + popw %ax # limits = 0 + incw %cx # cylinder 0, sector 1, clear Z + call read_first_sectors # read setup + +# This routine loads the system at address LOADSEG, making sure +# no 64kB boundaries are crossed. We try to load it as fast as +# possible, loading whole tracks whenever we can. + +#ifndef NO_DOTS + popw %bx # clear %bx +#endif + movw syssize, %di + decw %di + shrw $9-4, %di + incw %di + movw $SYSSEG, %cx +#ifdef BZIMAGE + push %cx +#endif + call read_sectorsCX + +# This procedure turns off the floppy drive motor, so +# that we enter the kernel in a known state, and +# don't have to worry about it later. + +kill_motor: + xchgw %ax, %di # reset FDC (%di < 128) + int $0x13 + +# After that (everything loaded), we jump to the setup-routine +# loaded directly after the bootblock: +# Segments are as follows: %ds = %ss = INITSEG + +#ifdef BZIMAGE + popw %bx + popw %si // SYSSEG:0 +movesys: // %bx = DS, %si + movw $16, %ax + mulw %bx + addw %si, %ax + adcw $0x9300, %dx // %dx:%ax src flat address + movw $9, %cx +zero1: + pushw $0 // 2E..1E + loop zero1 + //pushl $0x93100000 // 1A: dest + pushw $0x9310 + pushw %cx + pushw $-1 // 18 + pushw %cx // 16 + pushw %dx // src + pushw %ax + pushw $-1 // 10 + movb $8, %cl + movw %cx, %bx // will move 8*64 = 512Kb +zero2: + pushw $0 // 0E..00 + loop zero2 + movw %sp, %si + pushw %ss + popw %es + pushw %es + popw %ds +syslp: + movb $0x80, %ch + movb $0x87, %ah + int $0x15 + incb 0x14(%si) + incb 0x1C(%si) + decw %bx + jne syslp +#endif +jmp_setup: + ljmp $SETUPSEG, $0 + +#ifdef EXE_SUPPORT +#ifdef SHUTDOWNDOS +doiret: + iret +step19: + pushw %si + pushw %ds + movw %sp, %si + ldsw %ss:4(%si), %si + cmpw $0x19CD, (%si) + popw %ds + popw %si + jne doiret + xorw %si, %si + movw %si, %ds + pushw %cs + popw %ss + movw $stacktop-4-16, %sp + popl 4(%si) + popaw +#ifdef BZIMAGE + jmp movesys +#endif +#endif +#ifndef BZIMAGE +movesys: // %ax = SYSSEG, %bx = DS, %si + shrw $4, %si + addw %si, %bx + subw %ax, %bx + jnc forward + movb $0x90, %ah + ;decw %ax +forward: + movw %ax, %es + movw %ax, %di + addw %bx, %di + movw %di, %ds + sbbw %di, %di // %di = 0 : -1 + cmc // C = 1 : 0 + adcw %di, %ax + xorw %si, %si + xorw %di, %di + movb $0x10, %cl + cmpb %cl, %ah // move 512k + rep + movsb + jns forward +#ifndef NO_CURSOR_DEFINITION + movb $1, %ah + movb $0, %bh + movb $0x20, %ch // 0x2000 + int $0x10 +#endif + pushw %ss + popw %ds + jmp jmp_setup +#endif +comstart: + cld # assume nothing + pushw $INITSEG + popw %es +#ifdef CMDLINE + movw %sp, %di + movw $0x80, %si + lodsb + cbw + xchgw %ax, %cx + jcxz nocmdline +# if defined(BZIMAGE) && BZIMAGE >= 0x202 + movw $INITSEG/16+stacktop/256, EXEADRS(cmd_line_ptr+1) +# else + movw $0xA33F, 0x7F(%si) +# endif +# ifndef NO_CMDLINE_SHRINK +skipspace: + lodsb + cmpb $0x20, %al + je skipspace +# ifndef NO_CMDLINE_FILE + movw %si,%dx + decw %si + subb $'@',%al + jne notafile + movb $0x3D,%ah + int $0x21 + jc notafile + xchgw %ax,%bx + //movw %si,%dx // ~320 bytes max + movw $EXEADRS(notafile)-130,%cx + movb $0x3F,%ah + int $0x21 + xchgw %ax,%cx +notafile: +# else + decw %si +# endif +# endif + rep + movsb +nocmdline: + orb EXEADRS(setup_sects), %ch +# ifndef NO_MINSETUP +# ifndef BZIMAGE + jnz setupok + mov $4, %ch +setupok: +# endif +# endif +#else + movb EXEADRS(setup_sects), %ch +#endif + movb $(512-(end_header-_start))/2, %cl + movw $0x100, %si + movw $end_header, %di + rep + movsw + movw $SYSSEG, %ax + movw %ds, %bx + pushw %es + popw %ss +#ifndef SHUTDOWNDOS + pushw %es + pushw $movesys +#endif +#ifdef VCPI + pushaw + smsww %ax + andb $1, %al + je isrm + movw $EXEADRS(gdt_vcpi),%si + movw $pagebuf-0x90000,%di // %es = 0x9000 + movl $pagebuf+3,%es:0x1000(%di) +call_vcpi: + movb $0xDE,%ah // DE01, EBX = getiface(DS:SI, ES:DI) + int $0x67 + movl $FLAT20(sw2pm_params),%esi + movb $0x0C,%al // DE0C switchpm(ESI) + cli + jmp call_vcpi +pm_code: + movl %cr0,%eax + andl $0x7FFFFFFE,%eax + movl %eax,%cr0 + movl %eax,%cr3 +isrm: +# ifdef SHUTDOWNDOS + trace_int19 +# else + lssw %cs:EXEADRS(saved_ss_sp),%sp + popaw + retf +# endif +#else +# ifdef SHUTDOWNDOS + pushaw + trace_int19 +# endif + retf +#endif +#endif + +# read_sectors reads %di sectors into %es:0 buffer. +# %es:0 is updated to the next memory location. +# First, sectors are read sector by sector until +# sector per track count is known. Then they are +# read track by track. +# Assume no error on first track. + +#ifdef FLOPPY_1440K_ONLY +#define FLOPPY_HAS_2_SIDES hardcore heads count to 2 +#define FLOPPY_SECTORS 18 /* 18 sectors */ +#else +#define FLOPPY_HEADS 2 /* 2 heads minimum */ +#endif + +return: +#ifndef NO_DOTS + movw $0xE2E,%ax + movb $7,%bl + int $0x10 +#endif + ret + +check_limits: +#ifndef FLOPPY_1440K_ONLY + popw %dx + cmpb %al, %cl # max sector known ? + ja next_head # no -> store it +#ifndef FLOPPY_HAS_2_SIDES +#ifdef FLOPPY_HEADS + cmpb $FLOPPY_HEADS, %dh # 2 heads minimum + jb check_cylinder +#endif + cmpb %ah, %dh # max head known ? + ja next_cylinder # no -> store it +check_cylinder: +#endif +#endif + pushaw +#ifndef FLOPPY_1440K_ONLY + cbw # %ah = 0 +#endif + int $0x13 # reset controler + popaw + movb $1, %al # sector by sector... +read_sectorslp: + pushw %dx # some bios break dx... +#ifndef FLOPPY_1440K_ONLY + pushw %ax # limits + subb %cl, %al # sectors remaining in track + ja tolastsect + movb $1, %al # 1 sector mini +tolastsect: +#else + movb $FLOPPY_SECTORS+1, %al + subb %cl, %al # sectors remaining in track +#endif + cbw + cmpw %di, %ax + jb more1trk + movw %di, %ax # sectors to read +more1trk: + pushw %ax # save context + movb $2, %ah # cmd: read chs + int $0x13 +#ifndef FLOPPY_1440K_ONLY + popw %dx # save %ax + popw %ax # limits +#else + popw %ax # restore context + popw %dx +#endif + jc check_limits +#ifndef FLOPPY_1440K_ONLY + xchgw %ax, %bp + addw %dx,%cx # next sector + movw %cx, %gs + movw %es, %cx + pushw %dx + shlw $5, %dx + addw %dx, %cx + popw %dx + subw %dx,%di # update sector counter + popw %dx +#else + addw %ax,%cx # next sector + movw %cx, %gs + movw %es, %cx + pushw %ax + shlw $5, %ax + addw %ax, %cx + popw %ax + subw %ax,%di # update sector counter +#endif +read_sectorsCX: + movw %cx, %es # next location + jz return +read_sectors: + movw %gs, %cx +#ifndef FLOPPY_1440K_ONLY +# al is last sector+1 +# ah is last cylinder+1 + xchgw %ax, %bp +#endif +#ifndef FLOPPY_1440K_ONLY + cmpb %al,%cl # reach sector limit ? + jne bdendlp +next_head: + movb %cl,%al +#else + cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ? + jne bdendlp +#endif + movb $1,%cl # first sector +#ifndef FLOPPY_HAS_2_SIDES + incb %dh # next head + cmpb %ah, %dh # reach head limit ? + jne bdendlp +next_cylinder: + movb %dh,%ah + movb $0,%dh # first head +#else + xorb %cl,%dh # next head + jne bdendlp # reach head limit ? +#endif +# NOTE : support 256 cylinders max + incb %ch # next cylinder +read_first_sectors: +bdendlp: + jmp read_sectorslp + +#ifdef VCPI +pagebuf = 0x98000 +tss = gdt_abs-40 +gdt = gdt_abs-32 +gdt_null = gdt_abs-32 +gdt_vcpi = gdt_abs-24 +gdt_vcpi2 = gdt_abs-16 +gdt_vcpi3 = gdt_abs-8 +gdt_abs: + .word 0xFFFF + .long 0x92000000 + .byte 0xCF,0 +gdt_code: + .word 0xFFFF +gdt_code_base: + .long 0x9A000000+FLAT20(0) + .byte 0x8F,0 +gdt_tss: + .word 0x00FF +gdt_tss_base: + .long 0x89000000+FLAT20(tss) + .byte 0,0 +gdtr: +gdt_lim: + .word 0xFFFF +gdt_base: + .long FLAT20(gdt) +sw2pm_params: +sw2pm_cr3: + .long pagebuf+0x1000 +sw2pm_gdtr_ptr: + .long FLAT20(gdtr) +sw2pm_idtr_ptr: + .long FLAT20(idtr) +sw2pm_ldtr: + .word 0 +sw2pm_tr: +SEL_TSS = gdt_tss-gdt_null + .word SEL_TSS +sw2pm_jumpaddr: + .long pm_code +SEL_CODE = gdt_code-gdt_null + .word SEL_CODE +idtr: +idt_lim: + .word 0x03FF +idt_base: + .long 0 +# ifndef SHUTDOWNDOS +saved_ss_sp: + .word stacktop-4-16-4,INITSEG +# endif +#endif diff -r 12473799110f -r d74b8b5a78d0 ipxe/stuff/lkrnprefix.S --- a/ipxe/stuff/lkrnprefix.S Thu Jan 25 03:48:04 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,639 +0,0 @@ -/* - Copyright (C) 2000, Entity Cyber, Inc. - - Authors: Gary Byers (gb@thinguin.org) - Marty Connor (mdc@thinguin.org) - - This software may be used and distributed according to the terms - of the GNU Public License (GPL), incorporated herein by reference. - - Description: - - This is just a little bit of code and data that can get prepended - to a ROM image in order to allow bootloaders to load the result - as if it were a Linux kernel image. - - A real Linux kernel image consists of a one-sector boot loader - (to load the image from a floppy disk), followed a few sectors - of setup code, followed by the kernel code itself. There's - a table in the first sector (starting at offset 497) that indicates - how many sectors of setup code follow the first sector and which - contains some other parameters that aren't interesting in this - case. - - We don't require much in the way of setup code. Historically, the - Linux kernel required at least 4 sectors of setup code. - Therefore, at least 4 sectors must be present even though we don't - use them. - -*/ - -FILE_LICENCE ( GPL_ANY ) - -#define SETUPSECS 4 /* Minimal nr of setup-sectors */ -#define PREFIXSIZE ((SETUPSECS+1)*512) -#define PREFIXPGH (PREFIXSIZE / 16 ) -#define BOOTSEG 0x07C0 /* original address of boot-sector */ -#define INITSEG 0x9000 /* we move boot here - out of the way */ -#define SETUPSEG 0x9020 /* setup starts here */ -#define SYSSEG 0x1000 /* system loaded at 0x10000 (65536). */ - - .text - .code16 - .arch i386 - .org 0 - .section ".prefix", "ax", @progbits - .globl _lkrn_start -_lkrn_start: - -bootsector: -_start: - -/* some extra features */ -#define EXE_SUPPORT real mode dos .exe file support - -#define EXEADRS(x) (x+0xE0) - -/* some contraints to reduce the size */ -//#define FLOPPY_1440K_ONLY 1.44M floppies support only - -#ifdef EXE_SUPPORT -/* Initial temporary stack size */ -#define EXE_STACK_SIZE 0x400 - -/* Temporary decompression area (avoid DOS high memory area) */ -#define EXE_DECOMPRESS_ADDRESS 0x110000 - -/* Fields within the Program Segment Prefix */ -#define PSP_CMDLINE_LEN 0x80 -#define PSP_CMDLINE_START 0x81 - -#define HEADER_SIZE 0x20 - -signature: - decw %bp // Magic number: MZ - popw %dx - jmp start // Bytes on last page of file -blocks: - .word 0 // Pages in file - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDW" - .long blocks - .long 512 - .long 0 - .previous - .word 0 // Relocations - .word ( HEADER_SIZE / 16 ) // Size of header in paragraphs - .word ( EXE_STACK_SIZE / 16 ) // Minimum extra paragraphs needed - .word ( EXE_STACK_SIZE / 16 ) // Maximum extra paragraphs needed -init_ss: - .word -( ( _exe_start - signature ) / 16 ) // Initial (relative) SS value - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDW" - .long init_ss - .long 16 - .long 0 - .previous - .word EXE_STACK_SIZE // Initial SP value - .word 0 // Checksum - .word _exe_start // Initial IP value - /* Initial code segment (relative to start of executable) */ - .word -( HEADER_SIZE / 16 ) // Initial (relative) CS value -// .word 0x001C // File address of relocation table -// .word 0,0,0 // Overlay number - .ascii "(SliTaz)" - -start: - pushw %dx -#endif - cld # assume nothing -stacktop = 0x9E00 # in 0x8000 .. 0xA000 -zeroed = 12 # zeroed registers - movw $stacktop-12-zeroed, %di # stacktop is an arbitrary value >= - # length of bootsect + length of - # setup + room for stack; - # 12 is disk parm size. - pushw $INITSEG - popw %ss # %ss contain INITSEG - movw %di, %sp # put stack at INITSEG:stacktop-... - -# Many BIOS's default disk parameter tables will not recognize -# multi-sector reads beyond the maximum sector number specified -# in the default diskette parameter tables - this may mean 7 -# sectors in some cases. -# -# Since single sector reads are slow and out of the question, -# we must take care of this by creating new parameter tables -# (for the first disk) in RAM. We can set the maximum sector -# count to 36 - the most we will encounter on an ED 2.88. -# -# High doesn't hurt. Low does. Let's use the max: 63 - - pushw %ss - popw %es # %es = %ss = INITSEG - xorw %ax, %ax # %ax = 0 -#ifdef EXE_SUPPORT - cwd # %dx = 0 -#endif - movw $zeroed/2, %cx # clear gdt + offset, %ds, limits - rep # don't worry about cld - stosw # already done above - popw %bx # offset = 0 - popw %ds # %ds = 0 - popw %fs # %fs = 0 - - movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0) - incw %ax - - ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address - pushw %es - pushw %di - movb $6, %cl # copy 12 bytes - rep # don't worry about cld - movsw # already done above - pushw %ss - popw %ds # now %ds = %es = %ss = INITSEG - popl %fs:0x78(%bx) # update parameter table address - movb $63, 0x4-12(%di) # patch sector count, %di = stacktop - cli - - xchg %ax, %di # sector count - popw %ax # limits = 0 - incw %cx # cylinder 0, sector 1, clear Z - call read_first_sectors # read setup - -# This routine loads the system at address LOADSEG, making sure -# no 64kB boundaries are crossed. We try to load it as fast as -# possible, loading whole tracks whenever we can. - - popw %bx # clear %bx - movw syssize, %di - addw $(512/16)-1, %di - shrw $9-4, %di - movw $SYSSEG, %cx - call read_sectorsCX - -# This procedure turns off the floppy drive motor, so -# that we enter the kernel in a known state, and -# don't have to worry about it later. - -kill_motor: - xchgw %ax, %di # reset FDC (%di < 128) - int $0x13 - -# After that (everything loaded), we jump to the setup-routine -# loaded directly after the bootblock: -# Segments are as follows: %ds = %ss = INITSEG - - ljmp $SETUPSEG, $0 - -#ifdef EXE_SUPPORT -dosexit: - movw $0x4c00, %ax - int $0x21 - -_exe_start: - pushw $dosexit - movw $EXEADRS(need386), %si - pushfw // save flags - // bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // flags 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF - movb $0x10, %ah // DF = IF = TF = 0 - pushw %ax - popfw // < 286 : flags[12..15] are forced 1 - pushfw // = 286 : flags[12..15] are forced 0 - popw %cx // > 286 : only flags[15] is forced 0 - popfw // restore flags - cmpb %ah, %ch // test Fx and 0x cases - js puts // S= not 386+ -// smsww %ax -// andb $1, %al -// jne puts - - /* Terminate command line with a NUL */ - movzbw PSP_CMDLINE_LEN, %si - movb $0, PSP_CMDLINE_START(%si) - cmpb $'?', PSP_CMDLINE_START-1(%si) - je help - pushw %si - - /* Install iPXE. Use a fixed temporary decompression area to - * avoid trashing the DOS high memory area. - */ - call alloc_basemem - movl $EXE_DECOMPRESS_ADDRESS, %edi - stc - sbbl %ebp, %ebp /* Allow arbitrary relocation */ - xorl %esi, %esi - call install_prealloc - - xorl %ebp, %ebp - xorl %ecx, %ecx - - /* Calculate command line physical address */ - xorl %edx, %edx - movw %ds, %dx - shll $4, %edx - popw %si - orw %si, %si - jne gotarg - movw $EXEADRS(default_config), %bp - addl %edx, %ebp - movw $0xA00-default_config, %cx -gotarg: - addl $PSP_CMDLINE_START, %edx - - jmp start_ipxe - -help: - movw $EXEADRS(helpmsg), %si -puts: - lodsb - orb %al, %al - je exit - call putc - jmp puts -#endif - -putcdot: - movb $0x2E, %al -putc: - movb $0xE, %ah - movw $7, %bx - int $0x10 -exit: - ret - - -# read_sectors reads %di sectors into %es:0 buffer. -# %es:0 is updated to the next memory location. -# First, sectors are read sector by sector until -# sector per track count is known. Then they are -# read track by track. -# Assume no error on first track. - -#ifdef FLOPPY_1440K_ONLY -#define FLOPPY_HEADS 2 /* 2 heads */ -#define FLOPPY_SECTORS 18 /* 18 sectors */ -#else -#define FLOPPY_HEADS 2 /* 2 heads minimum */ -#define FLOPPY_SECTORS 9 /* 9 sectors minimum */ -#endif - -check_limits: -#ifndef FLOPPY_1440K_ONLY - popw %dx -#ifdef FLOPPY_SECTORS - cmpb $FLOPPY_SECTORS+1, %cl # minimum sector count - jb check_head -#endif - cmpb %al, %cl # max sector known ? - ja next_head # no -> store it -check_head: -#ifdef FLOPPY_HEADS - cmpb $FLOPPY_HEADS, %dh # 2 heads minimum - jb check_cylinder -#endif - cmpb %ah, %dh # max head known ? - ja next_cylinder # no -> store it -check_cylinder: -#endif - pushaw -#ifndef FLOPPY_1440K_ONLY - cbw # %ah = 0 -#endif - int $0x13 # reset controler - popaw - movb $1, %al # sector by sector... -read_sectorslp: - pushw %dx # some bios break dx... -#ifndef FLOPPY_1440K_ONLY - pushw %ax # limits - subb %cl, %al # sectors remaining in track - ja tolastsect - movb $1, %al # 1 sector mini -tolastsect: -#else - mov $FLOPPY_SECTORS+1, %al - subb %cl, %al # sectors remaining in track -#endif - cbw - cmpw %di, %ax - jb more1trk - movw %di, %ax # sectors to read -more1trk: - pushw %ax # save context - movb $2, %ah # cmd: read chs - int $0x13 -#ifndef FLOPPY_1440K_ONLY - popw %dx # save %ax - popw %ax # limits -#else - popw %ax # restore context - popw %dx -#endif - jc check_limits -#ifndef FLOPPY_1440K_ONLY - xchgw %ax, %bp - addw %dx,%cx # next sector - movw %cx, %gs - movw %es, %cx - pushw %dx - shlw $5, %dx - addw %dx, %cx - popw %dx - subw %dx,%di # update sector counter - popw %dx -read_sectorsCX: - movw %cx, %es # next location - jz putcdot -#else - addw %ax,%cx # next sector - movw %cx, %gs - movw %es, %cx - pushw %ax - shlw $5, %ax - addw %ax, %cx - popw %ax - subw %ax,%di # update sector counter -read_sectorsCX: - movw %cx, %es # next location - jz putcdot -#endif -read_sectors: - movw %gs, %cx -#ifndef FLOPPY_1440K_ONLY -# al is last sector+1 -# ah is last cylinder+1 - xchgw %ax, %bp -#endif -#ifndef FLOPPY_1440K_ONLY - cmpb %al,%cl # reach sector limit ? - jne bdendlp -next_head: - movb %cl,%al -#else - cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ? - jne bdendlp -#endif - incb %dh # next head - movb $1,%cl # first sector -#ifndef FLOPPY_1440K_ONLY - cmpb %ah, %dh # reach head limit ? - jne bdendlp -next_cylinder: - movb %dh,%ah -#else - cmpb %cl,%dh # reach head limit ? - je bdendlp -#endif -# NOTE : support 256 cylinders max - incb %ch # next cylinder - movb $0,%dh # first head -read_first_sectors: -bdendlp: - jmp read_sectorslp - -#ifdef EXE_SUPPORT -need386: - .ascii "No 386+." - .byte 13,10 - .byte 0 -helpmsg: - .ascii "No help available." - .byte 13,10 - .byte 0 -#endif - -/* - The following header is documented in the Linux source code at - Documentation/x86/boot.txt -*/ - .org 497 -setup_sects: - .byte SETUPSECS -root_flags: - .word 0 -syssize: - .long -PREFIXPGH - - .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ - .ascii "ADDL" - .long syssize - .long 16 - .long 0 - .previous - -ram_size: - .word 0 -vid_mode: - .word 0 -root_dev: - .word 0 -boot_flag: - .word 0xAA55 -jump: - /* Manually specify a two-byte jmp instruction here rather - * than leaving it up to the assembler. */ - .byte 0xeb - .byte setup_code - header -header: - .byte 'H', 'd', 'r', 'S' -version: - .word 0x0207 /* 2.07 */ -realmode_swtch: - .long 0 -start_sys: - .word 0 -kernel_version: - .word 0 -type_of_loader: - .byte 0 -loadflags: - .byte 0 -setup_move_size: - .word 0 -code32_start: - .long SYSSEG*16 -ramdisk_image: - .long 0 -ramdisk_size: - .long 0 -bootsect_kludge: - .long 0 -heap_end_ptr: - .word 0 -pad1: - .word 0 -cmd_line_ptr: - .long 0 -initrd_addr_max: - /* We don't use an initrd but some bootloaders (e.g. SYSLINUX) have - * been known to require this field. Set the value to 2 GB. This - * value is also used by the Linux kernel. */ - .long 0x7fffffff -kernel_alignment: - .long 0 -relocatable_kernel: - .byte 0 -pad2: - .byte 0, 0, 0 -cmdline_size: - .long 0x7ff -hardware_subarch: - .long 0 -hardware_subarch_data: - .byte 0, 0, 0, 0, 0, 0, 0, 0 - -/* - We don't need to do too much setup. - - This code gets loaded at SETUPSEG:0. It wants to start - executing the image that's loaded at SYSSEG:0 and - whose entry point is SYSSEG:0. -*/ -setup_code: - movl ramdisk_image, %eax - orl %eax, %eax - jnz setup_done - - movw $default_config, %di - movw $-1, %bx - - movw $9, %cx -1: - pushw %ax - loop 1b - pushw $0x9310 - pushw %ax - pushw %bx - pushw %ax - pushw $0x9300+(INITSEG>>12) - pushw %di - pushw %bx - movb $8, %cl -1: - pushw %ax - loop 1b -1: - incw %bx - cmpb %al, (%bx,%di) - jne 1b - movw %bx, ramdisk_size - movb $0x10, ramdisk_image+2 - - pushw %ss - popw %es - movw %sp, %si - movb $0x87, %ah - movw $(run_ipxe-default_config)/2+1, %cx - int $0x15 - -setup_done: - /* We expect to be contiguous in memory once loaded. The Linux image - * boot process requires that setup code is loaded separately from - * "non-real code". Since we don't need any information that's left - * in the prefix, it doesn't matter: we just have to ensure that - * %cs:0000 is where the start of the image *would* be. - */ - ljmp $(SYSSEG-(PREFIXSIZE/16)), $run_ipxe - -default_config: - - .org PREFIXSIZE -/* - We're now at the beginning of the kernel proper. - */ -run_ipxe: - /* Set up stack just below 0x7c00 and clear direction flag */ - xorw %ax, %ax - movw %ax, %ss - movw $0x7c00, %sp - cld - - /* Retrieve command-line pointer */ - movl %ds:cmd_line_ptr, %edx - testl %edx, %edx - jz no_cmd_line - - /* Set up %es:%di to point to command line */ - movl %edx, %edi - andl $0xf, %edi - rorl $4, %edx - movw %dx, %es - - /* Find length of command line */ - pushw %di - movw $0xffff, %cx - repnz scasb - notw %cx - popw %si - - /* Make space for command line on stack */ - movw %sp, %di - subw %cx, %di - andw $~0xf, %di - movw %di, %sp - - /* Copy command line to stack */ - pushw %ds - pushw %es - popw %ds - pushw %ss - popw %es - rep movsb - popw %ds - - /* Store new command-line pointer */ - movzwl %sp, %edx -no_cmd_line: - - /* Calculate maximum relocation address */ - movl ramdisk_image, %ebp - testl %ebp, %ebp - jnz 1f - decl %ebp /* Allow arbitrary relocation if no initrd */ -1: - - /* Install iPXE */ - call alloc_basemem - xorl %esi, %esi - xorl %edi, %edi - call install_prealloc - - /* Retrieve initrd pointer and size */ - movl ramdisk_image, %ebp - movl ramdisk_size, %ecx - -start_ipxe: - /* Set up real-mode stack */ - movw %bx, %ss - movw $_estack16, %sp - - /* Jump to .text16 segment */ - pushw %ax - pushw $1f - lret - .section ".text16", "awx", @progbits -1: - /* Set up %ds for access to .data16 */ - movw %bx, %ds - - /* Store command-line pointer */ - movl %edx, cmdline_phys - - /* Store initrd pointer and size */ - movl %ebp, initrd_phys - movl %ecx, initrd_len - - /* Run iPXE */ - pushl $main - pushw %cs - call prot_call - popl %ecx /* discard */ - - /* Uninstall iPXE */ - call uninstall - - /* Boot next device */ - int $0x18 diff -r 12473799110f -r d74b8b5a78d0 memtest/stuff/bootloader.S --- a/memtest/stuff/bootloader.S Thu Jan 25 03:48:04 2018 +0200 +++ b/memtest/stuff/bootloader.S Sat Jan 27 12:56:10 2018 +0100 @@ -1,10 +1,11 @@ -// Image/zImage boot sector +// Image/zImage & tiny bzImage linux kernel boot sector, (C) SliTaz, GPL2. SYSSEG = 0x1000 INITSEG = 0x9000 SETUPSEG = 0x9020 setup_sects = 497 syssize = 500 +cmd_line_ptr = 0x228 .text .code16 @@ -14,20 +15,24 @@ #define CODESZ 512 /* patched by installer */ +//#define BZIMAGE 0x207 /* setup version ; for bzImage < 512 Kb only */ + /* some extra features */ #define EXE_SUPPORT real mode dos .exe file support -#define CMDLINE 0x9E00 +#define CMDLINE kernel cmdline support #define VCPI VCPI 4.0 support #define SHUTDOWNDOS shutdown DOS services -/* some contraints to reduce the size */ +/* some contraints to reduce the code size */ //#define FLOPPY_1440K_ONLY 1.44M floppies support only -33 //#define FLOPPY_HAS_2_SIDES hardcoded heads count to 2 -13 -//#define MOVE_MAX_SYSSIZE always memcpy 512Kb -2 -//#define NO_CURSOR_DEFINITION -8 -//#define NO_CMDLINE_SHRINK remove heading spaces ? -6 +//#define NO_CMDLINE_SHRINK remove heading spaces ? -6-20 //#define NO_CMDLINE_FILE remove @cmdline file support ? -20 //#define NO_DOTS show progression dots ? -8 +#ifndef BZIMAGE +//#defime NO_MINSETUP default setup (dos only) ? -4 +//#define NO_CURSOR_DEFINITION -8 +#endif #ifdef EXE_SUPPORT #define EXEADRS(x) (x+0xE0) @@ -65,23 +70,33 @@ // .word 0,0,0 // Overlay number #endif start: - cld # assume nothing xorw %ax, %ax # %ax = 0 +#ifdef BZIMAGE +zeroed = 14 # zeroed registers +#else zeroed = 12 # zeroed registers +#endif + movw $zeroed/2, %cx # clear gdt + offset, %ds, limits stacktop = 0x9E00 # in 0x8000 .. 0xA000 (+zeroed+12) pushw $INITSEG - popw %ss # %ss contain INITSEG - pushw %ss end_header: - popw %es # %es = %ss = INITSEG + cld # assume nothing +#if defined(BZIMAGE) && BZIMAGE >= 0x202 + popw %es # %es contain INITSEG + movw %es, %di +#else # cmdline offset at 0x22 movw $stacktop, %di # stacktop is an arbitrary value >= # length of bootsect + length of # setup + room for stack; # 12 is disk parm size. + popw %es # %es contain INITSEG +#endif + pushw %es + popw %ss # %es = %ss = INITSEG movw %di, %sp # put stack at INITSEG:stacktop-... #ifdef EXE_SUPPORT - cwd # %dx = 0 + cwd # force %dx = 0 (floppy only) #endif # Many BIOS's default disk parameter tables will not recognize @@ -96,7 +111,6 @@ # # High doesn't hurt. Low does. Let's use the max: 63 - movw $zeroed/2, %cx # clear gdt + offset, %ds, limits rep # don't worry about cld stosw # already done above popw %bx # offset = 0 @@ -135,6 +149,9 @@ shrw $9-4, %di incw %di movw $SYSSEG, %cx +#ifdef BZIMAGE + push %cx +#endif call read_sectorsCX # This procedure turns off the floppy drive motor, so @@ -149,6 +166,45 @@ # loaded directly after the bootblock: # Segments are as follows: %ds = %ss = INITSEG +#ifdef BZIMAGE + popw %bx + popw %si // SYSSEG:0 +movesys: // %bx = DS, %si + movw $16, %ax + mulw %bx + addw %si, %ax + adcw $0x9300, %dx // %dx:%ax src flat address + movw $9, %cx +zero1: + pushw $0 // 2E..1E + loop zero1 + //pushl $0x93100000 // 1A: dest + pushw $0x9310 + pushw %cx + pushw $-1 // 18 + pushw %cx // 16 + pushw %dx // src + pushw %ax + pushw $-1 // 10 + movb $8, %cl + movw %cx, %bx // will move 8*64 = 512Kb +zero2: + pushw $0 // 0E..00 + loop zero2 + movw %sp, %si + pushw %ss + popw %es + pushw %es + popw %ds +syslp: + movb $0x80, %ch + movb $0x87, %ah + int $0x15 + incb 0x14(%si) + incb 0x1C(%si) + decw %bx + jne syslp +#endif jmp_setup: ljmp $SETUPSEG, $0 @@ -172,29 +228,32 @@ movw $stacktop-4-16, %sp popl 4(%si) popaw +#ifdef BZIMAGE + jmp movesys #endif +#endif +#ifndef BZIMAGE movesys: // %ax = SYSSEG, %bx = DS, %si - //movw %cs:syssize, %bp - movw $0x8000, %bp shrw $4, %si addw %si, %bx subw %ax, %bx jnc forward - addw %bp, %ax + movb $0x90, %ah + ;decw %ax forward: movw %ax, %es - movw %ax, %dx - addw %bx, %dx - movw %dx, %ds - sbbw %dx, %dx // %dx = 0 : -1 + movw %ax, %di + addw %bx, %di + movw %di, %ds + sbbw %di, %di // %di = 0 : -1 cmc // C = 1 : 0 - adcw %dx, %ax + adcw %di, %ax xorw %si, %si xorw %di, %di - movb $8, %cl + movb $0x10, %cl + cmpb %cl, %ah // move 512k rep - movsw - decw %bp + movsb jns forward #ifndef NO_CURSOR_DEFINITION movb $1, %ah @@ -205,6 +264,7 @@ pushw %ss popw %ds jmp jmp_setup +#endif comstart: cld # assume nothing pushw $INITSEG @@ -216,7 +276,11 @@ cbw xchgw %ax, %cx jcxz nocmdline +# if defined(BZIMAGE) && BZIMAGE >= 0x202 + movw $INITSEG/16+stacktop/256, EXEADRS(cmd_line_ptr+1) +# else movw $0xA33F, 0x7F(%si) +# endif # ifndef NO_CMDLINE_SHRINK skipspace: lodsb @@ -244,9 +308,18 @@ rep movsb nocmdline: + orb EXEADRS(setup_sects), %ch +# ifndef NO_MINSETUP +# ifndef BZIMAGE + jnz setupok + mov $4, %ch +setupok: +# endif +# endif +#else + movb EXEADRS(setup_sects), %ch #endif movb $(512-(end_header-_start))/2, %cl - movb EXEADRS(setup_sects), %ch movw $0x100, %si movw $end_header, %di rep @@ -260,19 +333,13 @@ pushw $movesys #endif #ifdef VCPI -# ifndef SHUTDOWNDOS - pushw %es - pushw %ds -# endif pushaw smsww %ax andb $1, %al je isrm movw $EXEADRS(gdt_vcpi),%si - pushw $pagebuf/16 - popw %es - movl $pagebuf+3,%es:0x1000 - xorw %di,%di + movw $pagebuf-0x90000,%di // %es = 0x9000 + movl $pagebuf+3,%es:0x1000(%di) call_vcpi: movb $0xDE,%ah // DE01, EBX = getiface(DS:SI, ES:DI) int $0x67 @@ -291,8 +358,6 @@ # else lssw %cs:EXEADRS(saved_ss_sp),%sp popaw - popw %ds - popw %es retf # endif #else @@ -316,7 +381,6 @@ #define FLOPPY_SECTORS 18 /* 18 sectors */ #else #define FLOPPY_HEADS 2 /* 2 heads minimum */ -#define FLOPPY_SECTORS 9 /* 9 sectors minimum */ #endif return: @@ -330,14 +394,9 @@ check_limits: #ifndef FLOPPY_1440K_ONLY popw %dx -#ifdef FLOPPY_SECTORS - cmpb $FLOPPY_SECTORS+1, %cl # minimum sector count - jb check_head -#endif cmpb %al, %cl # max sector known ? ja next_head # no -> store it #ifndef FLOPPY_HAS_2_SIDES -check_head: #ifdef FLOPPY_HEADS cmpb $FLOPPY_HEADS, %dh # 2 heads minimum jb check_cylinder